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...@@ -330,7 +330,6 @@ set(ZIG_STAGE2_SOURCES
330 src/Air/Liveness.zig330 src/Air/Liveness.zig
331 src/Air/Liveness/Verify.zig331 src/Air/Liveness/Verify.zig
332 src/Air/print.zig332 src/Air/print.zig
333 src/Air/types_resolved.zig
334 src/Builtin.zig333 src/Builtin.zig
335 src/Compilation.zig334 src/Compilation.zig
336 src/Compilation/Config.zig335 src/Compilation/Config.zig
...@@ -344,6 +343,7 @@ set(ZIG_STAGE2_SOURCES...@@ -344,6 +343,7 @@ set(ZIG_STAGE2_SOURCES
344 src/Sema.zig343 src/Sema.zig
345 src/Sema/bitcast.zig344 src/Sema/bitcast.zig
346 src/Sema/comptime_ptr_access.zig345 src/Sema/comptime_ptr_access.zig
346 src/Sema/type_resolution.zig
347 src/Type.zig347 src/Type.zig
348 src/Value.zig348 src/Value.zig
349 src/Zcu.zig349 src/Zcu.zig
...@@ -360,7 +360,8 @@ set(ZIG_STAGE2_SOURCES...@@ -360,7 +360,8 @@ set(ZIG_STAGE2_SOURCES
360 src/codegen/aarch64/Mir.zig360 src/codegen/aarch64/Mir.zig
361 src/codegen/aarch64/Select.zig361 src/codegen/aarch64/Select.zig
362 src/codegen/c.zig362 src/codegen/c.zig
363 src/codegen/c/Type.zig363 src/codegen/c/type.zig
364 src/codegen/c/type/render_defs.zig
364 src/codegen/llvm.zig365 src/codegen/llvm.zig
365 src/codegen/llvm/bindings.zig366 src/codegen/llvm/bindings.zig
366 src/crash_report.zig367 src/crash_report.zig
...@@ -375,6 +376,7 @@ set(ZIG_STAGE2_SOURCES...@@ -375,6 +376,7 @@ set(ZIG_STAGE2_SOURCES
375 src/libs/libunwind.zig376 src/libs/libunwind.zig
376 src/link.zig377 src/link.zig
377 src/link/C.zig378 src/link/C.zig
379 src/link/ConstPool.zig
378 src/link/Coff.zig380 src/link/Coff.zig
379 src/link/Dwarf.zig381 src/link/Dwarf.zig
380 src/link/Elf.zig382 src/link/Elf.zig
...@@ -606,8 +608,8 @@ if(MSVC)...@@ -606,8 +608,8 @@ if(MSVC)
606 set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE")608 set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE")
607else()609else()
608 set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2")610 set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2")
609 set(ZIG1_COMPILE_FLAGS "-std=c99 -Os")611 set(ZIG1_COMPILE_FLAGS "-std=c99 -Os -fno-strict-aliasing")
610 set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector")612 set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector -fno-strict-aliasing")
611 # Must match the condition in build.zig.613 # Must match the condition in build.zig.
612 if(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)(eb)?$" OR ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$")614 if(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)(eb)?$" OR ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$")
613 set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections")615 set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections")
...@@ -623,6 +625,12 @@ else()...@@ -623,6 +625,12 @@ else()
623 else()625 else()
624 set(ZIG2_LINK_FLAGS "-Wl,-z,stack-size=0x10000000")626 set(ZIG2_LINK_FLAGS "-Wl,-z,stack-size=0x10000000")
625 endif()627 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()
626endif()634endif()
627635
628set(ZIG1_WASM_MODULE "${PROJECT_SOURCE_DIR}/stage1/zig1.wasm")636set(ZIG1_WASM_MODULE "${PROJECT_SOURCE_DIR}/stage1/zig1.wasm")
bootstrap.c+23-1
...@@ -102,6 +102,26 @@ int main(int argc, char **argv) {...@@ -102,6 +102,26 @@ int main(int argc, char **argv) {
102 const char *cc = get_c_compiler();102 const char *cc = get_c_compiler();
103 const char *host_triple = get_host_triple();103 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
105 {125 {
106 const char *child_argv[] = {126 const char *child_argv[] = {
107 cc, "-o", "zig-wasm2c", "stage1/wasm2c.c", "-O2", "-std=c99", NULL,127 cc, "-o", "zig-wasm2c", "stage1/wasm2c.c", "-O2", "-std=c99", NULL,
...@@ -116,7 +136,7 @@ int main(int argc, char **argv) {...@@ -116,7 +136,7 @@ int main(int argc, char **argv) {
116 }136 }
117 {137 {
118 const char *child_argv[] = {138 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,
120 };140 };
121 print_and_run(child_argv);141 print_and_run(child_argv);
122 }142 }
...@@ -193,6 +213,8 @@ int main(int argc, char **argv) {...@@ -193,6 +213,8 @@ int main(int argc, char **argv) {
193#if defined(__GNUC__)213#if defined(__GNUC__)
194 "-pthread",214 "-pthread",
195#endif215#endif
216 "-fno-strict-aliasing",
217 workaround_gcc_sra_miscomp ? "-fno-tree-sra" : NULL,
196 NULL,218 NULL,
197 };219 };
198 print_and_run(child_argv);220 print_and_run(child_argv);
build.zig+4-4
...@@ -568,7 +568,7 @@ pub fn build(b: *std.Build) !void {...@@ -568,7 +568,7 @@ pub fn build(b: *std.Build) !void {
568 .skip_linux = skip_linux,568 .skip_linux = skip_linux,
569 .skip_llvm = skip_llvm,569 .skip_llvm = skip_llvm,
570 .skip_libc = skip_libc,570 .skip_libc = skip_libc,
571 .max_rss = 8_500_000_000,571 .max_rss = 9_300_000_000,
572 }));572 }));
573573
574 const unit_tests_step = b.step("test-unit", "Run the compiler source unit tests");574 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 {...@@ -584,7 +584,7 @@ pub fn build(b: *std.Build) !void {
584 .use_llvm = use_llvm,584 .use_llvm = use_llvm,
585 .use_lld = use_llvm,585 .use_lld = use_llvm,
586 .zig_lib_dir = b.path("lib"),586 .zig_lib_dir = b.path("lib"),
587 .max_rss = 2_500_000_000,587 .max_rss = 2_700_000_000,
588 });588 });
589 if (link_libc) {589 if (link_libc) {
590 unit_tests.root_module.link_libc = true;590 unit_tests.root_module.link_libc = true;
...@@ -611,7 +611,7 @@ pub fn build(b: *std.Build) !void {...@@ -611,7 +611,7 @@ pub fn build(b: *std.Build) !void {
611 .skip_linux = skip_linux,611 .skip_linux = skip_linux,
612 .skip_llvm = skip_llvm,612 .skip_llvm = skip_llvm,
613 .skip_release = skip_release,613 .skip_release = skip_release,
614 .max_rss = 3_000_000_000,614 .max_rss = 3_300_000_000,
615 }));615 }));
616 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));616 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
617 test_step.dependOn(tests.addStackTraceTests(b, test_filters, skip_non_native));617 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...@@ -767,7 +767,7 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
767fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile {767fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile {
768 const exe = b.addExecutable(.{768 const exe = b.addExecutable(.{
769 .name = "zig",769 .name = "zig",
770 .max_rss = 7_900_000_000,770 .max_rss = 8_700_000_000,
771 .root_module = addCompilerMod(b, options),771 .root_module = addCompilerMod(b, options),
772 });772 });
773 exe.stack_size = stack_size;773 exe.stack_size = stack_size;
ci/aarch64-freebsd-debug.sh-1
...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 2m52 --test-timeout 2m
ci/aarch64-freebsd-release.sh-1
...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 2m52 --test-timeout 2m
ci/aarch64-linux-debug.sh-1
...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 -Dtarget=native-native-musl \50 -Dtarget=native-native-musl \
52 --search-prefix "$PREFIX" \51 --search-prefix "$PREFIX" \
53 --zig-lib-dir "$PWD/../lib" \52 --zig-lib-dir "$PWD/../lib" \
ci/aarch64-linux-release.sh-1
...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 -Dtarget=native-native-musl \50 -Dtarget=native-native-musl \
52 --search-prefix "$PREFIX" \51 --search-prefix "$PREFIX" \
53 --zig-lib-dir "$PWD/../lib" \52 --zig-lib-dir "$PWD/../lib" \
ci/aarch64-macos-debug.sh-1
...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
47 -Denable-macos-sdk \47 -Denable-macos-sdk \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --test-timeout 2m51 --test-timeout 2m
5352
ci/aarch64-macos-release.sh-1
...@@ -46,7 +46,6 @@ stage3-release/bin/zig build test docs \...@@ -46,7 +46,6 @@ stage3-release/bin/zig build test docs \
46 -Denable-macos-sdk \46 -Denable-macos-sdk \
47 -Dstatic-llvm \47 -Dstatic-llvm \
48 -Dskip-non-native \48 -Dskip-non-native \
49 -Dskip-test-incremental \
50 --search-prefix "$PREFIX" \49 --search-prefix "$PREFIX" \
51 --test-timeout 2m50 --test-timeout 2m
5251
ci/aarch64-netbsd-debug.sh-1
...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 4m52 --test-timeout 4m
ci/aarch64-netbsd-release.sh-1
...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 4m52 --test-timeout 4m
ci/aarch64-windows.ps1-1
...@@ -60,7 +60,6 @@ Write-Output "Main test suite..."...@@ -60,7 +60,6 @@ Write-Output "Main test suite..."
60 --search-prefix "$PREFIX_PATH" `60 --search-prefix "$PREFIX_PATH" `
61 -Dstatic-llvm `61 -Dstatic-llvm `
62 -Dskip-non-native `62 -Dskip-non-native `
63 -Dskip-test-incremental `
64 -Denable-symlinks-windows `63 -Denable-symlinks-windows `
65 --test-timeout 30m64 --test-timeout 30m
66CheckLastExitCode65CheckLastExitCode
ci/loongarch64-linux-debug.sh-1
...@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \...@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \
48 --maxrss ${ZSF_MAX_RSS:-0} \48 --maxrss ${ZSF_MAX_RSS:-0} \
49 -Dstatic-llvm \49 -Dstatic-llvm \
50 -Dskip-non-native \50 -Dskip-non-native \
51 -Dskip-test-incremental \
52 -Dtarget=native-native-musl \51 -Dtarget=native-native-musl \
53 --search-prefix "$PREFIX" \52 --search-prefix "$PREFIX" \
54 --zig-lib-dir "$PWD/../lib" \53 --zig-lib-dir "$PWD/../lib" \
ci/loongarch64-linux-release.sh-1
...@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \...@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \
48 --maxrss ${ZSF_MAX_RSS:-0} \48 --maxrss ${ZSF_MAX_RSS:-0} \
49 -Dstatic-llvm \49 -Dstatic-llvm \
50 -Dskip-non-native \50 -Dskip-non-native \
51 -Dskip-test-incremental \
52 -Dtarget=native-native-musl \51 -Dtarget=native-native-musl \
53 --search-prefix "$PREFIX" \52 --search-prefix "$PREFIX" \
54 --zig-lib-dir "$PWD/../lib" \53 --zig-lib-dir "$PWD/../lib" \
ci/powerpc64le-linux-debug.sh-1
...@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \...@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \
48 --maxrss ${ZSF_MAX_RSS:-0} \48 --maxrss ${ZSF_MAX_RSS:-0} \
49 -Dstatic-llvm \49 -Dstatic-llvm \
50 -Dskip-non-native \50 -Dskip-non-native \
51 -Dskip-test-incremental \
52 -Dtarget=native-native-musl \51 -Dtarget=native-native-musl \
53 -Dcpu=native+longcall \52 -Dcpu=native+longcall \
54 --search-prefix "$PREFIX" \53 --search-prefix "$PREFIX" \
ci/powerpc64le-linux-release.sh-1
...@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \...@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \
48 --maxrss ${ZSF_MAX_RSS:-0} \48 --maxrss ${ZSF_MAX_RSS:-0} \
49 -Dstatic-llvm \49 -Dstatic-llvm \
50 -Dskip-non-native \50 -Dskip-non-native \
51 -Dskip-test-incremental \
52 -Dtarget=native-native-musl \51 -Dtarget=native-native-musl \
53 -Dcpu=native+longcall \52 -Dcpu=native+longcall \
54 --search-prefix "$PREFIX" \53 --search-prefix "$PREFIX" \
ci/s390x-linux-debug.sh-1
...@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \...@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \
48 --maxrss ${ZSF_MAX_RSS:-0} \48 --maxrss ${ZSF_MAX_RSS:-0} \
49 -Dstatic-llvm \49 -Dstatic-llvm \
50 -Dskip-non-native \50 -Dskip-non-native \
51 -Dskip-test-incremental \
52 -Dtarget=native-native-musl \51 -Dtarget=native-native-musl \
53 --search-prefix "$PREFIX" \52 --search-prefix "$PREFIX" \
54 --zig-lib-dir "$PWD/../lib" \53 --zig-lib-dir "$PWD/../lib" \
ci/s390x-linux-release.sh-1
...@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \...@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \
48 --maxrss ${ZSF_MAX_RSS:-0} \48 --maxrss ${ZSF_MAX_RSS:-0} \
49 -Dstatic-llvm \49 -Dstatic-llvm \
50 -Dskip-non-native \50 -Dskip-non-native \
51 -Dskip-test-incremental \
52 -Dtarget=native-native-musl \51 -Dtarget=native-native-musl \
53 --search-prefix "$PREFIX" \52 --search-prefix "$PREFIX" \
54 --zig-lib-dir "$PWD/../lib" \53 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-freebsd-debug.sh-1
...@@ -53,7 +53,6 @@ stage3-debug/bin/zig build test docs \...@@ -53,7 +53,6 @@ stage3-debug/bin/zig build test docs \
53 -Dskip-openbsd \53 -Dskip-openbsd \
54 -Dskip-windows \54 -Dskip-windows \
55 -Dskip-darwin \55 -Dskip-darwin \
56 -Dskip-test-incremental \
57 --search-prefix "$PREFIX" \56 --search-prefix "$PREFIX" \
58 --zig-lib-dir "$PWD/../lib" \57 --zig-lib-dir "$PWD/../lib" \
59 --test-timeout 2m58 --test-timeout 2m
ci/x86_64-freebsd-release.sh-1
...@@ -53,7 +53,6 @@ stage3-release/bin/zig build test docs \...@@ -53,7 +53,6 @@ stage3-release/bin/zig build test docs \
53 -Dskip-openbsd \53 -Dskip-openbsd \
54 -Dskip-windows \54 -Dskip-windows \
55 -Dskip-darwin \55 -Dskip-darwin \
56 -Dskip-test-incremental \
57 --search-prefix "$PREFIX" \56 --search-prefix "$PREFIX" \
58 --zig-lib-dir "$PWD/../lib" \57 --zig-lib-dir "$PWD/../lib" \
59 --test-timeout 2m58 --test-timeout 2m
ci/x86_64-linux-debug-llvm.sh-1
...@@ -64,7 +64,6 @@ stage3-debug/bin/zig build test docs \...@@ -64,7 +64,6 @@ stage3-debug/bin/zig build test docs \
64 -Dskip-openbsd \64 -Dskip-openbsd \
65 -Dskip-windows \65 -Dskip-windows \
66 -Dskip-darwin \66 -Dskip-darwin \
67 -Dskip-test-incremental \
68 -Dtarget=native-native-musl \67 -Dtarget=native-native-musl \
69 --search-prefix "$PREFIX" \68 --search-prefix "$PREFIX" \
70 --zig-lib-dir "$PWD/../lib" \69 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-linux-debug.sh-1
...@@ -63,7 +63,6 @@ stage3-debug/bin/zig build test docs \...@@ -63,7 +63,6 @@ stage3-debug/bin/zig build test docs \
63 -Dskip-windows \63 -Dskip-windows \
64 -Dskip-darwin \64 -Dskip-darwin \
65 -Dskip-llvm \65 -Dskip-llvm \
66 -Dskip-test-incremental \
67 -Dtarget=native-native-musl \66 -Dtarget=native-native-musl \
68 --search-prefix "$PREFIX" \67 --search-prefix "$PREFIX" \
69 --zig-lib-dir "$PWD/../lib" \68 --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"...@@ -21,7 +21,8 @@ export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
2121
22# Test building from source without LLVM.22# Test building from source without LLVM.
23cc -o bootstrap bootstrap.c23cc -o bootstrap bootstrap.c
24./bootstrap24# See comments in bootstrap.c for an explanation of the flag given here.
25./bootstrap --workaround-gcc-sra-miscomp
25./zig2 build -Dno-lib26./zig2 build -Dno-lib
26./zig-out/bin/zig test test/behavior.zig27./zig-out/bin/zig test test/behavior.zig
2728
...@@ -64,7 +65,6 @@ stage3-release/bin/zig build test docs \...@@ -64,7 +65,6 @@ stage3-release/bin/zig build test docs \
64 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \65 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \
65 -fwasmtime \66 -fwasmtime \
66 -Dstatic-llvm \67 -Dstatic-llvm \
67 -Dskip-test-incremental \
68 -Dtarget=native-native-musl \68 -Dtarget=native-native-musl \
69 --search-prefix "$PREFIX" \69 --search-prefix "$PREFIX" \
70 --zig-lib-dir "$PWD/../lib" \70 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-netbsd-debug.sh-1
...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 2m52 --test-timeout 2m
ci/x86_64-netbsd-release.sh-1
...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 2m52 --test-timeout 2m
ci/x86_64-openbsd-debug.sh-1
...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 2m52 --test-timeout 2m
ci/x86_64-openbsd-release.sh-1
...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \...@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
47 --maxrss ${ZSF_MAX_RSS:-0} \47 --maxrss ${ZSF_MAX_RSS:-0} \
48 -Dstatic-llvm \48 -Dstatic-llvm \
49 -Dskip-non-native \49 -Dskip-non-native \
50 -Dskip-test-incremental \
51 --search-prefix "$PREFIX" \50 --search-prefix "$PREFIX" \
52 --zig-lib-dir "$PWD/../lib" \51 --zig-lib-dir "$PWD/../lib" \
53 --test-timeout 2m52 --test-timeout 2m
doc/langref.html.in+3-2
...@@ -2103,8 +2103,9 @@ or...@@ -2103,8 +2103,9 @@ or
2103 less than {#syntax#}1 << 29{#endsyntax#}.2103 less than {#syntax#}1 << 29{#endsyntax#}.
2104 </p>2104 </p>
2105 <p>2105 <p>
2106 In Zig, a pointer type has an alignment value. If the value is equal to the2106 Pointer types may explicitly specify an alignment in bytes. If it is not
2107 alignment of the underlying type, it can be omitted from the type:2107 specified, the alignment is assumed to be equal to the alignment of the
2108 underlying type.
2108 </p>2109 </p>
2109 {#code|test_variable_alignment.zig#}2110 {#code|test_variable_alignment.zig#}
21102111
doc/langref/test_comptime_invalid_error_code.zig+2-5
...@@ -1,8 +1,5 @@...@@ -1,8 +1,5 @@
1comptime {1comptime {
2 const err = error.AnError;2 _ = @errorFromInt(12345);
3 const number = @intFromError(err) + 10;
4 const invalid_err = @errorFromInt(number);
5 _ = invalid_err;
6}3}
74
8// test_error=integer value '11' represents no error5// 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" {...@@ -3,4 +3,4 @@ test "missized packed struct" {
3 _ = S{ .a = 4, .b = 2 };3 _ = S{ .a = 4, .b = 2 };
4}4}
55
6// test_error=backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 246// 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 @@...@@ -1,15 +1,20 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
45
5test "variable alignment" {6test "variable alignment" {
6 var x: i32 = 1234;7 var x: i32 = 1234;
7 const align_of_i32 = @alignOf(@TypeOf(x));8
8 try expectEqual(*i32, @TypeOf(&x));9 try expectEqual(*i32, @TypeOf(&x));
9 try expectEqual(*align(align_of_i32) i32, *i32);10
10 if (builtin.target.cpu.arch == .x86_64) {11 try expect(@intFromPtr(&x) % @alignOf(i32) == 0);
11 try expectEqual(4, @typeInfo(*i32).pointer.alignment);12
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.*);
13}18}
1419
15// test20// test
lib/compiler/aro/aro/InitList.zig+13-7
...@@ -22,9 +22,15 @@ const Item = struct {...@@ -22,9 +22,15 @@ const Item = struct {
2222
23const InitList = @This();23const InitList = @This();
2424
25list: std.ArrayList(Item) = .empty,25list: std.ArrayList(Item),
26node: Node.OptIndex = .null,26node: Node.OptIndex,
27tok: TokenIndex = 0,27tok: TokenIndex,
28
29pub const empty: InitList = .{
30 .list = .empty,
31 .node = .null,
32 .tok = 0,
33};
2834
29/// Deinitialize freeing all memory.35/// Deinitialize freeing all memory.
30pub fn deinit(il: *InitList, gpa: Allocator) void {36pub fn deinit(il: *InitList, gpa: Allocator) void {
...@@ -43,7 +49,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {...@@ -43,7 +49,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
43 if (il.list.items.len == 0) {49 if (il.list.items.len == 0) {
44 const item = try il.list.addOne(gpa);50 const item = try il.list.addOne(gpa);
45 item.* = .{51 item.* = .{
46 .list = .{},52 .list = .empty,
47 .index = index,53 .index = index,
48 };54 };
49 return &item.list;55 return &item.list;
...@@ -51,7 +57,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {...@@ -51,7 +57,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
51 // Append a new value to the end of the list.57 // Append a new value to the end of the list.
52 const new = try il.list.addOne(gpa);58 const new = try il.list.addOne(gpa);
53 new.* = .{59 new.* = .{
54 .list = .{},60 .list = .empty,
55 .index = index,61 .index = index,
56 };62 };
57 return &new.list;63 return &new.list;
...@@ -70,7 +76,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {...@@ -70,7 +76,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
7076
71 // Insert a new value into a sorted position.77 // Insert a new value into a sorted position.
72 try il.list.insert(gpa, left, .{78 try il.list.insert(gpa, left, .{
73 .list = .{},79 .list = .empty,
74 .index = index,80 .index = index,
75 });81 });
76 return &il.list.items[left].list;82 return &il.list.items[left].list;
...@@ -78,7 +84,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {...@@ -78,7 +84,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
7884
79test "basic usage" {85test "basic usage" {
80 const gpa = testing.allocator;86 const gpa = testing.allocator;
81 var il: InitList = .{};87 var il: InitList = .empty;
82 defer il.deinit(gpa);88 defer il.deinit(gpa);
8389
84 {90 {
lib/compiler/aro/aro/Parser.zig+3-3
...@@ -3977,7 +3977,7 @@ fn initializer(p: *Parser, init_qt: QualType) Error!Result {...@@ -3977,7 +3977,7 @@ fn initializer(p: *Parser, init_qt: QualType) Error!Result {
3977 final_init_qt = .invalid;3977 final_init_qt = .invalid;
3978 }3978 }
39793979
3980 var il: InitList = .{};3980 var il: InitList = .empty;
3981 defer il.deinit(p.comp.gpa);3981 defer il.deinit(p.comp.gpa);
39823982
3983 try p.initializerItem(&il, final_init_qt, l_brace);3983 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...@@ -4028,12 +4028,12 @@ fn initializerItem(p: *Parser, il: *InitList, init_qt: QualType, l_brace: TokenI
4028 try p.err(first_tok, .initializer_overrides, .{});4028 try p.err(first_tok, .initializer_overrides, .{});
4029 try p.err(item.il.tok, .previous_initializer, .{});4029 try p.err(item.il.tok, .previous_initializer, .{});
4030 item.il.deinit(gpa);4030 item.il.deinit(gpa);
4031 item.il.* = .{};4031 item.il.* = .empty;
4032 }4032 }
4033 try p.initializerItem(item.il, item.qt, inner_l_brace);4033 try p.initializerItem(item.il, item.qt, inner_l_brace);
4034 } else {4034 } else {
4035 // discard further values4035 // discard further values
4036 var tmp_il: InitList = .{};4036 var tmp_il: InitList = .empty;
4037 defer tmp_il.deinit(gpa);4037 defer tmp_il.deinit(gpa);
4038 try p.initializerItem(&tmp_il, .invalid, inner_l_brace);4038 try p.initializerItem(&tmp_il, .invalid, inner_l_brace);
4039 if (!warned_excess) try p.err(first_tok, switch (init_qt.base(p.comp).type) {4039 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();...@@ -43,13 +43,13 @@ const Toolchain = @This();
43driver: *Driver,43driver: *Driver,
4444
45/// The list of toolchain specific path prefixes to search for libraries.45/// The list of toolchain specific path prefixes to search for libraries.
46library_paths: PathList = .{},46library_paths: PathList = .empty,
4747
48/// The list of toolchain specific path prefixes to search for files.48/// The list of toolchain specific path prefixes to search for files.
49file_paths: PathList = .{},49file_paths: PathList = .empty,
5050
51/// The list of toolchain specific path prefixes to search for programs.51/// The list of toolchain specific path prefixes to search for programs.
52program_paths: PathList = .{},52program_paths: PathList = .empty,
5353
54selected_multilib: Multilib = .{},54selected_multilib: Multilib = .{},
5555
lib/compiler/objcopy.zig+2-2
...@@ -388,8 +388,8 @@ const BinaryElfOutput = struct {...@@ -388,8 +388,8 @@ const BinaryElfOutput = struct {
388388
389 pub fn parse(allocator: Allocator, in: *File.Reader, elf_hdr: elf.Header) !Self {389 pub fn parse(allocator: Allocator, in: *File.Reader, elf_hdr: elf.Header) !Self {
390 var self: Self = .{390 var self: Self = .{
391 .segments = .{},391 .segments = .empty,
392 .sections = .{},392 .sections = .empty,
393 .allocator = allocator,393 .allocator = allocator,
394 .shstrtab = null,394 .shstrtab = null,
395 };395 };
lib/compiler/resinator/cvtres.zig+1-1
...@@ -410,7 +410,7 @@ pub const ResourceDirectoryTable = extern struct {...@@ -410,7 +410,7 @@ pub const ResourceDirectoryTable = extern struct {
410};410};
411411
412pub const ResourceDirectoryEntry = extern struct {412pub const ResourceDirectoryEntry = extern struct {
413 entry: packed union {413 entry: packed union(u32) {
414 name_offset: packed struct(u32) {414 name_offset: packed struct(u32) {
415 address: u31,415 address: u31,
416 /// This is undocumented in the PE/COFF spec, but the high bit416 /// 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 {...@@ -38,10 +38,10 @@ pub fn main(init: std.process.Init.Minimal) void {
38 }38 }
3939
40 if (need_simple) {40 if (need_simple) {
41 return mainSimple() catch @panic("test failure");41 return mainSimple() catch |err| std.debug.panic("test failure: {t}", .{err});
42 }42 }
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
46 var listen = false;46 var listen = false;
47 var opt_cache_dir: ?[]const u8 = null;47 var opt_cache_dir: ?[]const u8 = null;
...@@ -55,7 +55,7 @@ pub fn main(init: std.process.Init.Minimal) void {...@@ -55,7 +55,7 @@ pub fn main(init: std.process.Init.Minimal) void {
55 } else if (std.mem.startsWith(u8, arg, "--cache-dir")) {55 } else if (std.mem.startsWith(u8, arg, "--cache-dir")) {
56 opt_cache_dir = arg["--cache-dir=".len..];56 opt_cache_dir = arg["--cache-dir=".len..];
57 } else {57 } else {
58 @panic("unrecognized command line argument");58 std.debug.panic("unrecognized command line argument: {s}", .{arg});
59 }59 }
60 }60 }
6161
...@@ -65,7 +65,7 @@ pub fn main(init: std.process.Init.Minimal) void {...@@ -65,7 +65,7 @@ pub fn main(init: std.process.Init.Minimal) void {
65 }65 }
6666
67 if (listen) {67 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});
69 } else {69 } else {
70 return mainTerminal(init);70 return mainTerminal(init);
71 }71 }
lib/std/Build/Fuzz.zig+2-2
...@@ -390,7 +390,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO...@@ -390,7 +390,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO
390 .coverage = std.debug.Coverage.init,390 .coverage = std.debug.Coverage.init,
391 .mapped_memory = undefined, // populated below391 .mapped_memory = undefined, // populated below
392 .source_locations = undefined, // populated below392 .source_locations = undefined, // populated below
393 .entry_points = .{},393 .entry_points = .empty,
394 .start_timestamp = ws.now(),394 .start_timestamp = ws.now(),
395 .start_n_runs = undefined, // populated below395 .start_n_runs = undefined, // populated below
396 };396 };
...@@ -450,7 +450,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO...@@ -450,7 +450,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO
450450
451 // Unfortunately the PCs array that LLVM gives us from the 8-bit PC451 // Unfortunately the PCs array that LLVM gives us from the 8-bit PC
452 // counters feature is not sorted.452 // 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;
454 defer sorted_pcs.deinit(gpa);454 defer sorted_pcs.deinit(gpa);
455 try sorted_pcs.resize(gpa, pcs.len);455 try sorted_pcs.resize(gpa, pcs.len);
456 @memcpy(sorted_pcs.items(.pc), pcs);456 @memcpy(sorted_pcs.items(.pc), pcs);
lib/std/Build/Module.zig+7-7
...@@ -275,18 +275,18 @@ pub fn init(...@@ -275,18 +275,18 @@ pub fn init(
275 m.* = .{275 m.* = .{
276 .owner = owner,276 .owner = owner,
277 .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null,277 .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null,
278 .import_table = .{},278 .import_table = .empty,
279 .resolved_target = options.target,279 .resolved_target = options.target,
280 .optimize = options.optimize,280 .optimize = options.optimize,
281 .link_libc = options.link_libc,281 .link_libc = options.link_libc,
282 .link_libcpp = options.link_libcpp,282 .link_libcpp = options.link_libcpp,
283 .dwarf_format = options.dwarf_format,283 .dwarf_format = options.dwarf_format,
284 .c_macros = .{},284 .c_macros = .empty,
285 .include_dirs = .{},285 .include_dirs = .empty,
286 .lib_paths = .{},286 .lib_paths = .empty,
287 .rpaths = .{},287 .rpaths = .empty,
288 .frameworks = .{},288 .frameworks = .empty,
289 .link_objects = .{},289 .link_objects = .empty,
290 .strip = options.strip,290 .strip = options.strip,
291 .unwind_tables = options.unwind_tables,291 .unwind_tables = options.unwind_tables,
292 .single_threaded = options.single_threaded,292 .single_threaded = options.single_threaded,
lib/std/Build/Step.zig+1-1
...@@ -250,7 +250,7 @@ pub fn init(options: StepOptions) Step {...@@ -250,7 +250,7 @@ pub fn init(options: StepOptions) Step {
250 const first_ret_addr = options.first_ret_addr orelse @returnAddress();250 const first_ret_addr = options.first_ret_addr orelse @returnAddress();
251 break :blk std.debug.captureCurrentStackTrace(.{ .first_address = first_ret_addr }, addr_buf);251 break :blk std.debug.captureCurrentStackTrace(.{ .first_address = first_ret_addr }, addr_buf);
252 },252 },
253 .result_error_msgs = .{},253 .result_error_msgs = .empty,
254 .result_error_bundle = std.zig.ErrorBundle.empty,254 .result_error_bundle = std.zig.ErrorBundle.empty,
255 .result_stderr = "",255 .result_stderr = "",
256 .result_cached = false,256 .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 {...@@ -213,13 +213,13 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
213 .owner = owner,213 .owner = owner,
214 .makeFn = make,214 .makeFn = make,
215 }),215 }),
216 .argv = .{},216 .argv = .empty,
217 .cwd = null,217 .cwd = null,
218 .environ_map = null,218 .environ_map = null,
219 .disable_zig_progress = false,219 .disable_zig_progress = false,
220 .stdio = .infer_from_args,220 .stdio = .infer_from_args,
221 .stdin = .none,221 .stdin = .none,
222 .file_inputs = .{},222 .file_inputs = .empty,
223 .rename_step_with_output_arg = true,223 .rename_step_with_output_arg = true,
224 .skip_foreign_checks = false,224 .skip_foreign_checks = false,
225 .failing_to_execute_foreign_is_an_error = true,225 .failing_to_execute_foreign_is_an_error = true,
...@@ -228,7 +228,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {...@@ -228,7 +228,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
228 .captured_stderr = null,228 .captured_stderr = null,
229 .dep_output_file = null,229 .dep_output_file = null,
230 .has_side_effects = false,230 .has_side_effects = false,
231 .fuzz_tests = .{},231 .fuzz_tests = .empty,
232 .rebuilt_executable = null,232 .rebuilt_executable = null,
233 .producer = null,233 .producer = null,
234 };234 };
...@@ -642,7 +642,7 @@ pub fn addCheck(run: *Run, new_check: StdIo.Check) void {...@@ -642,7 +642,7 @@ pub fn addCheck(run: *Run, new_check: StdIo.Check) void {
642642
643 switch (run.stdio) {643 switch (run.stdio) {
644 .infer_from_args => {644 .infer_from_args => {
645 run.stdio = .{ .check = .{} };645 run.stdio = .{ .check = .empty };
646 run.stdio.check.append(b.allocator, new_check) catch @panic("OOM");646 run.stdio.check.append(b.allocator, new_check) catch @panic("OOM");
647 },647 },
648 .check => |*checks| checks.append(b.allocator, new_check) catch @panic("OOM"),648 .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 {...@@ -35,7 +35,7 @@ pub fn create(owner: *std.Build) *UpdateSourceFiles {
35 .owner = owner,35 .owner = owner,
36 .makeFn = make,36 .makeFn = make,
37 }),37 }),
38 .output_source_files = .{},38 .output_source_files = .empty,
39 };39 };
40 return usf;40 return usf;
41}41}
lib/std/Build/Step/WriteFile.zig+2-2
...@@ -94,8 +94,8 @@ pub fn create(owner: *std.Build) *WriteFile {...@@ -94,8 +94,8 @@ pub fn create(owner: *std.Build) *WriteFile {
94 .owner = owner,94 .owner = owner,
95 .makeFn = make,95 .makeFn = make,
96 }),96 }),
97 .files = .{},97 .files = .empty,
98 .directories = .{},98 .directories = .empty,
99 .generated_directory = .{ .step = &write_file.step },99 .generated_directory = .{ .step = &write_file.step },
100 };100 };
101 return write_file;101 return write_file;
lib/std/Io/Dir.zig+1-1
...@@ -334,7 +334,7 @@ pub fn walkSelectively(dir: Dir, allocator: Allocator) !SelectiveWalker {...@@ -334,7 +334,7 @@ pub fn walkSelectively(dir: Dir, allocator: Allocator) !SelectiveWalker {
334334
335 return .{335 return .{
336 .stack = stack,336 .stack = stack,
337 .name_buffer = .{},337 .name_buffer = .empty,
338 .allocator = allocator,338 .allocator = allocator,
339 };339 };
340}340}
lib/std/array_list.zig+2-2
...@@ -582,10 +582,10 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {...@@ -582,10 +582,10 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {
582 /// functions of this ArrayList in accordance with the respective582 /// functions of this ArrayList in accordance with the respective
583 /// documentation. In all cases, "invalidated" means that the memory583 /// documentation. In all cases, "invalidated" means that the memory
584 /// has been passed to an allocator's resize or free function.584 /// has been passed to an allocator's resize or free function.
585 items: Slice = &[_]T{},585 items: Slice,
586 /// How many T values this list can hold without allocating586 /// How many T values this list can hold without allocating
587 /// additional memory.587 /// additional memory.
588 capacity: usize = 0,588 capacity: usize,
589589
590 /// An ArrayList containing no elements.590 /// An ArrayList containing no elements.
591 pub const empty: Self = .{591 pub const empty: Self = .{
lib/std/builtin.zig+8-4
...@@ -592,8 +592,8 @@ pub const Type = union(enum) {...@@ -592,8 +592,8 @@ pub const Type = union(enum) {
592 size: Size,592 size: Size,
593 is_const: bool,593 is_const: bool,
594 is_volatile: bool,594 is_volatile: bool,
595 /// TODO make this u16 instead of comptime_int595 /// `null` means implicit alignment, which is equivalent to `@alignOf(child)`.
596 alignment: comptime_int,596 alignment: ?usize,
597 address_space: AddressSpace,597 address_space: AddressSpace,
598 child: type,598 child: type,
599 is_allowzero: bool,599 is_allowzero: bool,
...@@ -670,7 +670,9 @@ pub const Type = union(enum) {...@@ -670,7 +670,9 @@ pub const Type = union(enum) {
670 /// See also: `defaultValue`.670 /// See also: `defaultValue`.
671 default_value_ptr: ?*const anyopaque,671 default_value_ptr: ?*const anyopaque,
672 is_comptime: bool,672 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
675 /// Loads the field's default value from `default_value_ptr`.677 /// Loads the field's default value from `default_value_ptr`.
676 /// Returns `null` if the field has no default value.678 /// Returns `null` if the field has no default value.
...@@ -747,7 +749,9 @@ pub const Type = union(enum) {...@@ -747,7 +749,9 @@ pub const Type = union(enum) {
747 pub const UnionField = struct {749 pub const UnionField = struct {
748 name: [:0]const u8,750 name: [:0]const u8,
749 type: type,751 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
752 /// This data structure is used by the Zig language code generation and756 /// This data structure is used by the Zig language code generation and
753 /// therefore must be kept in sync with the compiler implementation.757 /// 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;...@@ -436,7 +436,7 @@ pub const thread_state_flavor_t = c_int;
436pub const ipc_space_t = mach_port_t;436pub const ipc_space_t = mach_port_t;
437pub const ipc_space_port_t = ipc_space_t;437pub 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) {
440 RCV: MACH.RCV,440 RCV: MACH.RCV,
441 SEND: MACH.SEND,441 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) {...@@ -210,7 +210,7 @@ pub const source_timer_flags_t = packed struct(usize) {
210 STRICT: bool = false,210 STRICT: bool = false,
211 unused1: @Int(.unsigned, @bitSizeOf(usize) - 1) = 0,211 unused1: @Int(.unsigned, @bitSizeOf(usize) - 1) = 0,
212};212};
213pub const source_flags_t = packed union {213pub const source_flags_t = packed union(usize) {
214 raw: usize,214 raw: usize,
215 MACH_SEND: source_mach_send_flags_t,215 MACH_SEND: source_mach_send_flags_t,
216 MACH_RECV: source_mach_recv_flags_t,216 MACH_RECV: source_mach_recv_flags_t,
lib/std/compress/lzma.zig+1-1
...@@ -349,7 +349,7 @@ pub const Decode = struct {...@@ -349,7 +349,7 @@ pub const Decode = struct {
349349
350 pub fn init(dict_size: usize, mem_limit: usize) CircularBuffer {350 pub fn init(dict_size: usize, mem_limit: usize) CircularBuffer {
351 return .{351 return .{
352 .buf = .{},352 .buf = .empty,
353 .dict_size = dict_size,353 .dict_size = dict_size,
354 .mem_limit = mem_limit,354 .mem_limit = mem_limit,
355 .cursor = 0,355 .cursor = 0,
lib/std/compress/lzma2.zig+1-1
...@@ -16,7 +16,7 @@ pub const AccumBuffer = struct {...@@ -16,7 +16,7 @@ pub const AccumBuffer = struct {
1616
17 pub fn init(memlimit: usize) AccumBuffer {17 pub fn init(memlimit: usize) AccumBuffer {
18 return .{18 return .{
19 .buf = .{},19 .buf = .empty,
20 .memlimit = memlimit,20 .memlimit = memlimit,
21 .len = 0,21 .len = 0,
22 };22 };
lib/std/debug/Coverage.zig+3-3
...@@ -27,10 +27,10 @@ string_bytes: std.ArrayList(u8),...@@ -27,10 +27,10 @@ string_bytes: std.ArrayList(u8),
27mutex: Io.Mutex,27mutex: Io.Mutex,
2828
29pub const init: Coverage = .{29pub const init: Coverage = .{
30 .directories = .{},30 .directories = .empty,
31 .files = .{},31 .files = .empty,
32 .mutex = .init,32 .mutex = .init,
33 .string_bytes = .{},33 .string_bytes = .empty,
34};34};
3535
36pub const String = enum(u32) {36pub const String = enum(u32) {
lib/std/elf.zig+2-2
...@@ -1071,7 +1071,7 @@ pub const Elf32 = struct {...@@ -1071,7 +1071,7 @@ pub const Elf32 = struct {
1071 pub const Shdr = extern struct {1071 pub const Shdr = extern struct {
1072 name: Word,1072 name: Word,
1073 type: SHT,1073 type: SHT,
1074 flags: packed struct { shf: SHF },1074 flags: packed struct(Word) { shf: SHF },
1075 addr: Elf32.Addr,1075 addr: Elf32.Addr,
1076 offset: Elf32.Off,1076 offset: Elf32.Off,
1077 size: Word,1077 size: Word,
...@@ -1161,7 +1161,7 @@ pub const Elf64 = struct {...@@ -1161,7 +1161,7 @@ pub const Elf64 = struct {
1161 pub const Shdr = extern struct {1161 pub const Shdr = extern struct {
1162 name: Word,1162 name: Word,
1163 type: SHT,1163 type: SHT,
1164 flags: packed struct { shf: SHF, unused: Word = 0 },1164 flags: packed struct(Xword) { shf: SHF, unused: Word = 0 },
1165 addr: Elf64.Addr,1165 addr: Elf64.Addr,
1166 offset: Elf64.Off,1166 offset: Elf64.Off,
1167 size: Xword,1167 size: Xword,
lib/std/hash_map.zig+3-3
...@@ -1526,9 +1526,9 @@ pub fn HashMapUnmanaged(...@@ -1526,9 +1526,9 @@ pub fn HashMapUnmanaged(
1526 }1526 }
15271527
1528 comptime {1528 comptime {
1529 if (!builtin.strip_debug_info) _ = switch (builtin.zig_backend) {1529 if (!builtin.strip_debug_info) switch (builtin.zig_backend) {
1530 .stage2_llvm => &dbHelper,1530 .stage2_llvm => _ = &dbHelper,
1531 .stage2_x86_64 => KV,1531 .stage2_x86_64 => _ = @as(KV, undefined),
1532 else => {},1532 else => {},
1533 };1533 };
1534 }1534 }
lib/std/macho.zig+1-1
...@@ -851,7 +851,7 @@ pub const nlist = extern struct {...@@ -851,7 +851,7 @@ pub const nlist = extern struct {
851851
852pub const nlist_64 = extern struct {852pub const nlist_64 = extern struct {
853 n_strx: u32,853 n_strx: u32,
854 n_type: packed union {854 n_type: packed union(u8) {
855 bits: packed struct(u8) {855 bits: packed struct(u8) {
856 ext: bool,856 ext: bool,
857 type: enum(u3) {857 type: enum(u3) {
lib/std/math/big/int.zig+12-2
...@@ -924,7 +924,12 @@ pub const Mutable = struct {...@@ -924,7 +924,12 @@ pub const Mutable = struct {
924 /// Asserts the result fits in `r`. Upper bound on the number of limbs needed by924 /// Asserts the result fits in `r`. Upper bound on the number of limbs needed by
925 /// r is `calcTwosCompLimbCount(bit_count)`.925 /// r is `calcTwosCompLimbCount(bit_count)`.
926 pub fn bitReverse(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void {926 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
929 r.copy(a);934 r.copy(a);
930935
...@@ -986,7 +991,12 @@ pub const Mutable = struct {...@@ -986,7 +991,12 @@ pub const Mutable = struct {
986 /// Asserts the result fits in `r`. Upper bound on the number of limbs needed by991 /// Asserts the result fits in `r`. Upper bound on the number of limbs needed by
987 /// r is `calcTwosCompLimbCount(8*byte_count)`.992 /// r is `calcTwosCompLimbCount(8*byte_count)`.
988 pub fn byteSwap(r: *Mutable, a: Const, signedness: Signedness, byte_count: usize) void {993 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
991 r.copy(a);1001 r.copy(a);
992 const limbs_required = calcTwosCompLimbCount(8 * byte_count);1002 const limbs_required = calcTwosCompLimbCount(8 * byte_count);
lib/std/mem.zig+12-4
...@@ -38,6 +38,10 @@ pub const Alignment = enum(math.Log2Int(usize)) {...@@ -38,6 +38,10 @@ pub const Alignment = enum(math.Log2Int(usize)) {
38 return @enumFromInt(@ctz(n));38 return @enumFromInt(@ctz(n));
39 }39 }
4040
41 pub fn fromByteUnitsOptional(maybe_n: ?usize) ?Alignment {
42 return if (maybe_n) |n| .fromByteUnits(n) else null;
43 }
44
41 pub inline fn of(comptime T: type) Alignment {45 pub inline fn of(comptime T: type) Alignment {
42 return comptime fromByteUnits(@alignOf(T));46 return comptime fromByteUnits(@alignOf(T));
43 }47 }
...@@ -2287,8 +2291,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a...@@ -2287,8 +2291,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a
2287 ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));2291 ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));
2288 } else inline for (std.meta.fields(S)) |f| {2292 } else inline for (std.meta.fields(S)) |f| {
2289 switch (@typeInfo(f.type)) {2293 switch (@typeInfo(f.type)) {
2290 .@"struct" => 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)),
2291 .@"union", .array => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment), &@field(ptr, f.name)),2295 .@"union", .array => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment orelse @alignOf(f.type)), &@field(ptr, f.name)),
2292 .@"enum" => {2296 .@"enum" => {
2293 @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name))));2297 @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name))));
2294 },2298 },
...@@ -4330,7 +4334,7 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize {...@@ -4330,7 +4334,7 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize {
4330 @compileError("expected many item pointer, got " ++ @typeName(T));4334 @compileError("expected many item pointer, got " ++ @typeName(T));
43314335
4332 // Do nothing if the pointer is already well-aligned.4336 // 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))
4334 return 0;4338 return 0;
43354339
4336 // Calculate the aligned base address with an eye out for overflow.4340 // Calculate the aligned base address with an eye out for overflow.
...@@ -4388,7 +4392,11 @@ fn CopyPtrAttrs(...@@ -4388,7 +4392,11 @@ fn CopyPtrAttrs(
4388 .@"const" = ptr.is_const,4392 .@"const" = ptr.is_const,
4389 .@"volatile" = ptr.is_volatile,4393 .@"volatile" = ptr.is_volatile,
4390 .@"allowzero" = ptr.is_allowzero,4394 .@"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 },
4392 .@"addrspace" = ptr.address_space,4400 .@"addrspace" = ptr.address_space,
4393 }, child, null);4401 }, child, null);
4394}4402}
lib/std/mem/Allocator.zig+52-47
...@@ -179,7 +179,11 @@ pub fn destroy(self: Allocator, ptr: anytype) void {...@@ -179,7 +179,11 @@ pub fn destroy(self: Allocator, ptr: anytype) void {
179 const T = info.child;179 const T = info.child;
180 if (@sizeOf(T) == 0) return;180 if (@sizeOf(T) == 0) return;
181 const non_const_ptr = @as([*]u8, @ptrCast(@constCast(ptr)));181 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 );
183}187}
184188
185/// Allocates an array of `n` items of type `T` and sets all the189/// Allocates an array of `n` items of type `T` and sets all the
...@@ -266,7 +270,7 @@ pub inline fn allocAdvancedWithRetAddr(...@@ -266,7 +270,7 @@ pub inline fn allocAdvancedWithRetAddr(
266 n: usize,270 n: usize,
267 return_address: usize,271 return_address: usize,
268) Error![]align(if (alignment) |a| a.toByteUnits() else @alignOf(T)) T {272) 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);
270 const ptr: [*]align(a.toByteUnits()) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address));274 const ptr: [*]align(a.toByteUnits()) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address));
271 return ptr[0..n];275 return ptr[0..n];
272}276}
...@@ -278,7 +282,7 @@ fn allocWithSizeAndAlignment(...@@ -278,7 +282,7 @@ fn allocWithSizeAndAlignment(
278 n: usize,282 n: usize,
279 return_address: usize,283 return_address: usize,
280) Error![*]align(alignment.toByteUnits()) u8 {284) 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;
282 return self.allocBytesWithAlignment(alignment, byte_count, return_address);286 return self.allocBytesWithAlignment(alignment, byte_count, return_address);
283}287}
284288
...@@ -293,7 +297,7 @@ fn allocBytesWithAlignment(...@@ -293,7 +297,7 @@ fn allocBytesWithAlignment(
293 return @as([*]align(alignment.toByteUnits()) u8, @ptrFromInt(ptr));297 return @as([*]align(alignment.toByteUnits()) u8, @ptrFromInt(ptr));
294 }298 }
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;
297 @memset(byte_ptr[0..byte_count], undefined);301 @memset(byte_ptr[0..byte_count], undefined);
298 return @alignCast(byte_ptr);302 return @alignCast(byte_ptr);
299}303}
...@@ -308,9 +312,9 @@ fn allocBytesWithAlignment(...@@ -308,9 +312,9 @@ fn allocBytesWithAlignment(
308///312///
309/// `new_len` may be zero, in which case the allocation is freed.313/// `new_len` may be zero, in which case the allocation is freed.
310pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {314pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
311 const Slice = @typeInfo(@TypeOf(allocation)).pointer;315 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
312 const T = Slice.child;316 comptime assert(slice_info.size == .slice);
313 const alignment = Slice.alignment;317 const T = slice_info.child;
314 if (new_len == 0) {318 if (new_len == 0) {
315 self.free(allocation);319 self.free(allocation);
316 return true;320 return true;
...@@ -323,7 +327,12 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {...@@ -323,7 +327,12 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
323 // on WebAssembly: https://github.com/ziglang/zig/issues/9660327 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
324 //const new_len_bytes = new_len *| @sizeOf(T);328 //const new_len_bytes = new_len *| @sizeOf(T);
325 const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return false;329 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 );
327}336}
328337
329/// Request to modify the size of an allocation, allowing relocation.338/// 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 {...@@ -342,14 +351,11 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
342/// `new_len` may be zero, in which case the allocation is freed.351/// `new_len` may be zero, in which case the allocation is freed.
343///352///
344/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`.353/// 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: {354pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allocation) {
346 const Slice = @typeInfo(@TypeOf(allocation)).pointer;355 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
347 break :t ?[]align(Slice.alignment) Slice.child;356 comptime assert(slice_info.size == .slice);
348} {357 const T = slice_info.child;
349 const Slice = @typeInfo(@TypeOf(allocation)).pointer;358
350 const T = Slice.child;
351
352 const alignment = Slice.alignment;
353 if (new_len == 0) {359 if (new_len == 0) {
354 self.free(allocation);360 self.free(allocation);
355 return allocation[0..0];361 return allocation[0..0];
...@@ -367,9 +373,13 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {...@@ -367,9 +373,13 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {
367 // on WebAssembly: https://github.com/ziglang/zig/issues/9660373 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
368 //const new_len_bytes = new_len *| @sizeOf(T);374 //const new_len_bytes = new_len *| @sizeOf(T);
369 const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return null;375 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;376 const new_ptr = self.rawRemap(
371 const new_memory: []align(alignment) u8 = @alignCast(new_ptr[0..new_len_bytes]);377 old_memory,
372 return mem.bytesAsSlice(T, new_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]));
373}383}
374384
375/// This function requests a new size for an existing allocation, which385/// 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: {...@@ -386,10 +396,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {
386/// do the realloc more efficiently than the caller396/// do the realloc more efficiently than the caller
387/// * `resize` which returns `false` when the `Allocator` implementation cannot397/// * `resize` which returns `false` when the `Allocator` implementation cannot
388/// change the size without relocating the allocation.398/// change the size without relocating the allocation.
389pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) t: {399pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old_mem) {
390 const Slice = @typeInfo(@TypeOf(old_mem)).pointer;
391 break :t Error![]align(Slice.alignment) Slice.child;
392} {
393 return self.reallocAdvanced(old_mem, new_n, @returnAddress());400 return self.reallocAdvanced(old_mem, new_n, @returnAddress());
394}401}
395402
...@@ -398,51 +405,49 @@ pub fn reallocAdvanced(...@@ -398,51 +405,49 @@ pub fn reallocAdvanced(
398 old_mem: anytype,405 old_mem: anytype,
399 new_n: usize,406 new_n: usize,
400 return_address: usize,407 return_address: usize,
401) t: {408) Error!@TypeOf(old_mem) {
402 const Slice = @typeInfo(@TypeOf(old_mem)).pointer;409 const slice_info = @typeInfo(@TypeOf(old_mem)).pointer;
403 break :t Error![]align(Slice.alignment) Slice.child;410 comptime assert(slice_info.size == .slice);
404} {411 const T = slice_info.child;
405 const Slice = @typeInfo(@TypeOf(old_mem)).pointer;
406 const T = Slice.child;
407 if (old_mem.len == 0) {412 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);
409 }414 }
410 if (new_n == 0) {415 if (new_n == 0) {
411 self.free(old_mem);416 self.free(old_mem);
412 const ptr = comptime std.mem.alignBackward(usize, math.maxInt(usize), Slice.alignment);417 const alignment = slice_info.alignment orelse @alignOf(T);
413 return @as([*]align(Slice.alignment) T, @ptrFromInt(ptr))[0..0];418 const addr = comptime std.mem.alignBackward(usize, math.maxInt(usize), alignment);
419 const ptr: *align(alignment) [0]T = @ptrFromInt(addr);
420 return ptr;
414 }421 }
415422
416 const old_byte_slice = mem.sliceAsBytes(old_mem);423 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;
418 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure425 // 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| {426 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), byte_count, return_address)) |p| {
420 const new_bytes: []align(Slice.alignment) u8 = @alignCast(p[0..byte_count]);427 return @ptrCast(@alignCast(p[0..byte_count]));
421 return mem.bytesAsSlice(T, new_bytes);
422 }428 }
423429
424 const new_mem = self.rawAlloc(byte_count, .fromByteUnits(Slice.alignment), return_address) orelse430 const new_mem = self.rawAlloc(byte_count, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), return_address) orelse
425 return error.OutOfMemory;431 return error.OutOfMemory;
426 const copy_len = @min(byte_count, old_byte_slice.len);432 const copy_len = @min(byte_count, old_byte_slice.len);
427 @memcpy(new_mem[0..copy_len], old_byte_slice[0..copy_len]);433 @memcpy(new_mem[0..copy_len], old_byte_slice[0..copy_len]);
428 @memset(old_byte_slice, undefined);434 @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]);437 return @ptrCast(@alignCast(new_mem[0..byte_count]));
432 return mem.bytesAsSlice(T, new_bytes);
433}438}
434439
435/// Free an array allocated with `alloc`.440/// Free an array allocated with `alloc`.
436/// If memory has length 0, free is a no-op.441/// If memory has length 0, free is a no-op.
437/// To free a single item, see `destroy`.442/// To free a single item, see `destroy`.
438pub fn free(self: Allocator, memory: anytype) void {443pub fn free(self: Allocator, memory: anytype) void {
439 const Slice = @typeInfo(@TypeOf(memory)).pointer;444 const slice_info = @typeInfo(@TypeOf(memory)).pointer;
440 const bytes = mem.sliceAsBytes(memory);445 comptime assert(slice_info.size == .slice);
441 const bytes_len = bytes.len + if (Slice.sentinel() != null) @sizeOf(Slice.child) else 0;446 const mem_with_sent = memory[0 .. memory.len + @intFromBool(slice_info.sentinel() != null)];
442 if (bytes_len == 0) return;447 const bytes: []u8 = @ptrCast(@constCast(mem_with_sent));
443 const non_const_ptr = @constCast(bytes.ptr);448 if (bytes.len == 0) return;
444 @memset(non_const_ptr[0..bytes_len], undefined);449 @memset(bytes, undefined);
445 self.rawFree(non_const_ptr[0..bytes_len], .fromByteUnits(Slice.alignment), @returnAddress());450 self.rawFree(bytes, .fromByteUnits(slice_info.alignment orelse @alignOf(slice_info.child)), @returnAddress());
446}451}
447452
448/// Copies `m` to newly allocated memory. Caller owns the memory.453/// 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 {...@@ -63,7 +63,7 @@ pub fn alignment(comptime T: type) comptime_int {
63 .pointer, .@"fn" => alignment(info.child),63 .pointer, .@"fn" => alignment(info.child),
64 else => @alignOf(T),64 else => @alignOf(T),
65 },65 },
66 .pointer => |info| info.alignment,66 .pointer => |info| info.alignment orelse @alignOf(info.child),
67 else => @alignOf(T),67 else => @alignOf(T),
68 };68 };
69}69}
...@@ -315,7 +315,7 @@ test declarationInfo {...@@ -315,7 +315,7 @@ test declarationInfo {
315 try testing.expect(comptime mem.eql(u8, info.name, "a"));315 try testing.expect(comptime mem.eql(u8, info.name, "a"));
316 }316 }
317}317}
318pub fn fields(comptime T: type) switch (@typeInfo(T)) {318pub inline fn fields(comptime T: type) switch (@typeInfo(T)) {
319 .@"struct" => []const Type.StructField,319 .@"struct" => []const Type.StructField,
320 .@"union" => []const Type.UnionField,320 .@"union" => []const Type.UnionField,
321 .@"enum" => []const Type.EnumField,321 .@"enum" => []const Type.EnumField,
lib/std/multi_array_list.zig+15-9
...@@ -19,7 +19,11 @@ const testing = std.testing;...@@ -19,7 +19,11 @@ const testing = std.testing;
19/// For unions you can call `.items(.tags)` or `.items(.data)`.19/// For unions you can call `.items(.tags)` or `.items(.data)`.
20pub fn MultiArrayList(comptime T: type) type {20pub fn MultiArrayList(comptime T: type) type {
21 return struct {21 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,
23 len: usize = 0,27 len: usize = 0,
24 capacity: usize = 0,28 capacity: usize = 0,
2529
...@@ -133,10 +137,8 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -133,10 +137,8 @@ pub fn MultiArrayList(comptime T: type) type {
133 if (self.ptrs.len == 0 or self.capacity == 0) {137 if (self.ptrs.len == 0 or self.capacity == 0) {
134 return .{};138 return .{};
135 }139 }
136 const unaligned_ptr = self.ptrs[sizes.fields[0]];
137 const aligned_ptr: [*]align(@alignOf(Elem)) u8 = @alignCast(unaligned_ptr);
138 return .{140 return .{
139 .bytes = aligned_ptr,141 .bytes = self.ptrs[sizes.fields[0]],
140 .len = self.len,142 .len = self.len,
141 .capacity = self.capacity,143 .capacity = self.capacity,
142 };144 };
...@@ -179,6 +181,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -179,6 +181,7 @@ pub fn MultiArrayList(comptime T: type) type {
179 const fields = meta.fields(Elem);181 const fields = meta.fields(Elem);
180 /// `sizes.bytes` is an array of @sizeOf each T field. Sorted by alignment, descending.182 /// `sizes.bytes` is an array of @sizeOf each T field. Sorted by alignment, descending.
181 /// `sizes.fields` is an array mapping from `sizes.bytes` array index to field index.183 /// `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.
182 const sizes = blk: {185 const sizes = blk: {
183 const Data = struct {186 const Data = struct {
184 size: usize,187 size: usize,
...@@ -186,12 +189,14 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -186,12 +189,14 @@ pub fn MultiArrayList(comptime T: type) type {
186 alignment: usize,189 alignment: usize,
187 };190 };
188 var data: [fields.len]Data = undefined;191 var data: [fields.len]Data = undefined;
192 var big_align: usize = 1;
189 for (fields, 0..) |field_info, i| {193 for (fields, 0..) |field_info, i| {
190 data[i] = .{194 data[i] = .{
191 .size = @sizeOf(field_info.type),195 .size = @sizeOf(field_info.type),
192 .size_index = i,196 .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),
194 };198 };
199 big_align = @max(big_align, data[i].alignment);
195 }200 }
196 const Sort = struct {201 const Sort = struct {
197 fn lessThan(context: void, lhs: Data, rhs: Data) bool {202 fn lessThan(context: void, lhs: Data, rhs: Data) bool {
...@@ -210,6 +215,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -210,6 +215,7 @@ pub fn MultiArrayList(comptime T: type) type {
210 break :blk .{215 break :blk .{
211 .bytes = sizes_bytes,216 .bytes = sizes_bytes,
212 .fields = field_indexes,217 .fields = field_indexes,
218 .big_align = mem.Alignment.fromByteUnits(big_align),
213 };219 };
214 };220 };
215221
...@@ -452,7 +458,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -452,7 +458,7 @@ pub fn MultiArrayList(comptime T: type) type {
452 assert(new_len <= self.capacity);458 assert(new_len <= self.capacity);
453 assert(new_len <= self.len);459 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 {
456 const self_slice = self.slice();462 const self_slice = self.slice();
457 inline for (fields, 0..) |field_info, i| {463 inline for (fields, 0..) |field_info, i| {
458 if (@sizeOf(field_info.type) != 0) {464 if (@sizeOf(field_info.type) != 0) {
...@@ -533,7 +539,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -533,7 +539,7 @@ pub fn MultiArrayList(comptime T: type) type {
533 /// `new_capacity` must be greater or equal to `len`.539 /// `new_capacity` must be greater or equal to `len`.
534 pub fn setCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void {540 pub fn setCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void {
535 assert(new_capacity >= self.len);541 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));
537 if (self.len == 0) {543 if (self.len == 0) {
538 gpa.free(self.allocatedBytes());544 gpa.free(self.allocatedBytes());
539 self.bytes = new_bytes.ptr;545 self.bytes = new_bytes.ptr;
...@@ -650,8 +656,8 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -650,8 +656,8 @@ pub fn MultiArrayList(comptime T: type) type {
650 return elem_bytes * capacity;656 return elem_bytes * capacity;
651 }657 }
652658
653 fn allocatedBytes(self: Self) []align(@alignOf(Elem)) u8 {659 fn allocatedBytes(self: Self) []align(sizes.big_align.toByteUnits()) u8 {
654 return self.bytes[0..capacityInBytes(self.capacity)];660 return @alignCast(self.bytes[0..capacityInBytes(self.capacity)]);
655 }661 }
656662
657 fn FieldType(comptime field: Field) type {663 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 {...@@ -7113,7 +7113,7 @@ pub const io_uring_buf_reg = extern struct {
7113 flags: Flags,7113 flags: Flags,
7114 resv: [3]u64,7114 resv: [3]u64,
71157115
7116 pub const Flags = packed struct {7116 pub const Flags = packed struct(u16) {
7117 _0: u1 = 0,7117 _0: u1 = 0,
7118 /// Incremental buffer consumption.7118 /// Incremental buffer consumption.
7119 inc: bool,7119 inc: bool,
lib/std/os/windows.zig+5-5
...@@ -4160,7 +4160,7 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {...@@ -4160,7 +4160,7 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {
4160 BeginAddress: DWORD,4160 BeginAddress: DWORD,
4161 DUMMYUNIONNAME: extern union {4161 DUMMYUNIONNAME: extern union {
4162 UnwindData: DWORD,4162 UnwindData: DWORD,
4163 DUMMYSTRUCTNAME: packed struct {4163 DUMMYSTRUCTNAME: packed struct(u32) {
4164 Flag: u2,4164 Flag: u2,
4165 FunctionLength: u11,4165 FunctionLength: u11,
4166 Ret: u2,4166 Ret: u2,
...@@ -4177,7 +4177,7 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {...@@ -4177,7 +4177,7 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {
4177 BeginAddress: DWORD,4177 BeginAddress: DWORD,
4178 DUMMYUNIONNAME: extern union {4178 DUMMYUNIONNAME: extern union {
4179 UnwindData: DWORD,4179 UnwindData: DWORD,
4180 DUMMYSTRUCTNAME: packed struct {4180 DUMMYSTRUCTNAME: packed struct(u32) {
4181 Flag: u2,4181 Flag: u2,
4182 FunctionLength: u11,4182 FunctionLength: u11,
4183 RegF: u3,4183 RegF: u3,
...@@ -5013,7 +5013,7 @@ pub const KUSER_SHARED_DATA = extern struct {...@@ -5013,7 +5013,7 @@ pub const KUSER_SHARED_DATA = extern struct {
5013 KdDebuggerEnabled: BOOLEAN,5013 KdDebuggerEnabled: BOOLEAN,
5014 DummyUnion1: extern union {5014 DummyUnion1: extern union {
5015 MitigationPolicies: UCHAR,5015 MitigationPolicies: UCHAR,
5016 Alt: packed struct {5016 Alt: packed struct(u8) {
5017 NXSupportPolicy: u2,5017 NXSupportPolicy: u2,
5018 SEHValidationPolicy: u2,5018 SEHValidationPolicy: u2,
5019 CurDirDevicesSkippedForDlls: u2,5019 CurDirDevicesSkippedForDlls: u2,
...@@ -5029,7 +5029,7 @@ pub const KUSER_SHARED_DATA = extern struct {...@@ -5029,7 +5029,7 @@ pub const KUSER_SHARED_DATA = extern struct {
5029 SafeBootMode: BOOLEAN,5029 SafeBootMode: BOOLEAN,
5030 DummyUnion2: extern union {5030 DummyUnion2: extern union {
5031 VirtualizationFlags: UCHAR,5031 VirtualizationFlags: UCHAR,
5032 Alt: packed struct {5032 Alt: packed struct(u8) {
5033 ArchStartedInEl2: u1,5033 ArchStartedInEl2: u1,
5034 QcSlIsSupported: u1,5034 QcSlIsSupported: u1,
5035 SpareBits: u6,5035 SpareBits: u6,
...@@ -5038,7 +5038,7 @@ pub const KUSER_SHARED_DATA = extern struct {...@@ -5038,7 +5038,7 @@ pub const KUSER_SHARED_DATA = extern struct {
5038 Reserved12: [2]UCHAR,5038 Reserved12: [2]UCHAR,
5039 DummyUnion3: extern union {5039 DummyUnion3: extern union {
5040 SharedDataFlags: ULONG,5040 SharedDataFlags: ULONG,
5041 Alt: packed struct {5041 Alt: packed struct(u32) {
5042 DbgErrorPortPresent: u1,5042 DbgErrorPortPresent: u1,
5043 DbgElevationEnabled: u1,5043 DbgElevationEnabled: u1,
5044 DbgVirtEnabled: u1,5044 DbgVirtEnabled: u1,
lib/std/pdb.zig+2-2
...@@ -332,7 +332,7 @@ pub const ProcSym = extern struct {...@@ -332,7 +332,7 @@ pub const ProcSym = extern struct {
332 name: [1]u8, // null-terminated332 name: [1]u8, // null-terminated
333};333};
334334
335pub const ProcSymFlags = packed struct {335pub const ProcSymFlags = packed struct(u8) {
336 has_fp: bool,336 has_fp: bool,
337 has_iret: bool,337 has_iret: bool,
338 has_fret: bool,338 has_fret: bool,
...@@ -373,7 +373,7 @@ pub const LineFragmentHeader = extern struct {...@@ -373,7 +373,7 @@ pub const LineFragmentHeader = extern struct {
373 code_size: u32,373 code_size: u32,
374};374};
375375
376pub const LineFlags = packed struct {376pub const LineFlags = packed struct(u16) {
377 /// CV_LINES_HAVE_COLUMNS377 /// CV_LINES_HAVE_COLUMNS
378 have_columns: bool,378 have_columns: bool,
379 unused: u15,379 unused: u15,
lib/std/testing.zig+2-3
...@@ -950,9 +950,8 @@ test "expectEqualDeep primitive type" {...@@ -950,9 +950,8 @@ test "expectEqualDeep primitive type" {
950}950}
951951
952test "expectEqualDeep pointer" {952test "expectEqualDeep pointer" {
953 const a = 1;953 try comptime expectEqualDeep(&1, &1);
954 const b = 1;954 try expectEqualDeep(&@as(u32, 1), &@as(u32, 1));
955 try expectEqualDeep(&a, &b);
956}955}
957956
958test "expectEqualDeep composite type" {957test "expectEqualDeep composite type" {
lib/std/zig.zig+11-2
...@@ -837,6 +837,10 @@ pub const SimpleComptimeReason = enum(u32) {...@@ -837,6 +837,10 @@ pub const SimpleComptimeReason = enum(u32) {
837 tuple_field_types,837 tuple_field_types,
838 enum_field_names,838 enum_field_names,
839 enum_field_values,839 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
841 // Evaluating at comptime because decl/field name must be comptime-known.845 // Evaluating at comptime because decl/field name must be comptime-known.
842 decl_name,846 decl_name,
...@@ -864,7 +868,7 @@ pub const SimpleComptimeReason = enum(u32) {...@@ -864,7 +868,7 @@ pub const SimpleComptimeReason = enum(u32) {
864 casted_to_comptime_enum,868 casted_to_comptime_enum,
865 casted_to_comptime_int,869 casted_to_comptime_int,
866 casted_to_comptime_float,870 casted_to_comptime_float,
867 panic_handler,871 std_builtin_decl,
868872
869 pub fn message(r: SimpleComptimeReason) []const u8 {873 pub fn message(r: SimpleComptimeReason) []const u8 {
870 return switch (r) {874 return switch (r) {
...@@ -925,6 +929,11 @@ pub const SimpleComptimeReason = enum(u32) {...@@ -925,6 +929,11 @@ pub const SimpleComptimeReason = enum(u32) {
925 .enum_field_names => "enum field names must be comptime-known",929 .enum_field_names => "enum field names must be comptime-known",
926 .enum_field_values => "enum field values must be comptime-known",930 .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
928 .decl_name => "declaration name must be comptime-known",937 .decl_name => "declaration name must be comptime-known",
929 .field_name => "field name must be comptime-known",938 .field_name => "field name must be comptime-known",
930 .tuple_field_index => "tuple field index must be comptime-known",939 .tuple_field_index => "tuple field index must be comptime-known",
...@@ -948,7 +957,7 @@ pub const SimpleComptimeReason = enum(u32) {...@@ -948,7 +957,7 @@ pub const SimpleComptimeReason = enum(u32) {
948 .casted_to_comptime_enum => "value casted to enum with 'comptime_int' tag type must be comptime-known",957 .casted_to_comptime_enum => "value casted to enum with 'comptime_int' tag type must be comptime-known",
949 .casted_to_comptime_int => "value casted to 'comptime_int' must be comptime-known",958 .casted_to_comptime_int => "value casted to 'comptime_int' must be comptime-known",
950 .casted_to_comptime_float => "value casted to 'comptime_float' must be comptime-known",959 .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",
952 // zig fmt: on961 // zig fmt: on
953 };962 };
954 }963 }
lib/std/zig/Ast.zig+4-4
...@@ -175,10 +175,10 @@ pub fn parseTokens(...@@ -175,10 +175,10 @@ pub fn parseTokens(
175 .source = source,175 .source = source,
176 .gpa = gpa,176 .gpa = gpa,
177 .tokens = tokens,177 .tokens = tokens,
178 .errors = .{},178 .errors = .empty,
179 .nodes = .{},179 .nodes = .empty,
180 .extra_data = .{},180 .extra_data = .empty,
181 .scratch = .{},181 .scratch = .empty,
182 .tok_i = 0,182 .tok_i = 0,
183 };183 };
184 defer parser.errors.deinit(gpa);184 defer parser.errors.deinit(gpa);
lib/std/zig/AstGen.zig+530-1102
...@@ -1780,7 +1780,7 @@ fn structInitExpr(...@@ -1780,7 +1780,7 @@ fn structInitExpr(
1780 try gop.value_ptr.append(sfba_allocator, name_token);1780 try gop.value_ptr.append(sfba_allocator, name_token);
1781 any_duplicate = true;1781 any_duplicate = true;
1782 } else {1782 } else {
1783 gop.value_ptr.* = .{};1783 gop.value_ptr.* = .empty;
1784 try gop.value_ptr.append(sfba_allocator, name_token);1784 try gop.value_ptr.append(sfba_allocator, name_token);
1785 }1785 }
1786 }1786 }
...@@ -3975,81 +3975,67 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node....@@ -3975,81 +3975,67 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.
3975 return rvalue(gz, ri, result, node);3975 return rvalue(gz, ri, result, node);
3976}3976}
39773977
3978const WipMembers = struct {3978const Scratch = struct {
3979 payload: *ArrayList(u32),3979 astgen: *AstGen,
3980 payload_top: usize,3980 scratch_top: u32,
3981 field_bits_start: u32,3981 fn init(astgen: *AstGen) Scratch {
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);
3998 return .{3982 return .{
3999 .payload = payload,3983 .astgen = astgen,
4000 .payload_top = payload_top,3984 .scratch_top = @intCast(astgen.scratch.items.len),
4001 .field_bits_start = field_bits_start,
4002 .fields_start = fields_start,
4003 .fields_end = fields_start,
4004 };3985 };
4005 }3986 }
40063987 fn reset(s: *Scratch) void {
4007 fn nextDecl(self: *Self, decl_inst: Zir.Inst.Index) void {3988 s.astgen.scratch.shrinkRetainingCapacity(s.scratch_top);
4008 self.payload.items[self.payload_top + self.decl_index] = @intFromEnum(decl_inst);3989 s.* = undefined;
4009 self.decl_index += 1;
4010 }3990 }
40113991 fn addSlice(s: *Scratch, len: u32) Allocator.Error!Slice {
4012 fn nextField(self: *Self, comptime bits_per_field: u32, bits: [bits_per_field]bool) void {3992 const start: u32 = @intCast(s.astgen.scratch.items.len);
4013 const fields_per_u32 = 32 / bits_per_field;3993 try s.astgen.scratch.resize(s.astgen.gpa, start + len);
4014 const index = self.field_bits_start + self.field_index / fields_per_u32;3994 return .{ .start = start, .len = len };
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;
4024 }3995 }
40253996 fn addOptionalSlice(s: *Scratch, present: bool, len: u32) Allocator.Error!?Slice {
4026 fn appendToField(self: *Self, data: u32) void {3997 if (!present) return null;
4027 assert(self.fields_end < self.payload.items.len);3998 return try addSlice(s, len);
4028 self.payload.items[self.fields_end] = data;
4029 self.fields_end += 1;
4030 }3999 }
40314000 fn appendBodyWithFixups(s: *Scratch, body: []const Zir.Inst.Index) Allocator.Error!u32 {
4032 fn finishBits(self: *Self, comptime bits_per_field: u32) void {4001 const len = countBodyLenAfterFixups(s.astgen, body);
4033 if (bits_per_field > 0) {4002 try s.astgen.scratch.ensureUnusedCapacity(s.astgen.gpa, len);
4034 const fields_per_u32 = 32 / bits_per_field;4003 appendBodyWithFixupsArrayList(s.astgen, &s.astgen.scratch, body);
4035 const empty_field_slots = fields_per_u32 - (self.field_index % fields_per_u32);4004 return len;
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 }
4041 }4005 }
40424006 /// Returns the slice containing all data added to this `Scratch`.
4043 fn declsSlice(self: *Self) []u32 {4007 fn all(s: *Scratch) Slice {
4044 return self.payload.items[self.payload_top..][0..self.decl_index];4008 const len = s.astgen.scratch.items.len - s.scratch_top;
4009 return .{ .start = s.scratch_top, .len = @intCast(len) };
4045 }4010 }
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 {4020const WipDecls = struct {
4048 return self.payload.items[self.field_bits_start..self.fields_end];4021 astgen: *AstGen,
4049 }4022 slice: Scratch.Slice,
4023 index: u32,
40504024
4051 fn deinit(self: *Self) void {4025 fn init(scratch: *Scratch, decls_len: u32) Allocator.Error!WipDecls {
4052 self.payload.items.len = self.payload_top;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;
4053 }4039 }
4054};4040};
40554041
...@@ -4057,7 +4043,7 @@ fn fnDecl(...@@ -4057,7 +4043,7 @@ fn fnDecl(
4057 astgen: *AstGen,4043 astgen: *AstGen,
4058 gz: *GenZir,4044 gz: *GenZir,
4059 scope: *Scope,4045 scope: *Scope,
4060 wip_members: *WipMembers,4046 wip_decls: *WipDecls,
4061 decl_node: Ast.Node.Index,4047 decl_node: Ast.Node.Index,
4062 body_node: Ast.Node.OptionalIndex,4048 body_node: Ast.Node.OptionalIndex,
4063 fn_proto: Ast.full.FnProto,4049 fn_proto: Ast.full.FnProto,
...@@ -4133,7 +4119,7 @@ fn fnDecl(...@@ -4133,7 +4119,7 @@ fn fnDecl(
4133 assert(!is_extern); // validated by parser (TODO why???)4119 assert(!is_extern); // validated by parser (TODO why???)
4134 }4120 }
41354121
4136 wip_members.nextDecl(decl_inst);4122 wip_decls.nextDecl(decl_inst);
41374123
4138 var type_gz: GenZir = .{4124 var type_gz: GenZir = .{
4139 .is_comptime = true,4125 .is_comptime = true,
...@@ -4488,7 +4474,7 @@ fn globalVarDecl(...@@ -4488,7 +4474,7 @@ fn globalVarDecl(
4488 astgen: *AstGen,4474 astgen: *AstGen,
4489 gz: *GenZir,4475 gz: *GenZir,
4490 scope: *Scope,4476 scope: *Scope,
4491 wip_members: *WipMembers,4477 wip_decls: *WipDecls,
4492 node: Ast.Node.Index,4478 node: Ast.Node.Index,
4493 var_decl: Ast.full.VarDecl,4479 var_decl: Ast.full.VarDecl,
4494) InnerError!void {4480) InnerError!void {
...@@ -4533,7 +4519,7 @@ fn globalVarDecl(...@@ -4533,7 +4519,7 @@ fn globalVarDecl(
4533 const decl_column = astgen.source_column;4519 const decl_column = astgen.source_column;
45344520
4535 const decl_inst = try gz.makeDeclaration(node);4521 const decl_inst = try gz.makeDeclaration(node);
4536 wip_members.nextDecl(decl_inst);4522 wip_decls.nextDecl(decl_inst);
45374523
4538 if (var_decl.ast.init_node.unwrap()) |init_node| {4524 if (var_decl.ast.init_node.unwrap()) |init_node| {
4539 if (is_extern) {4525 if (is_extern) {
...@@ -4635,7 +4621,7 @@ fn comptimeDecl(...@@ -4635,7 +4621,7 @@ fn comptimeDecl(
4635 astgen: *AstGen,4621 astgen: *AstGen,
4636 gz: *GenZir,4622 gz: *GenZir,
4637 scope: *Scope,4623 scope: *Scope,
4638 wip_members: *WipMembers,4624 wip_decls: *WipDecls,
4639 node: Ast.Node.Index,4625 node: Ast.Node.Index,
4640) InnerError!void {4626) InnerError!void {
4641 const tree = astgen.tree;4627 const tree = astgen.tree;
...@@ -4650,7 +4636,7 @@ fn comptimeDecl(...@@ -4650,7 +4636,7 @@ fn comptimeDecl(
4650 // Up top so the ZIR instruction index marks the start range of this4636 // Up top so the ZIR instruction index marks the start range of this
4651 // top-level declaration.4637 // top-level declaration.
4652 const decl_inst = try gz.makeDeclaration(node);4638 const decl_inst = try gz.makeDeclaration(node);
4653 wip_members.nextDecl(decl_inst);4639 wip_decls.nextDecl(decl_inst);
4654 astgen.advanceSourceCursorToNode(node);4640 astgen.advanceSourceCursorToNode(node);
46554641
4656 // This is just needed for the `setDeclaration` call.4642 // This is just needed for the `setDeclaration` call.
...@@ -4698,7 +4684,7 @@ fn testDecl(...@@ -4698,7 +4684,7 @@ fn testDecl(
4698 astgen: *AstGen,4684 astgen: *AstGen,
4699 gz: *GenZir,4685 gz: *GenZir,
4700 scope: *Scope,4686 scope: *Scope,
4701 wip_members: *WipMembers,4687 wip_decls: *WipDecls,
4702 node: Ast.Node.Index,4688 node: Ast.Node.Index,
4703) InnerError!void {4689) InnerError!void {
4704 const tree = astgen.tree;4690 const tree = astgen.tree;
...@@ -4714,7 +4700,7 @@ fn testDecl(...@@ -4714,7 +4700,7 @@ fn testDecl(
4714 // top-level declaration.4700 // top-level declaration.
4715 const decl_inst = try gz.makeDeclaration(node);4701 const decl_inst = try gz.makeDeclaration(node);
47164702
4717 wip_members.nextDecl(decl_inst);4703 wip_decls.nextDecl(decl_inst);
4718 astgen.advanceSourceCursorToNode(node);4704 astgen.advanceSourceCursorToNode(node);
47194705
4720 // This is just needed for the `setDeclaration` call.4706 // This is just needed for the `setDeclaration` call.
...@@ -4914,7 +4900,7 @@ fn structDeclInner(...@@ -4914,7 +4900,7 @@ fn structDeclInner(
4914 node: Ast.Node.Index,4900 node: Ast.Node.Index,
4915 container_decl: Ast.full.ContainerDecl,4901 container_decl: Ast.full.ContainerDecl,
4916 layout: std.builtin.Type.ContainerLayout,4902 layout: std.builtin.Type.ContainerLayout,
4917 backing_int_node: Ast.Node.OptionalIndex,4903 maybe_backing_int_node: Ast.Node.OptionalIndex,
4918 name_strat: Zir.Inst.NameStrategy,4904 name_strat: Zir.Inst.NameStrategy,
4919) InnerError!Zir.Inst.Ref {4905) InnerError!Zir.Inst.Ref {
4920 const astgen = gz.astgen;4906 const astgen = gz.astgen;
...@@ -4930,27 +4916,29 @@ fn structDeclInner(...@@ -4930,27 +4916,29 @@ fn structDeclInner(
4930 if (node == .root) {4916 if (node == .root) {
4931 return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{});4917 return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{});
4932 } else {4918 } 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);
4934 }4920 }
4935 }4921 }
49364922
4923 astgen.advanceSourceCursorToNode(node);
4924
4937 const decl_inst = try gz.reserveInstructionIndex();4925 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) {
4940 try gz.setStruct(decl_inst, .{4928 try gz.setStruct(decl_inst, .{
4941 .src_node = node,4929 .src_node = node,
4930 .name_strat = name_strat,
4942 .layout = layout,4931 .layout = layout,
4943 .captures_len = 0,4932 .backing_int_type_body_len = null,
4944 .fields_len = 0,
4945 .decls_len = 0,4933 .decls_len = 0,
4946 .has_backing_int = false,4934 .fields_len = 0,
4947 .known_non_opv = false,4935 .any_field_aligns = false,
4948 .known_comptime_only = false,4936 .any_field_defaults = false,
4949 .any_comptime_fields = false,4937 .any_comptime_fields = false,
4950 .any_default_inits = false,4938 .fields_hash = @splat(0),
4951 .any_aligned_fields = false,4939 .captures = &.{},
4952 .fields_hash = std.zig.hashSrc(@tagName(layout)),4940 .capture_names = &.{},
4953 .name_strat = name_strat,4941 .remaining = &.{},
4954 });4942 });
4955 return decl_inst.toRef();4943 return decl_inst.toRef();
4956 }4944 }
...@@ -4967,7 +4955,6 @@ fn structDeclInner(...@@ -4967,7 +4955,6 @@ fn structDeclInner(
4967 // The struct_decl instruction introduces a scope in which the decls of the struct4955 // The struct_decl instruction introduces a scope in which the decls of the struct
4968 // are in scope, so that field types, alignments, and default value expressions4956 // are in scope, so that field types, alignments, and default value expressions
4969 // can refer to decls within the struct itself.4957 // can refer to decls within the struct itself.
4970 astgen.advanceSourceCursorToNode(node);
4971 var block_scope: GenZir = .{4958 var block_scope: GenZir = .{
4972 .parent = &namespace.base,4959 .parent = &namespace.base,
4973 .decl_node_index = node,4960 .decl_node_index = node,
...@@ -4979,197 +4966,134 @@ fn structDeclInner(...@@ -4979,197 +4966,134 @@ fn structDeclInner(
4979 };4966 };
4980 defer block_scope.unstack();4967 defer block_scope.unstack();
49814968
4982 const scratch_top = astgen.scratch.items.len;4969 const scan_result = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"struct");
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 };
50104970
5011 const decl_count = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"struct");4971 var scratch: Scratch = .init(astgen);
5012 const field_count: u32 = @intCast(container_decl.ast.members.len - decl_count);4972 defer scratch.reset();
50134973
5014 const bits_per_field = 4;4974 // Replicate the structure of the ZIR trailing data in `scratch`
5015 const max_field_size = 5;4975 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
5016 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);4976 const field_names = try scratch.addSlice(scan_result.fields_len);
5017 defer wip_members.deinit();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:4986 // Before any field bodies comes the backing int type, if specified.
5020 // bodies: { // for every fields_len4987 const backing_int_type_body_len: ?u32 = if (maybe_backing_int_node.unwrap()) |backing_int_node| len: {
5021 // field_type_body_inst: Inst, // for each field_type_body_len4988 if (layout != .@"packed") return astgen.failNode(
5022 // align_body_inst: Inst, // for each align_body_len4989 backing_int_node,
5023 // init_body_inst: Inst, // for each init_body_len4990 "non-packed struct does not support backing integer type",
5024 // }4991 .{},
5025 // Note that the scratch buffer is simultaneously being used by WipMembers, however4992 );
5026 // it will not access any elements beyond this point in the ArrayList. It also4993 const type_ref = try typeExpr(&block_scope, &namespace.base, backing_int_node);
5027 // accesses via the ArrayList items field so it can handle the scratch buffer being4994 if (!block_scope.endsWithNoReturn()) {
5028 // reallocated.4995 _ = try block_scope.addBreak(.break_inline, decl_inst, type_ref);
5029 // No defer needed here because it is handled by `wip_members.deinit()` above.4996 }
5030 const bodies_start = astgen.scratch.items.len;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
5032 const old_hasher = astgen.src_hasher;5002 const old_hasher = astgen.src_hasher;
5033 defer astgen.src_hasher = old_hasher;5003 defer astgen.src_hasher = old_hasher;
5034 astgen.src_hasher = std.zig.SrcHasher.init(.{});5004 astgen.src_hasher = .init(.{});
5035 astgen.src_hasher.update(@tagName(layout));
5036 if (backing_int_node.unwrap()) |arg| {
5037 astgen.src_hasher.update(tree.getNodeSource(arg));
5038 }
50395005
5040 var known_non_opv = false;5006 var next_field_idx: u32 = 0;
5041 var known_comptime_only = false;
5042 var any_comptime_fields = false;
5043 var any_aligned_fields = false;
5044 var any_default_inits = false;
5045 for (container_decl.ast.members) |member_node| {5007 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)) {
5047 .decl => continue,5009 .decl => continue,
5048 .field => |field| field,5010 .field => |field| field,
5049 };5011 };
5012 const field_idx = next_field_idx;
5013 next_field_idx += 1;
50505014
5051 astgen.src_hasher.update(tree.getNodeSource(member_node));5015 astgen.src_hasher.update(tree.getNodeSource(member_node));
50525016
5053 const field_name = try astgen.identAsString(member.ast.main_token);
5054 member.convertToNonTupleLike(astgen.tree);5017 member.convertToNonTupleLike(astgen.tree);
5055 assert(!member.ast.tuple_like);5018 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);5020 field_names.get(astgen)[field_idx] = @intFromEnum(try astgen.identAsString(member.ast.main_token));
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;
50675021
5068 if (is_comptime) {5022 {
5069 switch (layout) {5023 const type_node = member.ast.type_expr.unwrap() orelse {
5070 .@"packed", .@"extern" => return astgen.failTok(member.comptime_token.?, "{s} struct fields cannot be marked comptime", .{@tagName(layout)}),5024 return astgen.failTok(member.ast.main_token, "struct field missing type", .{});
5071 .auto => any_comptime_fields = true,5025 };
5072 }5026 const type_ref = try typeExpr(&block_scope, &namespace.base, type_node);
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) {
5082 if (!block_scope.endsWithNoReturn()) {5027 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);
5084 }5029 }
5085 const body = block_scope.instructionsSlice();5030 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5086 const old_scratch_len = astgen.scratch.items.len;5031 field_type_body_lens.get(astgen)[field_idx] = body_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));
5090 block_scope.instructions.items.len = block_scope.instructions_top;5032 block_scope.instructions.items.len = block_scope.instructions_top;
5091 } else {
5092 wip_members.appendToField(@intFromEnum(field_type));
5093 }5033 }
50945034
5095 if (member.ast.align_expr.unwrap()) |align_expr| {5035 if (member.ast.align_expr.unwrap()) |align_node| {
5096 if (layout == .@"packed") {5036 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", .{});
5098 }5038 }
5099 any_aligned_fields = true;5039 const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_node);
5100 const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_expr);
5101 if (!block_scope.endsWithNoReturn()) {5040 if (!block_scope.endsWithNoReturn()) {
5102 _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref);5041 _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref);
5103 }5042 }
5104 const body = block_scope.instructionsSlice();5043 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5105 const old_scratch_len = astgen.scratch.items.len;5044 field_align_body_lens.?.get(astgen)[field_idx] = body_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));
5109 block_scope.instructions.items.len = block_scope.instructions_top;5045 block_scope.instructions.items.len = block_scope.instructions_top;
5046 } else if (field_align_body_lens) |lens| {
5047 lens.get(astgen)[field_idx] = 0;
5110 }5048 }
51115049
5112 if (member.ast.value_expr.unwrap()) |value_expr| {5050 if (member.ast.value_expr.unwrap()) |default_node| {
5113 any_default_inits = true;5051 const ri: ResultInfo = .{ .rl = .{ .coerced_ty = decl_inst.toRef() } };
51145052 const default_ref = try expr(&block_scope, &namespace.base, ri, default_node);
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);
5120 if (!block_scope.endsWithNoReturn()) {5053 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);
5122 }5055 }
5123 const body = block_scope.instructionsSlice();5056 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5124 const old_scratch_len = astgen.scratch.items.len;5057 field_default_body_lens.?.get(astgen)[field_idx] = body_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));
5128 block_scope.instructions.items.len = block_scope.instructions_top;5058 block_scope.instructions.items.len = block_scope.instructions_top;
5129 } else if (member.comptime_token) |comptime_token| {5059 } else if (field_default_body_lens) |lens| {
5130 return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});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;
5131 }5073 }
5132 }5074 }
5075 assert(next_field_idx == scan_result.fields_len);
5076 wip_decls.finish();
51335077
5134 var fields_hash: std.zig.SrcHash = undefined;5078 var fields_hash: std.zig.SrcHash = undefined;
5135 astgen.src_hasher.final(&fields_hash);5079 astgen.src_hasher.final(&fields_hash);
51365080
5137 try gz.setStruct(decl_inst, .{5081 try gz.setStruct(decl_inst, .{
5138 .src_node = node,5082 .src_node = node,
5083 .name_strat = name_strat,
5139 .layout = layout,5084 .layout = layout,
5140 .captures_len = @intCast(namespace.captures.count()),5085 .backing_int_type_body_len = backing_int_type_body_len,
5141 .fields_len = field_count,5086 .decls_len = scan_result.decls_len,
5142 .decls_len = decl_count,5087 .fields_len = scan_result.fields_len,
5143 .has_backing_int = backing_int_ref != .none,5088 .any_field_aligns = scan_result.any_field_aligns,
5144 .known_non_opv = known_non_opv,5089 .any_field_defaults = scan_result.any_field_values,
5145 .known_comptime_only = known_comptime_only,5090 .any_comptime_fields = scan_result.any_comptime_fields,
5146 .any_comptime_fields = any_comptime_fields,
5147 .any_default_inits = any_default_inits,
5148 .any_aligned_fields = any_aligned_fields,
5149 .fields_hash = fields_hash,5091 .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),
5151 });5095 });
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
5173 block_scope.unstack();5097 block_scope.unstack();
5174 return decl_inst.toRef();5098 return decl_inst.toRef();
5175}5099}
...@@ -5281,11 +5205,29 @@ fn unionDeclInner(...@@ -5281,11 +5205,29 @@ fn unionDeclInner(
5281 auto_enum_tok: ?Ast.TokenIndex,5205 auto_enum_tok: ?Ast.TokenIndex,
5282 name_strat: Zir.Inst.NameStrategy,5206 name_strat: Zir.Inst.NameStrategy,
5283) InnerError!Zir.Inst.Ref {5207) InnerError!Zir.Inst.Ref {
5284 const decl_inst = try gz.reserveInstructionIndex();
5285
5286 const astgen = gz.astgen;5208 const astgen = gz.astgen;
5287 const gpa = astgen.gpa;5209 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
5289 var namespace: Scope.Namespace = .{5231 var namespace: Scope.Namespace = .{
5290 .parent = scope,5232 .parent = scope,
5291 .node = node,5233 .node = node,
...@@ -5298,7 +5240,6 @@ fn unionDeclInner(...@@ -5298,7 +5240,6 @@ fn unionDeclInner(
5298 // The union_decl instruction introduces a scope in which the decls of the union5240 // The union_decl instruction introduces a scope in which the decls of the union
5299 // are in scope, so that field types, alignments, and default value expressions5241 // are in scope, so that field types, alignments, and default value expressions
5300 // can refer to decls within the union itself.5242 // can refer to decls within the union itself.
5301 astgen.advanceSourceCursorToNode(node);
5302 var block_scope: GenZir = .{5243 var block_scope: GenZir = .{
5303 .parent = &namespace.base,5244 .parent = &namespace.base,
5304 .decl_node_index = node,5245 .decl_node_index = node,
...@@ -5310,42 +5251,42 @@ fn unionDeclInner(...@@ -5310,42 +5251,42 @@ fn unionDeclInner(
5310 };5251 };
5311 defer block_scope.unstack();5252 defer block_scope.unstack();
53125253
5313 const decl_count = try astgen.scanContainer(&namespace, members, .@"union");5254 const scan_result = try astgen.scanContainer(&namespace, members, .@"union");
5314 const field_count: u32 = @intCast(members.len - decl_count);
53155255
5316 if (layout != .auto and (auto_enum_tok != null or opt_arg_node != .none)) {5256 var scratch: Scratch = .init(astgen);
5317 if (opt_arg_node.unwrap()) |arg_node| {5257 defer scratch.reset();
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 }
53235258
5324 const arg_inst: Zir.Inst.Ref = if (opt_arg_node.unwrap()) |arg_node|5259 // Replicate the structure of the ZIR trailing data in `scratch`
5325 try typeExpr(&block_scope, &namespace.base, arg_node)5260 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
5326 else5261 const field_names = try scratch.addSlice(scan_result.fields_len);
5327 .none;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;5266 // Before any field bodies comes the tag/backing type, if specified.
5330 const max_field_size = 4;5267 const arg_type_body_len: ?u32 = if (opt_arg_node.unwrap()) |arg_node| len: {
5331 var any_aligned_fields = false;5268 const type_ref = try typeExpr(&block_scope, &namespace.base, arg_node);
5332 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);5269 if (!block_scope.endsWithNoReturn()) {
5333 defer wip_members.deinit();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
5335 const old_hasher = astgen.src_hasher;5277 const old_hasher = astgen.src_hasher;
5336 defer astgen.src_hasher = old_hasher;5278 defer astgen.src_hasher = old_hasher;
5337 astgen.src_hasher = std.zig.SrcHasher.init(.{});5279 astgen.src_hasher = .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 }
53435280
5281 var next_field_idx: u32 = 0;
5344 for (members) |member_node| {5282 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)) {
5346 .decl => continue,5284 .decl => continue,
5347 .field => |field| field,5285 .field => |field| field,
5348 };5286 };
5287 const field_idx = next_field_idx;
5288 next_field_idx += 1;
5289
5349 astgen.src_hasher.update(astgen.tree.getNodeSource(member_node));5290 astgen.src_hasher.update(astgen.tree.getNodeSource(member_node));
5350 member.convertToNonTupleLike(astgen.tree);5291 member.convertToNonTupleLike(astgen.tree);
5351 if (member.ast.tuple_like) {5292 if (member.ast.tuple_like) {
...@@ -5355,97 +5296,91 @@ fn unionDeclInner(...@@ -5355,97 +5296,91 @@ fn unionDeclInner(
5355 return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{});5296 return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{});
5356 }5297 }
53575298
5358 const field_name = try astgen.identAsString(member.ast.main_token);5299 field_names.get(astgen)[field_idx] = @intFromEnum(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 });
53665300
5367 if (member.ast.type_expr.unwrap()) |type_expr| {5301 if (member.ast.type_expr.unwrap()) |type_node| {
5368 const field_type = try typeExpr(&block_scope, &namespace.base, type_expr);5302 const type_ref = try typeExpr(&block_scope, &namespace.base, type_node);
5369 wip_members.appendToField(@intFromEnum(field_type));5303 if (!block_scope.endsWithNoReturn()) {
5370 } else if (arg_inst == .none and auto_enum_tok == null) {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) {
5371 return astgen.failNode(member_node, "union field missing type", .{});5310 return astgen.failNode(member_node, "union field missing type", .{});
5311 } else {
5312 field_type_body_lens.get(astgen)[field_idx] = 0;
5372 }5313 }
5373 if (member.ast.align_expr.unwrap()) |align_expr| {5314
5315 if (member.ast.align_expr.unwrap()) |align_node| {
5374 if (layout == .@"packed") {5316 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", .{});
5376 }5318 }
5377 const align_inst = try expr(&block_scope, &block_scope.base, coerced_align_ri, align_expr);5319 const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_node);
5378 wip_members.appendToField(@intFromEnum(align_inst));5320 if (!block_scope.endsWithNoReturn()) {
5379 any_aligned_fields = true;5321 _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref);
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 );
5395 }5322 }
5396 if (auto_enum_tok == null) {5323 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5397 return astgen.failNodeNotes(5324 field_align_body_lens.?.get(astgen)[field_idx] = body_len;
5398 node,5325 block_scope.instructions.items.len = block_scope.instructions_top;
5399 "explicitly valued tagged union requires inferred enum tag type",5326 } else if (field_align_body_lens) |lens| {
5400 .{},5327 lens.get(astgen)[field_idx] = 0;
5401 &[_]u32{5328 }
5402 try astgen.errNoteNode(5329
5403 value_expr,5330 if (member.ast.value_expr.unwrap()) |value_node| {
5404 "tag value specified here",5331 if (!explicit_int_or_enum_tag) return astgen.failNodeNotes(
5405 .{},5332 node,
5406 ),5333 "explicitly valued tagged union missing integer tag type",
5407 },5334 .{},
5408 );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);
5409 }5347 }
5410 const tag_value = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = arg_inst } }, value_expr);5348 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5411 wip_members.appendToField(@intFromEnum(tag_value));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;
5412 }5353 }
5413 }5354 }
5355 assert(next_field_idx == scan_result.fields_len);
5356 wip_decls.finish();
54145357
5415 var fields_hash: std.zig.SrcHash = undefined;5358 var fields_hash: std.zig.SrcHash = undefined;
5416 astgen.src_hasher.final(&fields_hash);5359 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
5425 try gz.setUnion(decl_inst, .{5361 try gz.setUnion(decl_inst, .{
5426 .src_node = node,5362 .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,
5436 .name_strat = name_strat,5363 .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),
5437 });5382 });
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
5449 block_scope.unstack();5384 block_scope.unstack();
5450 return decl_inst.toRef();5385 return decl_inst.toRef();
5451}5386}
...@@ -5494,103 +5429,8 @@ fn containerDecl(...@@ -5494,103 +5429,8 @@ fn containerDecl(
5494 if (container_decl.layout_token) |t| {5429 if (container_decl.layout_token) |t| {
5495 return astgen.failTok(t, "enums do not support 'packed' or 'extern'; instead provide an explicit integer tag type", .{});5430 return astgen.failTok(t, "enums do not support 'packed' or 'extern'; instead provide an explicit integer tag type", .{});
5496 }5431 }
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;5433 astgen.advanceSourceCursorToNode(node);
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;
55945434
5595 const decl_inst = try gz.reserveInstructionIndex();5435 const decl_inst = try gz.reserveInstructionIndex();
55965436
...@@ -5605,7 +5445,6 @@ fn containerDecl(...@@ -5605,7 +5445,6 @@ fn containerDecl(
56055445
5606 // The enum_decl instruction introduces a scope in which the decls of the enum5446 // The enum_decl instruction introduces a scope in which the decls of the enum
5607 // are in scope, so that tag values can refer to decls within the enum itself.5447 // are in scope, so that tag values can refer to decls within the enum itself.
5608 astgen.advanceSourceCursorToNode(node);
5609 var block_scope: GenZir = .{5448 var block_scope: GenZir = .{
5610 .parent = &namespace.base,5449 .parent = &namespace.base,
5611 .decl_node_index = node,5450 .decl_node_index = node,
...@@ -5617,104 +5456,127 @@ fn containerDecl(...@@ -5617,104 +5456,127 @@ fn containerDecl(
5617 };5456 };
5618 defer block_scope.unstack();5457 defer block_scope.unstack();
56195458
5620 _ = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum");5459 const scan_result = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum");
5621 namespace.base.tag = .namespace;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|5463 var scratch: Scratch = .init(astgen);
5624 try comptimeExpr(&block_scope, &namespace.base, coerced_type_ri, arg, .type)5464 defer scratch.reset();
5625 else
5626 .none;
56275465
5628 const bits_per_field = 1;5466 // Replicate the structure of the ZIR trailing data in `scratch`
5629 const max_field_size = 2;5467 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
5630 var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(counts.decls), @intCast(counts.total_fields), bits_per_field, max_field_size);5468 const field_names = try scratch.addSlice(fields_len);
5631 defer wip_members.deinit();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
5633 const old_hasher = astgen.src_hasher;5482 const old_hasher = astgen.src_hasher;
5634 defer astgen.src_hasher = old_hasher;5483 defer astgen.src_hasher = old_hasher;
5635 astgen.src_hasher = std.zig.SrcHasher.init(.{});5484 astgen.src_hasher = .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)});
56405485
5486 var next_field_idx: u32 = 0;
5487 var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none;
5641 for (container_decl.ast.members) |member_node| {5488 for (container_decl.ast.members) |member_node| {
5642 if (member_node.toOptional() == counts.nonexhaustive_node)5489 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_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)) {
5646 .decl => continue,5490 .decl => continue,
5647 .field => |field| field,5491 .field => |field| field,
5648 };5492 };
5649 member.convertToNonTupleLike(astgen.tree);5493 member.convertToNonTupleLike(astgen.tree);
5650 assert(member.comptime_token == null);5494 if (member.ast.tuple_like) return astgen.failTok(member.ast.main_token, "enum field missing name", .{});
5651 assert(member.ast.type_expr == .none);5495 if (member.comptime_token) |t| return astgen.failTok(t, "enum fields cannot be marked comptime", .{});
5652 assert(member.ast.align_expr == .none);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);5525 // This is a real field rather than a non-exhaustive mark.
5655 wip_members.appendToField(@intFromEnum(field_name));5526 const field_idx = next_field_idx;
5527 next_field_idx += 1;
56565528
5657 const have_value = member.ast.value_expr != .none;5529 astgen.src_hasher.update(tree.getNodeSource(member_node));
5658 wip_members.nextField(bits_per_field, .{have_value});
56595530
5660 if (member.ast.value_expr.unwrap()) |value_expr| {5531 field_names.get(astgen)[field_idx] = @intFromEnum(try astgen.identAsString(member.ast.main_token));
5661 if (arg_inst == .none) {5532
5662 return astgen.failNodeNotes(5533 if (member.ast.value_expr.unwrap()) |value_node| {
5663 node,5534 if (tag_type_body_len == null) {
5664 "explicitly valued enum missing integer tag type",5535 return astgen.failNodeNotes(node, "explicitly valued enum missing integer tag type", .{}, &.{
5665 .{},5536 try astgen.errNoteNode(value_node, "tag value specified here", .{}),
5666 &[_]u32{5537 });
5667 try astgen.errNoteNode(5538 }
5668 value_expr,5539 const val_ri: ResultInfo = .{ .rl = .{ .coerced_ty = decl_inst.toRef() } };
5669 "tag value specified here",5540 const value_ref = try expr(&block_scope, &namespace.base, val_ri, value_node);
5670 .{},5541 if (!block_scope.endsWithNoReturn()) {
5671 ),5542 _ = try block_scope.addBreak(.break_inline, decl_inst, value_ref);
5672 },
5673 );
5674 }5543 }
5675 const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .rl = .{ .ty = arg_inst } }, value_expr);5544 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5676 wip_members.appendToField(@intFromEnum(tag_value_inst));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;
5677 }5549 }
5678 }5550 }
56795551 assert(scan_result.has_underscore_field == (opt_nonexhaustive_node != .none));
5680 if (!block_scope.isEmpty()) {5552 assert(next_field_idx == fields_len);
5681 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);5553 wip_decls.finish();
5682 }
56835554
5684 var fields_hash: std.zig.SrcHash = undefined;5555 var fields_hash: std.zig.SrcHash = undefined;
5685 astgen.src_hasher.final(&fields_hash);5556 astgen.src_hasher.final(&fields_hash);
56865557
5687 const body = block_scope.instructionsSlice();
5688 const body_len = astgen.countBodyLenAfterFixups(body);
5689
5690 try gz.setEnum(decl_inst, .{5558 try gz.setEnum(decl_inst, .{
5691 .src_node = node,5559 .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,
5699 .name_strat = name_strat,5560 .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),
5700 });5570 });
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
5712 block_scope.unstack();5572 block_scope.unstack();
5713 return rvalue(gz, ri, decl_inst.toRef(), node);5573 return rvalue(gz, ri, decl_inst.toRef(), node);
5714 },5574 },
5715 .keyword_opaque => {5575 .keyword_opaque => {
5716 assert(container_decl.ast.arg == .none);5576 assert(container_decl.ast.arg == .none);
57175577
5578 astgen.advanceSourceCursorToNode(node);
5579
5718 const decl_inst = try gz.reserveInstructionIndex();5580 const decl_inst = try gz.reserveInstructionIndex();
57195581
5720 var namespace: Scope.Namespace = .{5582 var namespace: Scope.Namespace = .{
...@@ -5726,7 +5588,6 @@ fn containerDecl(...@@ -5726,7 +5588,6 @@ fn containerDecl(
5726 };5588 };
5727 defer namespace.deinit(gpa);5589 defer namespace.deinit(gpa);
57285590
5729 astgen.advanceSourceCursorToNode(node);
5730 var block_scope: GenZir = .{5591 var block_scope: GenZir = .{
5731 .parent = &namespace.base,5592 .parent = &namespace.base,
5732 .decl_node_index = node,5593 .decl_node_index = node,
...@@ -5738,36 +5599,34 @@ fn containerDecl(...@@ -5738,36 +5599,34 @@ fn containerDecl(
5738 };5599 };
5739 defer block_scope.unstack();5600 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);5604 var scratch: Scratch = .init(astgen);
5744 defer wip_members.deinit();5605 defer scratch.reset();
5606 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
57455607
5746 if (container_decl.layout_token) |layout_token| {5608 if (container_decl.layout_token) |layout_token| {
5747 return astgen.failTok(layout_token, "opaque types do not support 'packed' or 'extern'", .{});5609 return astgen.failTok(layout_token, "opaque types do not support 'packed' or 'extern'", .{});
5748 }5610 }
57495611
5750 for (container_decl.ast.members) |member_node| {5612 for (container_decl.ast.members) |member_node| {
5751 const res = try containerMember(&block_scope, &namespace.base, &wip_members, member_node);5613 switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
5752 if (res == .field) {5614 .decl => {},
5753 return astgen.failNode(member_node, "opaque types cannot have fields", .{});5615 .field => return astgen.failNode(member_node, "opaque types cannot have fields", .{}),
5754 }5616 }
5755 }5617 }
57565618
5619 wip_decls.finish();
5620
5757 try gz.setOpaque(decl_inst, .{5621 try gz.setOpaque(decl_inst, .{
5758 .src_node = node,5622 .src_node = node,
5759 .captures_len = @intCast(namespace.captures.count()),
5760 .decls_len = decl_count,
5761 .name_strat = name_strat,5623 .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)),
5762 });5628 });
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
5771 block_scope.unstack();5630 block_scope.unstack();
5772 return rvalue(gz, ri, decl_inst.toRef(), node);5631 return rvalue(gz, ri, decl_inst.toRef(), node);
5773 },5632 },
...@@ -5780,7 +5639,7 @@ const ContainerMemberResult = union(enum) { decl, field: Ast.full.ContainerField...@@ -5780,7 +5639,7 @@ const ContainerMemberResult = union(enum) { decl, field: Ast.full.ContainerField
5780fn containerMember(5639fn containerMember(
5781 gz: *GenZir,5640 gz: *GenZir,
5782 scope: *Scope,5641 scope: *Scope,
5783 wip_members: *WipMembers,5642 wip_decls: *WipDecls,
5784 member_node: Ast.Node.Index,5643 member_node: Ast.Node.Index,
5785) InnerError!ContainerMemberResult {5644) InnerError!ContainerMemberResult {
5786 const astgen = gz.astgen;5645 const astgen = gz.astgen;
...@@ -5805,13 +5664,13 @@ fn containerMember(...@@ -5805,13 +5664,13 @@ fn containerMember(
5805 else5664 else
5806 .none;5665 .none;
58075666
5808 const prev_decl_index = wip_members.decl_index;5667 const prev_decl_index = wip_decls.index;
5809 astgen.fnDecl(gz, scope, wip_members, member_node, body, full) catch |err| switch (err) {5668 astgen.fnDecl(gz, scope, wip_decls, member_node, body, full) catch |err| switch (err) {
5810 error.OutOfMemory => return error.OutOfMemory,5669 error.OutOfMemory => return error.OutOfMemory,
5811 error.AnalysisFail => {5670 error.AnalysisFail => {
5812 wip_members.decl_index = prev_decl_index;5671 wip_decls.index = prev_decl_index;
5813 try addFailedDeclaration(5672 try addFailedDeclaration(
5814 wip_members,5673 wip_decls,
5815 gz,5674 gz,
5816 .@"const",5675 .@"const",
5817 try astgen.identAsString(full.name_token.?),5676 try astgen.identAsString(full.name_token.?),
...@@ -5828,13 +5687,13 @@ fn containerMember(...@@ -5828,13 +5687,13 @@ fn containerMember(
5828 .aligned_var_decl,5687 .aligned_var_decl,
5829 => {5688 => {
5830 const full = tree.fullVarDecl(member_node).?;5689 const full = tree.fullVarDecl(member_node).?;
5831 const prev_decl_index = wip_members.decl_index;5690 const prev_decl_index = wip_decls.index;
5832 astgen.globalVarDecl(gz, scope, wip_members, member_node, full) catch |err| switch (err) {5691 astgen.globalVarDecl(gz, scope, wip_decls, member_node, full) catch |err| switch (err) {
5833 error.OutOfMemory => return error.OutOfMemory,5692 error.OutOfMemory => return error.OutOfMemory,
5834 error.AnalysisFail => {5693 error.AnalysisFail => {
5835 wip_members.decl_index = prev_decl_index;5694 wip_decls.index = prev_decl_index;
5836 try addFailedDeclaration(5695 try addFailedDeclaration(
5837 wip_members,5696 wip_decls,
5838 gz,5697 gz,
5839 .@"const", // doesn't really matter5698 .@"const", // doesn't really matter
5840 try astgen.identAsString(full.ast.mut_token + 1),5699 try astgen.identAsString(full.ast.mut_token + 1),
...@@ -5846,13 +5705,13 @@ fn containerMember(...@@ -5846,13 +5705,13 @@ fn containerMember(
5846 },5705 },
58475706
5848 .@"comptime" => {5707 .@"comptime" => {
5849 const prev_decl_index = wip_members.decl_index;5708 const prev_decl_index = wip_decls.index;
5850 astgen.comptimeDecl(gz, scope, wip_members, member_node) catch |err| switch (err) {5709 astgen.comptimeDecl(gz, scope, wip_decls, member_node) catch |err| switch (err) {
5851 error.OutOfMemory => return error.OutOfMemory,5710 error.OutOfMemory => return error.OutOfMemory,
5852 error.AnalysisFail => {5711 error.AnalysisFail => {
5853 wip_members.decl_index = prev_decl_index;5712 wip_decls.index = prev_decl_index;
5854 try addFailedDeclaration(5713 try addFailedDeclaration(
5855 wip_members,5714 wip_decls,
5856 gz,5715 gz,
5857 .@"comptime",5716 .@"comptime",
5858 .empty,5717 .empty,
...@@ -5863,16 +5722,16 @@ fn containerMember(...@@ -5863,16 +5722,16 @@ fn containerMember(
5863 };5722 };
5864 },5723 },
5865 .test_decl => {5724 .test_decl => {
5866 const prev_decl_index = wip_members.decl_index;5725 const prev_decl_index = wip_decls.index;
5867 // We need to have *some* decl here so that the decl count matches what's expected.5726 // We need to have *some* decl here so that the decl count matches what's expected.
5868 // Since it doesn't strictly matter *what* this is, let's save ourselves the trouble5727 // Since it doesn't strictly matter *what* this is, let's save ourselves the trouble
5869 // of duplicating the test name logic, and just assume this is an unnamed test.5728 // 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) {
5871 error.OutOfMemory => return error.OutOfMemory,5730 error.OutOfMemory => return error.OutOfMemory,
5872 error.AnalysisFail => {5731 error.AnalysisFail => {
5873 wip_members.decl_index = prev_decl_index;5732 wip_decls.index = prev_decl_index;
5874 try addFailedDeclaration(5733 try addFailedDeclaration(
5875 wip_members,5734 wip_decls,
5876 gz,5735 gz,
5877 .unnamed_test,5736 .unnamed_test,
5878 .empty,5737 .empty,
...@@ -10619,482 +10478,6 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev...@@ -10619,482 +10478,6 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev
10619 }10478 }
10620}10479}
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
11098/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of10481/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
11099/// result locations must call this function on their result.10482/// result locations must call this function on their result.
11100/// As an example, if `ri.rl` is `.ptr`, it will write the result to the pointer.10483/// As an example, if `ri.rl` is `.ptr`, it will write the result to the pointer.
...@@ -13044,18 +12427,19 @@ const GenZir = struct {...@@ -13044,18 +12427,19 @@ const GenZir = struct {
1304412427
13045 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {12428 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
13046 src_node: Ast.Node.Index,12429 src_node: Ast.Node.Index,
13047 captures_len: u32,12430 name_strat: Zir.Inst.NameStrategy,
13048 fields_len: u32,
13049 decls_len: u32,
13050 has_backing_int: bool,
13051 layout: std.builtin.Type.ContainerLayout,12431 layout: std.builtin.Type.ContainerLayout,
13052 known_non_opv: bool,12432 backing_int_type_body_len: ?u32,
13053 known_comptime_only: bool,12433 decls_len: u32,
12434 fields_len: u32,
12435 any_field_aligns: bool,
12436 any_field_defaults: bool,
13054 any_comptime_fields: bool,12437 any_comptime_fields: bool,
13055 any_default_inits: bool,
13056 any_aligned_fields: bool,
13057 fields_hash: std.zig.SrcHash,12438 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,
13059 }) !void {12443 }) !void {
13060 const astgen = gz.astgen;12444 const astgen = gz.astgen;
13061 const gpa = astgen.gpa;12445 const gpa = astgen.gpa;
...@@ -13063,9 +12447,16 @@ const GenZir = struct {...@@ -13063,9 +12447,16 @@ const GenZir = struct {
13063 // Node .root is valid for the root `struct_decl` of a file!12447 // Node .root is valid for the root `struct_decl` of a file!
13064 assert(args.src_node != .root or gz.parent.tag == .top);12448 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
13066 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);12453 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
13069 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.StructDecl{12460 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.StructDecl{
13070 .fields_hash_0 = fields_hash_arr[0],12461 .fields_hash_0 = fields_hash_arr[0],
13071 .fields_hash_1 = fields_hash_arr[1],12462 .fields_hash_1 = fields_hash_arr[1],
...@@ -13075,31 +12466,28 @@ const GenZir = struct {...@@ -13075,31 +12466,28 @@ const GenZir = struct {
13075 .src_node = args.src_node,12466 .src_node = args.src_node,
13076 });12467 });
1307712468
13078 if (args.captures_len != 0) {12469 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
13079 astgen.extra.appendAssumeCapacity(args.captures_len);12470 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
13080 }12471 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
13081 if (args.fields_len != 0) {12472 if (args.backing_int_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
13082 astgen.extra.appendAssumeCapacity(args.fields_len);12473 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
13083 }12474 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
13084 if (args.decls_len != 0) {12475 astgen.extra.appendSliceAssumeCapacity(args.remaining);
13085 astgen.extra.appendAssumeCapacity(args.decls_len);12476
13086 }
13087 astgen.instructions.set(@intFromEnum(inst), .{12477 astgen.instructions.set(@intFromEnum(inst), .{
13088 .tag = .extended,12478 .tag = .extended,
13089 .data = .{ .extended = .{12479 .data = .{ .extended = .{
13090 .opcode = .struct_decl,12480 .opcode = .struct_decl,
13091 .small = @bitCast(Zir.Inst.StructDecl.Small{12481 .small = @bitCast(Zir.Inst.StructDecl.Small{
13092 .has_captures_len = args.captures_len != 0,12482 .has_captures_len = captures_len != 0,
13093 .has_fields_len = args.fields_len != 0,
13094 .has_decls_len = args.decls_len != 0,12483 .has_decls_len = args.decls_len != 0,
13095 .has_backing_int = args.has_backing_int,12484 .has_fields_len = args.fields_len != 0,
13096 .known_non_opv = args.known_non_opv,
13097 .known_comptime_only = args.known_comptime_only,
13098 .name_strategy = args.name_strat,12485 .name_strategy = args.name_strat,
13099 .layout = args.layout,12486 .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,
13100 .any_comptime_fields = args.any_comptime_fields,12490 .any_comptime_fields = args.any_comptime_fields,
13101 .any_default_inits = args.any_default_inits,
13102 .any_aligned_fields = args.any_aligned_fields,
13103 }),12491 }),
13104 .operand = payload_index,12492 .operand = payload_index,
13105 } },12493 } },
...@@ -13108,25 +12496,34 @@ const GenZir = struct {...@@ -13108,25 +12496,34 @@ const GenZir = struct {
1310812496
13109 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {12497 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
13110 src_node: Ast.Node.Index,12498 src_node: Ast.Node.Index,
13111 tag_type: Zir.Inst.Ref,12499 name_strat: Zir.Inst.NameStrategy,
13112 captures_len: u32,12500 kind: Zir.Inst.UnionDecl.Kind,
13113 body_len: u32,12501 arg_type_body_len: ?u32,
13114 fields_len: u32,
13115 decls_len: u32,12502 decls_len: u32,
13116 layout: std.builtin.Type.ContainerLayout,12503 fields_len: u32,
13117 auto_enum_tag: bool,12504 any_field_aligns: bool,
13118 any_aligned_fields: bool,12505 any_field_values: bool,
13119 fields_hash: std.zig.SrcHash,12506 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,
13121 }) !void {12511 }) !void {
13122 const astgen = gz.astgen;12512 const astgen = gz.astgen;
13123 const gpa = astgen.gpa;12513 const gpa = astgen.gpa;
1312412514
13125 assert(args.src_node != .root);12515 assert(args.src_node != .root);
1312612516
12517 const captures_len: u32 = @intCast(args.captures.len);
12518 assert(args.capture_names.len == captures_len);
12519
13127 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);12520 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
13130 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.UnionDecl{12527 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.UnionDecl{
13131 .fields_hash_0 = fields_hash_arr[0],12528 .fields_hash_0 = fields_hash_arr[0],
13132 .fields_hash_1 = fields_hash_arr[1],12529 .fields_hash_1 = fields_hash_arr[1],
...@@ -13136,35 +12533,30 @@ const GenZir = struct {...@@ -13136,35 +12533,30 @@ const GenZir = struct {
13136 .src_node = args.src_node,12533 .src_node = args.src_node,
13137 });12534 });
1313812535
13139 if (args.tag_type != .none) {12536 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
13140 astgen.extra.appendAssumeCapacity(@intFromEnum(args.tag_type));12537 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
13141 }12538 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
13142 if (args.captures_len != 0) {12539 if (args.kind.hasArgType()) {
13143 astgen.extra.appendAssumeCapacity(args.captures_len);12540 astgen.extra.appendAssumeCapacity(args.arg_type_body_len.?);
13144 }12541 } else {
13145 if (args.body_len != 0) {12542 assert(args.arg_type_body_len == null);
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);
13153 }12543 }
12544 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12545 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
12546 astgen.extra.appendSliceAssumeCapacity(args.remaining);
12547
13154 astgen.instructions.set(@intFromEnum(inst), .{12548 astgen.instructions.set(@intFromEnum(inst), .{
13155 .tag = .extended,12549 .tag = .extended,
13156 .data = .{ .extended = .{12550 .data = .{ .extended = .{
13157 .opcode = .union_decl,12551 .opcode = .union_decl,
13158 .small = @bitCast(Zir.Inst.UnionDecl.Small{12552 .small = @bitCast(Zir.Inst.UnionDecl.Small{
13159 .has_tag_type = args.tag_type != .none,12553 .has_captures_len = captures_len != 0,
13160 .has_captures_len = args.captures_len != 0,
13161 .has_body_len = args.body_len != 0,
13162 .has_fields_len = args.fields_len != 0,
13163 .has_decls_len = args.decls_len != 0,12554 .has_decls_len = args.decls_len != 0,
12555 .has_fields_len = args.fields_len != 0,
13164 .name_strategy = args.name_strat,12556 .name_strategy = args.name_strat,
13165 .layout = args.layout,12557 .kind = args.kind,
13166 .auto_enum_tag = args.auto_enum_tag,12558 .any_field_aligns = args.any_field_aligns,
13167 .any_aligned_fields = args.any_aligned_fields,12559 .any_field_values = args.any_field_values,
13168 }),12560 }),
13169 .operand = payload_index,12561 .operand = payload_index,
13170 } },12562 } },
...@@ -13173,23 +12565,33 @@ const GenZir = struct {...@@ -13173,23 +12565,33 @@ const GenZir = struct {
1317312565
13174 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {12566 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
13175 src_node: Ast.Node.Index,12567 src_node: Ast.Node.Index,
13176 tag_type: Zir.Inst.Ref,12568 name_strat: Zir.Inst.NameStrategy,
13177 captures_len: u32,12569 tag_type_body_len: ?u32,
13178 body_len: u32,
13179 fields_len: u32,
13180 decls_len: u32,
13181 nonexhaustive: bool,12570 nonexhaustive: bool,
12571 decls_len: u32,
12572 fields_len: u32,
12573 any_field_values: bool,
13182 fields_hash: std.zig.SrcHash,12574 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,
13184 }) !void {12579 }) !void {
13185 const astgen = gz.astgen;12580 const astgen = gz.astgen;
13186 const gpa = astgen.gpa;12581 const gpa = astgen.gpa;
1318712582
13188 assert(args.src_node != .root);12583 assert(args.src_node != .root);
1318912584
12585 const captures_len: u32 = @intCast(args.captures.len);
12586 assert(args.capture_names.len == captures_len);
12587
13190 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);12588 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
13193 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.EnumDecl{12595 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.EnumDecl{
13194 .fields_hash_0 = fields_hash_arr[0],12596 .fields_hash_0 = fields_hash_arr[0],
13195 .fields_hash_1 = fields_hash_arr[1],12597 .fields_hash_1 = fields_hash_arr[1],
...@@ -13199,33 +12601,26 @@ const GenZir = struct {...@@ -13199,33 +12601,26 @@ const GenZir = struct {
13199 .src_node = args.src_node,12601 .src_node = args.src_node,
13200 });12602 });
1320112603
13202 if (args.tag_type != .none) {12604 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
13203 astgen.extra.appendAssumeCapacity(@intFromEnum(args.tag_type));12605 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
13204 }12606 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
13205 if (args.captures_len != 0) {12607 if (args.tag_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
13206 astgen.extra.appendAssumeCapacity(args.captures_len);12608 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
13207 }12609 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
13208 if (args.body_len != 0) {12610 astgen.extra.appendSliceAssumeCapacity(args.remaining);
13209 astgen.extra.appendAssumeCapacity(args.body_len);12611
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 }
13217 astgen.instructions.set(@intFromEnum(inst), .{12612 astgen.instructions.set(@intFromEnum(inst), .{
13218 .tag = .extended,12613 .tag = .extended,
13219 .data = .{ .extended = .{12614 .data = .{ .extended = .{
13220 .opcode = .enum_decl,12615 .opcode = .enum_decl,
13221 .small = @bitCast(Zir.Inst.EnumDecl.Small{12616 .small = @bitCast(Zir.Inst.EnumDecl.Small{
13222 .has_tag_type = args.tag_type != .none,12617 .has_captures_len = captures_len != 0,
13223 .has_captures_len = args.captures_len != 0,
13224 .has_body_len = args.body_len != 0,
13225 .has_fields_len = args.fields_len != 0,
13226 .has_decls_len = args.decls_len != 0,12618 .has_decls_len = args.decls_len != 0,
12619 .has_fields_len = args.fields_len != 0,
13227 .name_strategy = args.name_strat,12620 .name_strategy = args.name_strat,
12621 .has_tag_type = args.tag_type_body_len != null,
13228 .nonexhaustive = args.nonexhaustive,12622 .nonexhaustive = args.nonexhaustive,
12623 .any_field_values = args.any_field_values,
13229 }),12624 }),
13230 .operand = payload_index,12625 .operand = payload_index,
13231 } },12626 } },
...@@ -13234,33 +12629,41 @@ const GenZir = struct {...@@ -13234,33 +12629,41 @@ const GenZir = struct {
1323412629
13235 fn setOpaque(gz: *GenZir, inst: Zir.Inst.Index, args: struct {12630 fn setOpaque(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
13236 src_node: Ast.Node.Index,12631 src_node: Ast.Node.Index,
13237 captures_len: u32,
13238 decls_len: u32,
13239 name_strat: Zir.Inst.NameStrategy,12632 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,
13240 }) !void {12637 }) !void {
13241 const astgen = gz.astgen;12638 const astgen = gz.astgen;
13242 const gpa = astgen.gpa;12639 const gpa = astgen.gpa;
1324312640
13244 assert(args.src_node != .root);12641 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
13247 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{12651 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{
13248 .src_line = astgen.source_line,12652 .src_line = astgen.source_line,
13249 .src_node = args.src_node,12653 .src_node = args.src_node,
13250 });12654 });
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 }
13258 astgen.instructions.set(@intFromEnum(inst), .{12661 astgen.instructions.set(@intFromEnum(inst), .{
13259 .tag = .extended,12662 .tag = .extended,
13260 .data = .{ .extended = .{12663 .data = .{ .extended = .{
13261 .opcode = .opaque_decl,12664 .opcode = .opaque_decl,
13262 .small = @bitCast(Zir.Inst.OpaqueDecl.Small{12665 .small = @bitCast(Zir.Inst.OpaqueDecl.Small{
13263 .has_captures_len = args.captures_len != 0,12666 .has_captures_len = captures_len != 0,
13264 .has_decls_len = args.decls_len != 0,12667 .has_decls_len = args.decls_len != 0,
13265 .name_strategy = args.name_strat,12668 .name_strategy = args.name_strat,
13266 }),12669 }),
...@@ -13484,14 +12887,24 @@ fn restoreSourceCursor(astgen: *AstGen, cursor: SourceCursor) void {...@@ -13484,14 +12887,24 @@ fn restoreSourceCursor(astgen: *AstGen, cursor: SourceCursor) void {
13484 astgen.source_column = cursor.column;12887 astgen.source_column = cursor.column;
13485}12888}
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
13487/// Detects name conflicts for decls and fields, and populates `namespace.decls` with all named declarations.12901/// 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).
13489fn scanContainer(12902fn scanContainer(
13490 astgen: *AstGen,12903 astgen: *AstGen,
13491 namespace: *Scope.Namespace,12904 namespace: *Scope.Namespace,
13492 members: []const Ast.Node.Index,12905 members: []const Ast.Node.Index,
13493 container_kind: enum { @"struct", @"union", @"enum", @"opaque" },12906 container_kind: enum { @"struct", @"union", @"enum", @"opaque" },
13494) !u32 {12907) !ScanContainerResult {
13495 const gpa = astgen.gpa;12908 const gpa = astgen.gpa;
13496 const tree = astgen.tree;12909 const tree = astgen.tree;
1349712910
...@@ -13521,6 +12934,10 @@ fn scanContainer(...@@ -13521,6 +12934,10 @@ fn scanContainer(
1352112934
13522 var any_duplicates = false;12935 var any_duplicates = false;
13523 var decl_count: u32 = 0;12936 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;
13524 for (members) |member_node| {12941 for (members) |member_node| {
13525 const Kind = enum { decl, field };12942 const Kind = enum { decl, field };
13526 const kind: Kind, const name_token = switch (tree.nodeTag(member_node)) {12943 const kind: Kind, const name_token = switch (tree.nodeTag(member_node)) {
...@@ -13533,6 +12950,10 @@ fn scanContainer(...@@ -13533,6 +12950,10 @@ fn scanContainer(
13533 .@"struct", .@"opaque" => {},12950 .@"struct", .@"opaque" => {},
13534 .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree),12951 .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree),
13535 }12952 }
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;
13536 if (full.ast.tuple_like) continue;12957 if (full.ast.tuple_like) continue;
13537 break :blk .{ .field, full.ast.main_token };12958 break :blk .{ .field, full.ast.main_token };
13538 },12959 },
...@@ -13698,7 +13119,14 @@ fn scanContainer(...@@ -13698,7 +13119,14 @@ fn scanContainer(
1369813119
13699 if (!any_duplicates) {13120 if (!any_duplicates) {
13700 if (any_invalid_declarations) return error.AnalysisFail;13121 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 };
13702 }13130 }
1370313131
13704 for (names.keys(), names.values()) |name, first| {13132 for (names.keys(), names.values()) |name, first| {
...@@ -13954,7 +13382,7 @@ const DeclarationName = union(enum) {...@@ -13954,7 +13382,7 @@ const DeclarationName = union(enum) {
13954};13382};
1395513383
13956fn addFailedDeclaration(13384fn addFailedDeclaration(
13957 wip_members: *WipMembers,13385 wip_decls: *WipDecls,
13958 gz: *GenZir,13386 gz: *GenZir,
13959 kind: Zir.Inst.Declaration.Unwrapped.Kind,13387 kind: Zir.Inst.Declaration.Unwrapped.Kind,
13960 name: Zir.NullTerminatedString,13388 name: Zir.NullTerminatedString,
...@@ -13962,7 +13390,7 @@ fn addFailedDeclaration(...@@ -13962,7 +13390,7 @@ fn addFailedDeclaration(
13962 is_pub: bool,13390 is_pub: bool,
13963) !void {13391) !void {
13964 const decl_inst = try gz.makeDeclaration(src_node);13392 const decl_inst = try gz.makeDeclaration(src_node);
13965 wip_members.nextDecl(decl_inst);13393 wip_decls.nextDecl(decl_inst);
1396613394
13967 var dummy_gz = gz.makeSubBlock(&gz.base);13395 var dummy_gz = gz.makeSubBlock(&gz.base);
1396813396
lib/std/zig/ErrorBundle.zig+10-6
...@@ -243,12 +243,14 @@ fn renderErrorMessage(...@@ -243,12 +243,14 @@ fn renderErrorMessage(
243 }243 }
244 try t.setColor(.reset);244 try t.setColor(.reset);
245 if (src.data.source_line != 0 and options.include_source_line) {245 if (src.data.source_line != 0 and options.include_source_line) {
246 try w.splatByteAll(' ', indent);
246 const line = eb.nullTerminatedString(src.data.source_line);247 const line = eb.nullTerminatedString(src.data.source_line);
247 for (line) |b| switch (b) {248 for (line) |b| switch (b) {
248 '\t' => try w.writeByte(' '),249 '\t' => try w.writeByte(' '),
249 else => try w.writeByte(b),250 else => try w.writeByte(b),
250 };251 };
251 try w.writeByte('\n');252 try w.writeByte('\n');
253 try w.splatByteAll(' ', indent);
252 // TODO basic unicode code point monospace width254 // TODO basic unicode code point monospace width
253 const before_caret = src.data.span_main - src.data.span_start;255 const before_caret = src.data.span_main - src.data.span_start;
254 // -1 since span.main includes the caret256 // -1 since span.main includes the caret
...@@ -267,11 +269,13 @@ fn renderErrorMessage(...@@ -267,11 +269,13 @@ fn renderErrorMessage(
267 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {269 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
268 try t.setColor(.reset);270 try t.setColor(.reset);
269 try t.setColor(.dim);271 try t.setColor(.dim);
272 try w.splatByteAll(' ', indent);
270 try w.print("referenced by:\n", .{});273 try w.print("referenced by:\n", .{});
271 var ref_index = src.end;274 var ref_index = src.end;
272 for (0..src.data.reference_trace_len) |_| {275 for (0..src.data.reference_trace_len) |_| {
273 const ref_trace = eb.extraData(ReferenceTrace, ref_index);276 const ref_trace = eb.extraData(ReferenceTrace, ref_index);
274 ref_index = ref_trace.end;277 ref_index = ref_trace.end;
278 try w.splatByteAll(' ', indent);
275 if (ref_trace.data.src_loc != .none) {279 if (ref_trace.data.src_loc != .none) {
276 const ref_src = eb.getSourceLocation(ref_trace.data.src_loc);280 const ref_src = eb.getSourceLocation(ref_trace.data.src_loc);
277 try w.print(" {s}: {s}:{d}:{d}\n", .{281 try w.print(" {s}: {s}:{d}:{d}\n", .{
...@@ -340,9 +344,9 @@ pub const Wip = struct {...@@ -340,9 +344,9 @@ pub const Wip = struct {
340 pub fn init(wip: *Wip, gpa: Allocator) !void {344 pub fn init(wip: *Wip, gpa: Allocator) !void {
341 wip.* = .{345 wip.* = .{
342 .gpa = gpa,346 .gpa = gpa,
343 .string_bytes = .{},347 .string_bytes = .empty,
344 .extra = .{},348 .extra = .empty,
345 .root_list = .{},349 .root_list = .empty,
346 };350 };
347351
348 // So that 0 can be used to indicate a null string.352 // So that 0 can be used to indicate a null string.
...@@ -371,9 +375,9 @@ pub const Wip = struct {...@@ -371,9 +375,9 @@ pub const Wip = struct {
371 wip.deinit();375 wip.deinit();
372 wip.* = .{376 wip.* = .{
373 .gpa = gpa,377 .gpa = gpa,
374 .string_bytes = .{},378 .string_bytes = .empty,
375 .extra = .{},379 .extra = .empty,
376 .root_list = .{},380 .root_list = .empty,
377 };381 };
378 return empty;382 return empty;
379 }383 }
lib/std/zig/Zir.zig+564-386
...@@ -2443,7 +2443,7 @@ pub const Inst = struct {...@@ -2443,7 +2443,7 @@ pub const Inst = struct {
2443 has_align: bool,2443 has_align: bool,
2444 has_addrspace: bool,2444 has_addrspace: bool,
2445 has_bit_range: bool,2445 has_bit_range: bool,
2446 _: u1 = undefined,2446 _: u1 = 0,
2447 },2447 },
2448 size: std.builtin.Type.Pointer.Size,2448 size: std.builtin.Type.Pointer.Size,
2449 /// Index into extra. See `PtrType`.2449 /// Index into extra. See `PtrType`.
...@@ -2668,7 +2668,7 @@ pub const Inst = struct {...@@ -2668,7 +2668,7 @@ pub const Inst = struct {
2668 has_ret_ty_body: bool,2668 has_ret_ty_body: bool,
2669 has_any_noalias: bool,2669 has_any_noalias: bool,
2670 ret_ty_is_generic: bool,2670 ret_ty_is_generic: bool,
2671 _: u23 = undefined,2671 _: u23 = 0,
2672 };2672 };
2673 };2673 };
26742674
...@@ -3134,7 +3134,7 @@ pub const Inst = struct {...@@ -3134,7 +3134,7 @@ pub const Inst = struct {
3134 pub const Flags = packed struct {3134 pub const Flags = packed struct {
3135 is_nosuspend: bool,3135 is_nosuspend: bool,
3136 ensure_result_used: bool,3136 ensure_result_used: bool,
3137 _: u30 = undefined,3137 _: u30 = 0,
31383138
3139 comptime {3139 comptime {
3140 if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32)3140 if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32)
...@@ -3462,33 +3462,21 @@ pub const Inst = struct {...@@ -3462,33 +3462,21 @@ pub const Inst = struct {
3462 };3462 };
34633463
3464 /// Trailing:3464 /// Trailing:
3465 /// 0. captures_len: u32 // if has_captures_len3465 /// 0. captures_len: u32 // if `has_captures_len`
3466 /// 1. fields_len: u32, // if has_fields_len3466 /// 1. decls_len: u32, // if `has_decls_len`
3467 /// 2. decls_len: u32, // if has_decls_len3467 /// 2. fields_len: u32, // if `has_fields_len`
3468 /// 3. capture: Capture // for every captures_len3468 /// 3. backing_int_body_len: u32 // if `has_backing_int`
3469 /// 4. capture_name: NullTerminatedString // for every captures_len3469 /// 4. capture: Capture // for every `captures_len`
3470 /// 5. backing_int_body_len: u32, // if has_backing_int3470 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3471 /// 6. backing_int_ref: Ref, // if has_backing_int and backing_int_body_len is 03471 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3472 /// 7. backing_int_body_inst: Inst, // if has_backing_int and backing_int_body_len is > 03472 /// 7. field_name: NullTerminatedString // for every `fields_len`
3473 /// 8. decl: Index, // for every decls_len; points to a `declaration` instruction3473 /// 8. field_type_body_len: u32 // for every `fields_len`
3474 /// 9. flags: u32 // for every 8 fields3474 /// 9. field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`
3475 /// - sets of 4 bits:3475 /// 10. field_default_body_len: u32 // for every `fields_len` if `any_field_defaults`
3476 /// 0b000X: whether corresponding field has an align expression3476 /// 11. field_comptime_bits: u32 // one bit per `fields_len` if `any_comptime_fields`
3477 /// 0b00X0: whether corresponding field has a default expression3477 /// // LSB is first field, minimum number of `u32` needed
3478 /// 0b0X00: whether corresponding field is comptime3478 /// 12. backing_int_body_inst: Inst.Index // for each `backing_int_body_len`
3479 /// 0bX000: whether corresponding field has a type expression3479 /// 13. body_inst: Inst.Index // type body, then align body, then default body, for each field
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 /// }
3492 pub const StructDecl = struct {3480 pub const StructDecl = struct {
3493 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.3481 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
3494 // This hash contains the source of all fields, and any specified attributes (`extern`, backing type, etc).3482 // This hash contains the source of all fields, and any specified attributes (`extern`, backing type, etc).
...@@ -3500,19 +3488,18 @@ pub const Inst = struct {...@@ -3500,19 +3488,18 @@ pub const Inst = struct {
3500 /// This node provides a new absolute baseline node for all instructions within this struct.3488 /// This node provides a new absolute baseline node for all instructions within this struct.
3501 src_node: Ast.Node.Index,3489 src_node: Ast.Node.Index,
35023490
3503 pub const Small = packed struct {3491 pub const Small = packed struct(u16) {
3504 has_captures_len: bool,3492 has_captures_len: bool,
3505 has_fields_len: bool,
3506 has_decls_len: bool,3493 has_decls_len: bool,
3507 has_backing_int: bool,3494 has_fields_len: bool,
3508 known_non_opv: bool,
3509 known_comptime_only: bool,
3510 name_strategy: NameStrategy,3495 name_strategy: NameStrategy,
3511 layout: std.builtin.Type.ContainerLayout,3496 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,
3513 any_comptime_fields: bool,3501 any_comptime_fields: bool,
3514 any_aligned_fields: bool,3502 _: u5 = 0,
3515 _: u3 = undefined,
3516 };3503 };
3517 };3504 };
35183505
...@@ -3633,21 +3620,17 @@ pub const Inst = struct {...@@ -3633,21 +3620,17 @@ pub const Inst = struct {
3633 };3620 };
36343621
3635 /// Trailing:3622 /// Trailing:
3636 /// 0. tag_type: Ref, // if has_tag_type3623 /// 0. captures_len: u32, // if has_captures_len
3637 /// 1. captures_len: u32, // if has_captures_len3624 /// 1. decls_len: u32, // if has_decls_len
3638 /// 2. body_len: u32, // if has_body_len3625 /// 2. fields_len: u32, // if has_fields_len
3639 /// 3. fields_len: u32, // if has_fields_len3626 /// 3. tag_type_body_len: u32, // if has_tag_type
3640 /// 4. decls_len: u32, // if has_decls_len3627 /// 4. capture: Capture // for every `captures_len`
3641 /// 5. capture: Capture // for every captures_len3628 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3642 /// 6. capture_name: NullTerminatedString // for every captures_len3629 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3643 /// 7. decl: Index, // for every decls_len; points to a `declaration` instruction3630 /// 7. field_name: NullTerminatedString // for every `fields_len`
3644 /// 8. inst: Index // for every body_len3631 /// 8. field_value_body_len: u32 // for every `fields_len` if `any_field_values`
3645 /// 9. has_bits: u32 // for every 32 fields3632 /// 9. tag_type_body_inst: Inst.Index // for each `tag_type_body_len`
3646 /// - the bit is whether corresponding field has an value expression3633 /// 10. body_inst: Inst.Index // value body for each field
3647 /// 10. fields: { // for every fields_len
3648 /// field_name: u32,
3649 /// value: Ref, // if corresponding bit is set
3650 /// }
3651 pub const EnumDecl = struct {3634 pub const EnumDecl = struct {
3652 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.3635 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
3653 // This hash contains the source of all fields, and the backing type if specified.3636 // This hash contains the source of all fields, and the backing type if specified.
...@@ -3659,40 +3642,32 @@ pub const Inst = struct {...@@ -3659,40 +3642,32 @@ pub const Inst = struct {
3659 /// This node provides a new absolute baseline node for all instructions within this struct.3642 /// This node provides a new absolute baseline node for all instructions within this struct.
3660 src_node: Ast.Node.Index,3643 src_node: Ast.Node.Index,
36613644
3662 pub const Small = packed struct {3645 pub const Small = packed struct(u16) {
3663 has_tag_type: bool,
3664 has_captures_len: bool,3646 has_captures_len: bool,
3665 has_body_len: bool,
3666 has_fields_len: bool,
3667 has_decls_len: bool,3647 has_decls_len: bool,
3648 has_fields_len: bool,
3668 name_strategy: NameStrategy,3649 name_strategy: NameStrategy,
3650 has_tag_type: bool,
3669 nonexhaustive: bool,3651 nonexhaustive: bool,
3670 _: u8 = undefined,3652 any_field_values: bool,
3653 _: u8 = 0,
3671 };3654 };
3672 };3655 };
36733656
3674 /// Trailing:3657 /// Trailing:
3675 /// 0. tag_type: Ref, // if has_tag_type3658 /// 0. captures_len: u32 // if `has_captures_len`
3676 /// 1. captures_len: u32 // if has_captures_len3659 /// 1. decls_len: u32, // if `has_decls_len`
3677 /// 2. body_len: u32, // if has_body_len3660 /// 2. fields_len: u32, // if `has_fields_len`
3678 /// 3. fields_len: u32, // if has_fields_len3661 /// 3. arg_type_body_len: u32, // if `kind.hasArgType()`
3679 /// 4. decls_len: u32, // if has_decls_len3662 /// 4. capture: Capture // for every `captures_len`
3680 /// 5. capture: Capture // for every captures_len3663 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3681 /// 6. capture_name: NullTerminatedString // for every captures_len3664 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3682 /// 7. decl: Index, // for every decls_len; points to a `declaration` instruction3665 /// 7. field_name: NullTerminatedString // for every `fields_len`
3683 /// 8. inst: Index // for every body_len3666 /// 8. field_type_body_len: u32 // for every `fields_len`
3684 /// 9. has_bits: u32 // for every 8 fields3667 /// 9 . field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`
3685 /// - sets of 4 bits:3668 /// 10. field_value_body_len: u32 // for every `fields_len` if `any_field_values`
3686 /// 0b000X: whether corresponding field has a type expression3669 /// 11. arg_type_body_inst: Inst.Index // for each `arg_type_body_len`
3687 /// 0b00X0: whether corresponding field has a align expression3670 /// 12. body_inst: Inst.Index // type body, then align body, then value body, for each field
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 /// }
3696 pub const UnionDecl = struct {3671 pub const UnionDecl = struct {
3697 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.3672 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
3698 // This hash contains the source of all fields, and any specified attributes (`extern` etc).3673 // This hash contains the source of all fields, and any specified attributes (`extern` etc).
...@@ -3704,23 +3679,47 @@ pub const Inst = struct {...@@ -3704,23 +3679,47 @@ pub const Inst = struct {
3704 /// This node provides a new absolute baseline node for all instructions within this struct.3679 /// This node provides a new absolute baseline node for all instructions within this struct.
3705 src_node: Ast.Node.Index,3680 src_node: Ast.Node.Index,
37063681
3707 pub const Small = packed struct {3682 pub const Small = packed struct(u16) {
3708 has_tag_type: bool,
3709 has_captures_len: bool,3683 has_captures_len: bool,
3710 has_body_len: bool,
3711 has_fields_len: bool,
3712 has_decls_len: bool,3684 has_decls_len: bool,
3685 has_fields_len: bool,
3713 name_strategy: NameStrategy,3686 name_strategy: NameStrategy,
3714 layout: std.builtin.Type.ContainerLayout,3687 kind: Kind,
3715 /// has_tag_type | auto_enum_tag | result3688 any_field_aligns: bool,
3716 /// -------------------------------------3689 any_field_values: bool,
3717 /// false | false | union { }3690 _: u6 = 0,
3718 /// false | true | union(enum) { }3691 };
3719 /// true | true | union(enum(T)) { }3692
3720 /// true | false | union(T) { }3693 pub const Kind = enum(u3) {
3721 auto_enum_tag: bool,3694 /// `union`
3722 any_aligned_fields: bool,3695 auto,
3723 _: u5 = undefined,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 }
3724 };3723 };
3725 };3724 };
37263725
...@@ -3735,11 +3734,11 @@ pub const Inst = struct {...@@ -3735,11 +3734,11 @@ pub const Inst = struct {
3735 /// This node provides a new absolute baseline node for all instructions within this struct.3734 /// This node provides a new absolute baseline node for all instructions within this struct.
3736 src_node: Ast.Node.Index,3735 src_node: Ast.Node.Index,
37373736
3738 pub const Small = packed struct {3737 pub const Small = packed struct(u16) {
3739 has_captures_len: bool,3738 has_captures_len: bool,
3740 has_decls_len: bool,3739 has_decls_len: bool,
3741 name_strategy: NameStrategy,3740 name_strategy: NameStrategy,
3742 _: u12 = undefined,3741 _: u12 = 0,
3743 };3742 };
3744 };3743 };
37453744
...@@ -3904,12 +3903,12 @@ pub const Inst = struct {...@@ -3904,12 +3903,12 @@ pub const Inst = struct {
3904 pub const AllocExtended = struct {3903 pub const AllocExtended = struct {
3905 src_node: Ast.Node.Offset,3904 src_node: Ast.Node.Offset,
39063905
3907 pub const Small = packed struct {3906 pub const Small = packed struct(u16) {
3908 has_type: bool,3907 has_type: bool,
3909 has_align: bool,3908 has_align: bool,
3910 is_const: bool,3909 is_const: bool,
3911 is_comptime: bool,3910 is_comptime: bool,
3912 _: u12 = undefined,3911 _: u12 = 0,
3913 };3912 };
3914 };3913 };
39153914
...@@ -4012,135 +4011,6 @@ pub const Inst = struct {...@@ -4012,135 +4011,6 @@ pub const Inst = struct {
4012 };4011 };
4013};4012};
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
4144/// `DeclContents` contains all "interesting" instructions found within a declaration by `findTrackable`.4014/// `DeclContents` contains all "interesting" instructions found within a declaration by `findTrackable`.
4145/// These instructions are partitioned into a few different sets, since this makes ZIR instruction mapping4015/// These instructions are partitioned into a few different sets, since this makes ZIR instruction mapping
4146/// more effective.4016/// more effective.
...@@ -4524,7 +4394,7 @@ fn findTrackableInner(...@@ -4524,7 +4394,7 @@ fn findTrackableInner(
4524 try zir.findTrackableBody(gpa, contents, defers, body);4394 try zir.findTrackableBody(gpa, contents, defers, body);
4525 },4395 },
45264396
4527 // Reifications and opaque declarations need tracking, but have no body.4397 // Reifications and opaque declarations need tracking, but have no bodies.
4528 .reify_enum,4398 .reify_enum,
4529 .reify_struct,4399 .reify_struct,
4530 .reify_union,4400 .reify_union,
...@@ -4535,150 +4405,37 @@ fn findTrackableInner(...@@ -4535,150 +4405,37 @@ fn findTrackableInner(
4535 .struct_decl => {4405 .struct_decl => {
4536 try contents.explicit_types.append(gpa, inst);4406 try contents.explicit_types.append(gpa, inst);
45374407
4538 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);4408 const struct_decl = zir.getStructDecl(inst);
4539 const extra = zir.extraData(Zir.Inst.StructDecl, extended.operand);4409 var it = struct_decl.iterateFields();
4540 var extra_index = extra.end;4410 while (it.next()) |field| {
4541 const captures_len = if (small.has_captures_len) blk: {4411 try zir.findTrackableBody(gpa, contents, defers, field.type_body);
4542 const captures_len = zir.extra[extra_index];4412 if (field.align_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4543 extra_index += 1;4413 if (field.default_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
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 }
4567 }4414 }
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);
4622 },4415 },
46234416
4624 // Union declarations need tracking and have a body.4417 // Union declarations need tracking and have bodies.
4625 .union_decl => {4418 .union_decl => {
4626 try contents.explicit_types.append(gpa, inst);4419 try contents.explicit_types.append(gpa, inst);
46274420
4628 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);4421 const union_decl = zir.getUnionDecl(inst);
4629 const extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand);4422 var it = union_decl.iterateFields();
4630 var extra_index = extra.end;4423 while (it.next()) |field| {
4631 extra_index += @intFromBool(small.has_tag_type);4424 if (field.type_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4632 const captures_len = if (small.has_captures_len) blk: {4425 if (field.align_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4633 const captures_len = zir.extra[extra_index];4426 if (field.value_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4634 extra_index += 1;4427 }
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);
4652 },4428 },
46534429
4654 // Enum declarations need tracking and have a body.4430 // Enum declarations need tracking and have bodies.
4655 .enum_decl => {4431 .enum_decl => {
4656 try contents.explicit_types.append(gpa, inst);4432 try contents.explicit_types.append(gpa, inst);
46574433
4658 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);4434 const enum_decl = zir.getEnumDecl(inst);
4659 const extra = zir.extraData(Zir.Inst.EnumDecl, extended.operand);4435 var it = enum_decl.iterateFields();
4660 var extra_index = extra.end;4436 while (it.next()) |field| {
4661 extra_index += @intFromBool(small.has_tag_type);4437 if (field.value_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4662 const captures_len = if (small.has_captures_len) blk: {4438 }
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);
4682 },4439 },
4683 }4440 }
4684 },4441 },
...@@ -5481,34 +5238,455 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {...@@ -5481,34 +5238,455 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
5481 }5238 }
5482}5239}
54835240
5484pub fn typeCapturesLen(zir: Zir, type_decl: Inst.Index) u32 {5241pub fn typeDecls(zir: Zir, type_decl: Inst.Index) []const Zir.Inst.Index {
5485 const inst = zir.instructions.get(@intFromEnum(type_decl));5242 const inst = zir.instructions.get(@intFromEnum(type_decl));
5486 assert(inst.tag == .extended);5243 assert(inst.tag == .extended);
5487 switch (inst.data.extended.opcode) {5244 return switch (inst.data.extended.opcode) {
5488 .struct_decl => {5245 .struct_decl => zir.getStructDecl(type_decl).decls,
5489 const small: Inst.StructDecl.Small = @bitCast(inst.data.extended.small);5246 .union_decl => zir.getUnionDecl(type_decl).decls,
5490 if (!small.has_captures_len) return 0;5247 .enum_decl => zir.getEnumDecl(type_decl).decls,
5491 const extra = zir.extraData(Inst.StructDecl, inst.data.extended.operand);5248 .opaque_decl => zir.getOpaqueDecl(type_decl).decls,
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 },
5512 else => unreachable,5249 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 };
5513 }5359 }
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 };
5514}5472}
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 {...@@ -34,8 +34,8 @@ pub const Block = struct {
3434
35 const default: Info = .{35 const default: Info = .{
36 .block_name = &.{},36 .block_name = &.{},
37 .record_names = .{},37 .record_names = .empty,
38 .abbrevs = .{ .abbrevs = .{} },38 .abbrevs = .{ .abbrevs = .empty },
39 };39 };
4040
41 const set_bid_id: u32 = 1;41 const set_bid_id: u32 = 1;
...@@ -109,8 +109,8 @@ pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader {...@@ -109,8 +109,8 @@ pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader {
109 .keep_names = options.keep_names,109 .keep_names = options.keep_names,
110 .bit_buffer = 0,110 .bit_buffer = 0,
111 .bit_offset = 0,111 .bit_offset = 0,
112 .stack = .{},112 .stack = .empty,
113 .block_info = .{},113 .block_info = .empty,
114 };114 };
115}115}
116116
...@@ -278,7 +278,7 @@ fn startBlock(bc: *BitcodeReader, block_id: ?u32, new_abbrev_len: u6) !void {...@@ -278,7 +278,7 @@ fn startBlock(bc: *BitcodeReader, block_id: ?u32, new_abbrev_len: u6) !void {
278 state.* = .{278 state.* = .{
279 .block_id = block_id,279 .block_id = block_id,
280 .abbrev_id_width = new_abbrev_len,280 .abbrev_id_width = new_abbrev_len,
281 .abbrevs = .{ .abbrevs = .{} },281 .abbrevs = .{ .abbrevs = .empty },
282 };282 };
283 try state.abbrevs.abbrevs.ensureTotalCapacity(283 try state.abbrevs.abbrevs.ensureTotalCapacity(
284 bc.allocator,284 bc.allocator,
lib/std/zig/llvm/Builder.zig+238-126
...@@ -7,6 +7,7 @@ const Allocator = std.mem.Allocator;...@@ -7,6 +7,7 @@ const Allocator = std.mem.Allocator;
7const assert = std.debug.assert;7const assert = std.debug.assert;
8const DW = std.dwarf;8const DW = std.dwarf;
9const log = std.log.scoped(.llvm);9const log = std.log.scoped(.llvm);
10const maxInt = std.math.maxInt;
10const Writer = std.Io.Writer;11const Writer = std.Io.Writer;
1112
12const bitcode_writer = @import("bitcode_writer.zig");13const bitcode_writer = @import("bitcode_writer.zig");
...@@ -55,6 +56,8 @@ constant_items: std.MultiArrayList(Constant.Item),...@@ -55,6 +56,8 @@ constant_items: std.MultiArrayList(Constant.Item),
55constant_extra: std.ArrayList(u32),56constant_extra: std.ArrayList(u32),
56constant_limbs: std.ArrayList(std.math.big.Limb),57constant_limbs: std.ArrayList(std.math.big.Limb),
5758
59alignment_forward_references: std.ArrayList(Alignment),
60
58metadata_map: std.AutoArrayHashMapUnmanaged(void, void),61metadata_map: std.AutoArrayHashMapUnmanaged(void, void),
59metadata_items: std.MultiArrayList(Metadata.Item),62metadata_items: std.MultiArrayList(Metadata.Item),
60metadata_extra: std.ArrayList(u32),63metadata_extra: std.ArrayList(u32),
...@@ -85,7 +88,7 @@ pub const Options = struct {...@@ -85,7 +88,7 @@ pub const Options = struct {
85};88};
8689
87pub const String = enum(u32) {90pub const String = enum(u32) {
88 none = std.math.maxInt(u31),91 none = maxInt(u31),
89 empty,92 empty,
90 _,93 _,
9194
...@@ -245,7 +248,7 @@ pub const Type = enum(u32) {...@@ -245,7 +248,7 @@ pub const Type = enum(u32) {
245 ptr,248 ptr,
246 @"ptr addrspace(4)",249 @"ptr addrspace(4)",
247250
248 none = std.math.maxInt(u32),251 none = maxInt(u32),
249 _,252 _,
250253
251 pub const ptr_amdgpu_constant =254 pub const ptr_amdgpu_constant =
...@@ -941,7 +944,7 @@ pub const Attribute = union(Kind) {...@@ -941,7 +944,7 @@ pub const Attribute = union(Kind) {
941 inalloca: Type,944 inalloca: Type,
942 sret: Type,945 sret: Type,
943 elementtype: Type,946 elementtype: Type,
944 @"align": Alignment,947 @"align": Alignment.Lazy,
945 @"noalias",948 @"noalias",
946 nocapture,949 nocapture,
947 nofree,950 nofree,
...@@ -956,7 +959,7 @@ pub const Attribute = union(Kind) {...@@ -956,7 +959,7 @@ pub const Attribute = union(Kind) {
956 immarg,959 immarg,
957 noundef,960 noundef,
958 nofpclass: FpClass,961 nofpclass: FpClass,
959 alignstack: Alignment,962 alignstack: Alignment.Lazy,
960 allocalign,963 allocalign,
961 allocptr,964 allocptr,
962 readnone,965 readnone,
...@@ -964,7 +967,7 @@ pub const Attribute = union(Kind) {...@@ -964,7 +967,7 @@ pub const Attribute = union(Kind) {
964 writeonly,967 writeonly,
965968
966 // Function Attributes969 // Function Attributes
967 //alignstack: Alignment,970 //alignstack: Alignment.Lazy,
968 allockind: AllocKind,971 allockind: AllocKind,
969 allocsize: AllocSize,972 allocsize: AllocSize,
970 alwaysinline,973 alwaysinline,
...@@ -1145,7 +1148,7 @@ pub const Attribute = union(Kind) {...@@ -1145,7 +1148,7 @@ pub const Attribute = union(Kind) {
1145 return @unionInit(Attribute, field.name, switch (field.type) {1148 return @unionInit(Attribute, field.name, switch (field.type) {
1146 void => {},1149 void => {},
1147 u32 => storage.value,1150 u32 => storage.value,
1148 Alignment, String, Type, UwTable => @enumFromInt(storage.value),1151 Alignment.Lazy, String, Type, UwTable => @enumFromInt(storage.value),
1149 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value),1152 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value),
1150 else => @compileError("bad payload type: " ++ field.name ++ ": " ++1153 else => @compileError("bad payload type: " ++ field.name ++ ": " ++
1151 @typeName(field.type)),1154 @typeName(field.type)),
...@@ -1246,7 +1249,7 @@ pub const Attribute = union(Kind) {...@@ -1246,7 +1249,7 @@ pub const Attribute = union(Kind) {
1246 .sret,1249 .sret,
1247 .elementtype,1250 .elementtype,
1248 => |ty| try w.print(" {s}({f})", .{ @tagName(attribute), ty.fmt(data.builder, .percent) }),1251 => |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(" ")}),
1250 .dereferenceable,1253 .dereferenceable,
1251 .dereferenceable_or_null,1254 .dereferenceable_or_null,
1252 => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),1255 => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),
...@@ -1270,7 +1273,7 @@ pub const Attribute = union(Kind) {...@@ -1270,7 +1273,7 @@ pub const Attribute = union(Kind) {
1270 },1273 },
1271 .alignstack => |alignment| {1274 .alignstack => |alignment| {
1272 try w.print(" {t}", .{attribute});1275 try w.print(" {t}", .{attribute});
1273 const alignment_bytes = alignment.toByteUnits() orelse return;1276 const alignment_bytes = alignment.resolve(data.builder).toByteUnits() orelse return;
1274 if (data.flags.pound) {1277 if (data.flags.pound) {
1275 try w.print("={d}", .{alignment_bytes});1278 try w.print("={d}", .{alignment_bytes});
1276 } else {1279 } else {
...@@ -1435,8 +1438,8 @@ pub const Attribute = union(Kind) {...@@ -1435,8 +1438,8 @@ pub const Attribute = union(Kind) {
1435 //sanitize_memtag,1438 //sanitize_memtag,
1436 sanitize_address_dyninit = 102,1439 sanitize_address_dyninit = 102,
14371440
1438 string = std.math.maxInt(u31),1441 string = maxInt(u31),
1439 none = std.math.maxInt(u32),1442 none = maxInt(u32),
1440 _,1443 _,
14411444
1442 pub const len = @typeInfo(Kind).@"enum".fields.len - 2;1445 pub const len = @typeInfo(Kind).@"enum".fields.len - 2;
...@@ -1516,12 +1519,12 @@ pub const Attribute = union(Kind) {...@@ -1516,12 +1519,12 @@ pub const Attribute = union(Kind) {
1516 elem_size: u16,1519 elem_size: u16,
1517 num_elems: u16,1520 num_elems: u16,
15181521
1519 pub const none = std.math.maxInt(u16);1522 pub const none = maxInt(u16);
15201523
1521 fn toLlvm(self: AllocSize) packed struct(u64) { num_elems: u32, elem_size: u32 } {1524 fn toLlvm(self: AllocSize) packed struct(u64) { num_elems: u32, elem_size: u32 } {
1522 return .{ .num_elems = switch (self.num_elems) {1525 return .{ .num_elems = switch (self.num_elems) {
1523 else => self.num_elems,1526 else => self.num_elems,
1524 none => std.math.maxInt(u32),1527 none => maxInt(u32),
1525 }, .elem_size = self.elem_size };1528 }, .elem_size = self.elem_size };
1526 }1529 }
1527 };1530 };
...@@ -1577,7 +1580,7 @@ pub const Attribute = union(Kind) {...@@ -1577,7 +1580,7 @@ pub const Attribute = union(Kind) {
1577 inline else => |value, tag| .{ .kind = @as(Kind, self), .value = switch (@TypeOf(value)) {1580 inline else => |value, tag| .{ .kind = @as(Kind, self), .value = switch (@TypeOf(value)) {
1578 void => 0,1581 void => 0,
1579 u32 => value,1582 u32 => value,
1580 Alignment, String, Type, UwTable => @intFromEnum(value),1583 Alignment.Lazy, String, Type, UwTable => @intFromEnum(value),
1581 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value),1584 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value),
1582 else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))),1585 else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))),
1583 } },1586 } },
...@@ -1627,7 +1630,7 @@ pub const FunctionAttributes = enum(u32) {...@@ -1627,7 +1630,7 @@ pub const FunctionAttributes = enum(u32) {
1627 const params_index = 2;1630 const params_index = 2;
16281631
1629 pub const Wip = struct {1632 pub const Wip = struct {
1630 maps: Maps = .{},1633 maps: Maps = .empty,
16311634
1632 const Map = std.AutoArrayHashMapUnmanaged(Attribute.Kind, Attribute.Index);1635 const Map = std.AutoArrayHashMapUnmanaged(Attribute.Kind, Attribute.Index);
1633 const Maps = std.ArrayList(Map);1636 const Maps = std.ArrayList(Map);
...@@ -2017,9 +2020,32 @@ pub const ExternallyInitialized = enum {...@@ -2017,9 +2020,32 @@ pub const ExternallyInitialized = enum {
2017};2020};
20182021
2019pub const Alignment = enum(u6) {2022pub const Alignment = enum(u6) {
2020 default = std.math.maxInt(u6),2023 default = maxInt(u6),
2021 _,2024 _,
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
2023 pub fn fromByteUnits(bytes: u64) Alignment {2049 pub fn fromByteUnits(bytes: u64) Alignment {
2024 if (bytes == 0) return .default;2050 if (bytes == 0) return .default;
2025 assert(std.math.isPowerOfTwo(bytes));2051 assert(std.math.isPowerOfTwo(bytes));
...@@ -2028,11 +2054,17 @@ pub const Alignment = enum(u6) {...@@ -2028,11 +2054,17 @@ pub const Alignment = enum(u6) {
2028 }2054 }
20292055
2030 pub fn toByteUnits(self: Alignment) ?u64 {2056 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 };
2032 }2061 }
20332062
2034 pub fn toLlvm(self: Alignment) u6 {2063 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 };
2036 }2068 }
20372069
2038 pub const Prefixed = struct {2070 pub const Prefixed = struct {
...@@ -2180,7 +2212,7 @@ pub const CallConv = enum(u10) {...@@ -2180,7 +2212,7 @@ pub const CallConv = enum(u10) {
2180};2212};
21812213
2182pub const StrtabString = enum(u32) {2214pub const StrtabString = enum(u32) {
2183 none = std.math.maxInt(u31),2215 none = maxInt(u31),
2184 empty,2216 empty,
2185 _,2217 _,
21862218
...@@ -2308,7 +2340,7 @@ pub const Global = struct {...@@ -2308,7 +2340,7 @@ pub const Global = struct {
2308 },2340 },
23092341
2310 pub const Index = enum(u32) {2342 pub const Index = enum(u32) {
2311 none = std.math.maxInt(u32),2343 none = maxInt(u32),
2312 _,2344 _,
23132345
2314 pub fn unwrap(self: Index, builder: *const Builder) Index {2346 pub fn unwrap(self: Index, builder: *const Builder) Index {
...@@ -2478,7 +2510,7 @@ pub const Alias = struct {...@@ -2478,7 +2510,7 @@ pub const Alias = struct {
2478 aliasee: Constant = .no_init,2510 aliasee: Constant = .no_init,
24792511
2480 pub const Index = enum(u32) {2512 pub const Index = enum(u32) {
2481 none = std.math.maxInt(u32),2513 none = maxInt(u32),
2482 _,2514 _,
24832515
2484 pub fn ptr(self: Index, builder: *Builder) *Alias {2516 pub fn ptr(self: Index, builder: *Builder) *Alias {
...@@ -2530,7 +2562,7 @@ pub const Variable = struct {...@@ -2530,7 +2562,7 @@ pub const Variable = struct {
2530 alignment: Alignment = .default,2562 alignment: Alignment = .default,
25312563
2532 pub const Index = enum(u32) {2564 pub const Index = enum(u32) {
2533 none = std.math.maxInt(u32),2565 none = maxInt(u32),
2534 _,2566 _,
25352567
2536 pub fn ptr(self: Index, builder: *Builder) *Variable {2568 pub fn ptr(self: Index, builder: *Builder) *Variable {
...@@ -3949,7 +3981,7 @@ pub const Intrinsic = enum {...@@ -3949,7 +3981,7 @@ pub const Intrinsic = enum {
3949 .params = &.{3981 .params = &.{
3950 .{3982 .{
3951 .kind = .{ .type = Type.ptr_amdgpu_constant },3983 .kind = .{ .type = Type.ptr_amdgpu_constant },
3952 .attrs = &.{.{ .@"align" = Builder.Alignment.fromByteUnits(4) }},3984 .attrs = &.{.{ .@"align" = .wrap(.fromByteUnits(4)) }},
3953 },3985 },
3954 },3986 },
3955 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3987 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
...@@ -4048,7 +4080,7 @@ pub const Function = struct {...@@ -4048,7 +4080,7 @@ pub const Function = struct {
4048 section: String = .none,4080 section: String = .none,
4049 alignment: Alignment = .default,4081 alignment: Alignment = .default,
4050 blocks: []const Block = &.{},4082 blocks: []const Block = &.{},
4051 instructions: std.MultiArrayList(Instruction) = .{},4083 instructions: std.MultiArrayList(Instruction) = .empty,
4052 names: [*]const String = &[0]String{},4084 names: [*]const String = &[0]String{},
4053 value_indices: [*]const u32 = &[0]u32{},4085 value_indices: [*]const u32 = &[0]u32{},
4054 strip: bool,4086 strip: bool,
...@@ -4057,7 +4089,7 @@ pub const Function = struct {...@@ -4057,7 +4089,7 @@ pub const Function = struct {
4057 extra: []const u32 = &.{},4089 extra: []const u32 = &.{},
40584090
4059 pub const Index = enum(u32) {4091 pub const Index = enum(u32) {
4060 none = std.math.maxInt(u32),4092 none = maxInt(u32),
4061 _,4093 _,
40624094
4063 pub fn ptr(self: Index, builder: *Builder) *Function {4095 pub fn ptr(self: Index, builder: *Builder) *Function {
...@@ -4411,7 +4443,7 @@ pub const Function = struct {...@@ -4411,7 +4443,7 @@ pub const Function = struct {
4411 };4443 };
44124444
4413 pub const Index = enum(u32) {4445 pub const Index = enum(u32) {
4414 none = std.math.maxInt(u31),4446 none = maxInt(u31),
4415 _,4447 _,
44164448
4417 pub fn name(self: Instruction.Index, function: *const Function) String {4449 pub fn name(self: Instruction.Index, function: *const Function) String {
...@@ -5007,7 +5039,7 @@ pub const Function = struct {...@@ -5007,7 +5039,7 @@ pub const Function = struct {
5007 fsub = 12,5039 fsub = 12,
5008 fmax = 13,5040 fmax = 13,
5009 fmin = 14,5041 fmin = 14,
5010 none = std.math.maxInt(u5),5042 none = maxInt(u5),
5011 };5043 };
5012 };5044 };
50135045
...@@ -5222,13 +5254,13 @@ pub const WipFunction = struct {...@@ -5222,13 +5254,13 @@ pub const WipFunction = struct {
5222 .prev_debug_location = .no_location,5254 .prev_debug_location = .no_location,
5223 .debug_location = .no_location,5255 .debug_location = .no_location,
5224 .cursor = undefined,5256 .cursor = undefined,
5225 .blocks = .{},5257 .blocks = .empty,
5226 .instructions = .{},5258 .instructions = .empty,
5227 .names = .{},5259 .names = .empty,
5228 .strip = options.strip,5260 .strip = options.strip,
5229 .debug_locations = .{},5261 .debug_locations = .empty,
5230 .debug_values = .{},5262 .debug_values = .empty,
5231 .extra = .{},5263 .extra = .empty,
5232 };5264 };
5233 errdefer self.deinit();5265 errdefer self.deinit();
52345266
...@@ -5265,7 +5297,7 @@ pub const WipFunction = struct {...@@ -5265,7 +5297,7 @@ pub const WipFunction = struct {
5265 self.blocks.appendAssumeCapacity(.{5297 self.blocks.appendAssumeCapacity(.{
5266 .name = final_name,5298 .name = final_name,
5267 .incoming = incoming,5299 .incoming = incoming,
5268 .instructions = .{},5300 .instructions = .empty,
5269 });5301 });
5270 return index;5302 return index;
5271 }5303 }
...@@ -6132,8 +6164,8 @@ pub const WipFunction = struct {...@@ -6132,8 +6164,8 @@ pub const WipFunction = struct {
6132 kind: MemoryAccessKind,6164 kind: MemoryAccessKind,
6133 @"inline": bool,6165 @"inline": bool,
6134 ) Allocator.Error!Instruction.Index {6166 ) Allocator.Error!Instruction.Index {
6135 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};6167 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(dst_align) })};
6136 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })};6168 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(src_align) })};
6137 const value = try self.callIntrinsic(6169 const value = try self.callIntrinsic(
6138 .normal,6170 .normal,
6139 try self.builder.fnAttrs(&.{6171 try self.builder.fnAttrs(&.{
...@@ -6162,8 +6194,8 @@ pub const WipFunction = struct {...@@ -6162,8 +6194,8 @@ pub const WipFunction = struct {
6162 len: Value,6194 len: Value,
6163 kind: MemoryAccessKind,6195 kind: MemoryAccessKind,
6164 ) Allocator.Error!Instruction.Index {6196 ) Allocator.Error!Instruction.Index {
6165 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};6197 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(dst_align) })};
6166 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })};6198 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(src_align) })};
6167 const value = try self.callIntrinsic(6199 const value = try self.callIntrinsic(
6168 .normal,6200 .normal,
6169 try self.builder.fnAttrs(&.{6201 try self.builder.fnAttrs(&.{
...@@ -6192,7 +6224,7 @@ pub const WipFunction = struct {...@@ -6192,7 +6224,7 @@ pub const WipFunction = struct {
6192 kind: MemoryAccessKind,6224 kind: MemoryAccessKind,
6193 @"inline": bool,6225 @"inline": bool,
6194 ) Allocator.Error!Instruction.Index {6226 ) 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) })};
6196 const value = try self.callIntrinsic(6228 const value = try self.callIntrinsic(
6197 .normal,6229 .normal,
6198 try self.builder.fnAttrs(&.{ .none, .none, try self.builder.attrs(&dst_attrs) }),6230 try self.builder.fnAttrs(&.{ .none, .none, try self.builder.attrs(&dst_attrs) }),
...@@ -6325,7 +6357,7 @@ pub const WipFunction = struct {...@@ -6325,7 +6357,7 @@ pub const WipFunction = struct {
6325 function.blocks = &.{};6357 function.blocks = &.{};
6326 gpa.free(function.names[0..function.instructions.len]);6358 gpa.free(function.names[0..function.instructions.len]);
6327 function.debug_locations.deinit(gpa);6359 function.debug_locations.deinit(gpa);
6328 function.debug_locations = .{};6360 function.debug_locations = .empty;
6329 gpa.free(function.debug_values);6361 gpa.free(function.debug_values);
6330 function.debug_values = &.{};6362 function.debug_values = &.{};
6331 gpa.free(function.extra);6363 gpa.free(function.extra);
...@@ -7329,7 +7361,7 @@ pub const Constant = enum(u32) {...@@ -7329,7 +7361,7 @@ pub const Constant = enum(u32) {
7329 //indices: [info.indices_len]Constant,7361 //indices: [info.indices_len]Constant,
73307362
7331 pub const Kind = enum { normal, inbounds };7363 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), _ };
7333 pub const Info = packed struct(u32) { indices_len: u16, inrange: InRangeIndex };7365 pub const Info = packed struct(u32) { indices_len: u16, inrange: InRangeIndex };
7334 };7366 };
73357367
...@@ -7579,7 +7611,7 @@ pub const Constant = enum(u32) {...@@ -7579,7 +7611,7 @@ pub const Constant = enum(u32) {
7579 string: [7611 string: [
7580 (std.math.big.int.Const{7612 (std.math.big.int.Const{
7581 .limbs = &([1]std.math.big.Limb{7613 .limbs = &([1]std.math.big.Limb{
7582 std.math.maxInt(std.math.big.Limb),7614 maxInt(std.math.big.Limb),
7583 } ** expected_limbs),7615 } ** expected_limbs),
7584 .positive = false,7616 .positive = false,
7585 }).sizeInBaseUpperBound(10)7617 }).sizeInBaseUpperBound(10)
...@@ -7643,7 +7675,7 @@ pub const Constant = enum(u32) {...@@ -7643,7 +7675,7 @@ pub const Constant = enum(u32) {
7643 std.math.minInt(Exponent64),7675 std.math.minInt(Exponent64),
7644 else => @as(Exponent64, repr.exponent) +7676 else => @as(Exponent64, repr.exponent) +
7645 (std.math.floatExponentMax(f64) - std.math.floatExponentMax(f32)),7677 (std.math.floatExponentMax(f64) - std.math.floatExponentMax(f32)),
7646 std.math.maxInt(Exponent32) => std.math.maxInt(Exponent64),7678 maxInt(Exponent32) => maxInt(Exponent64),
7647 },7679 },
7648 .sign = repr.sign,7680 .sign = repr.sign,
7649 }))});7681 }))});
...@@ -7820,7 +7852,7 @@ pub const Constant = enum(u32) {...@@ -7820,7 +7852,7 @@ pub const Constant = enum(u32) {
7820};7852};
78217853
7822pub const Value = enum(u32) {7854pub const Value = enum(u32) {
7823 none = std.math.maxInt(u31),7855 none = maxInt(u31),
7824 false = first_constant + @intFromEnum(Constant.false),7856 false = first_constant + @intFromEnum(Constant.false),
7825 true = first_constant + @intFromEnum(Constant.true),7857 true = first_constant + @intFromEnum(Constant.true),
7826 @"0" = first_constant + @intFromEnum(Constant.@"0"),7858 @"0" = first_constant + @intFromEnum(Constant.@"0"),
...@@ -8021,6 +8053,7 @@ pub const Metadata = packed struct(u32) {...@@ -8021,6 +8053,7 @@ pub const Metadata = packed struct(u32) {
8021 composite_vector_type,8053 composite_vector_type,
8022 derived_pointer_type,8054 derived_pointer_type,
8023 derived_member_type,8055 derived_member_type,
8056 derived_typedef_type,
8024 subroutine_type,8057 subroutine_type,
8025 enumerator_unsigned,8058 enumerator_unsigned,
8026 enumerator_signed_positive,8059 enumerator_signed_positive,
...@@ -8064,6 +8097,7 @@ pub const Metadata = packed struct(u32) {...@@ -8064,6 +8097,7 @@ pub const Metadata = packed struct(u32) {
8064 .composite_vector_type,8097 .composite_vector_type,
8065 .derived_pointer_type,8098 .derived_pointer_type,
8066 .derived_member_type,8099 .derived_member_type,
8100 .derived_typedef_type,
8067 .subroutine_type,8101 .subroutine_type,
8068 .enumerator_unsigned,8102 .enumerator_unsigned,
8069 .enumerator_signed_positive,8103 .enumerator_signed_positive,
...@@ -8391,7 +8425,7 @@ pub const Metadata = packed struct(u32) {...@@ -8391,7 +8425,7 @@ pub const Metadata = packed struct(u32) {
8391 map: std.AutoArrayHashMapUnmanaged(union(enum) {8425 map: std.AutoArrayHashMapUnmanaged(union(enum) {
8392 metadata: Metadata,8426 metadata: Metadata,
8393 debug_location: DebugLocation.Location,8427 debug_location: DebugLocation.Location,
8394 }, void) = .{},8428 }, void) = .empty,
83958429
8396 const FormatData = struct {8430 const FormatData = struct {
8397 formatter: *Formatter,8431 formatter: *Formatter,
...@@ -8649,52 +8683,54 @@ pub fn init(options: Options) Allocator.Error!Builder {...@@ -8649,52 +8683,54 @@ pub fn init(options: Options) Allocator.Error!Builder {
8649 .source_filename = .none,8683 .source_filename = .none,
8650 .data_layout = .none,8684 .data_layout = .none,
8651 .target_triple = .none,8685 .target_triple = .none,
8652 .module_asm = .{},8686 .module_asm = .empty,
86538687
8654 .string_map = .{},8688 .string_map = .empty,
8655 .string_indices = .{},8689 .string_indices = .empty,
8656 .string_bytes = .{},8690 .string_bytes = .empty,
86578691
8658 .types = .{},8692 .types = .empty,
8659 .next_unnamed_type = @enumFromInt(0),8693 .next_unnamed_type = @enumFromInt(0),
8660 .next_unique_type_id = .{},8694 .next_unique_type_id = .empty,
8661 .type_map = .{},8695 .type_map = .empty,
8662 .type_items = .{},8696 .type_items = .empty,
8663 .type_extra = .{},8697 .type_extra = .empty,
86648698
8665 .attributes = .{},8699 .attributes = .empty,
8666 .attributes_map = .{},8700 .attributes_map = .empty,
8667 .attributes_indices = .{},8701 .attributes_indices = .empty,
8668 .attributes_extra = .{},8702 .attributes_extra = .empty,
86698703
8670 .function_attributes_set = .{},8704 .function_attributes_set = .empty,
86718705
8672 .globals = .{},8706 .globals = .empty,
8673 .next_unnamed_global = @enumFromInt(0),8707 .next_unnamed_global = @enumFromInt(0),
8674 .next_replaced_global = .none,8708 .next_replaced_global = .none,
8675 .next_unique_global_id = .{},8709 .next_unique_global_id = .empty,
8676 .aliases = .{},8710 .aliases = .empty,
8677 .variables = .{},8711 .variables = .empty,
8678 .functions = .{},8712 .functions = .empty,
86798713
8680 .strtab_string_map = .{},8714 .strtab_string_map = .empty,
8681 .strtab_string_indices = .{},8715 .strtab_string_indices = .empty,
8682 .strtab_string_bytes = .{},8716 .strtab_string_bytes = .empty,
86838717
8684 .constant_map = .{},8718 .constant_map = .empty,
8685 .constant_items = .{},8719 .constant_items = .empty,
8686 .constant_extra = .{},8720 .constant_extra = .empty,
8687 .constant_limbs = .{},8721 .constant_limbs = .empty,
86888722
8689 .metadata_map = .{},8723 .alignment_forward_references = .empty,
8690 .metadata_items = .{},8724
8691 .metadata_extra = .{},8725 .metadata_map = .empty,
8692 .metadata_limbs = .{},8726 .metadata_items = .empty,
8693 .metadata_forward_references = .{},8727 .metadata_extra = .empty,
8694 .metadata_named = .{},8728 .metadata_limbs = .empty,
8695 .metadata_string_map = .{},8729 .metadata_forward_references = .empty,
8696 .metadata_string_indices = .{},8730 .metadata_named = .empty,
8697 .metadata_string_bytes = .{},8731 .metadata_string_map = .empty,
8732 .metadata_string_indices = .empty,
8733 .metadata_string_bytes = .empty,
8698 };8734 };
8699 errdefer self.deinit();8735 errdefer self.deinit();
87008736
...@@ -8798,51 +8834,55 @@ pub fn clearAndFree(self: *Builder) void {...@@ -8798,51 +8834,55 @@ pub fn clearAndFree(self: *Builder) void {
8798}8834}
87998835
8800pub fn deinit(self: *Builder) void {8836pub 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);8839 self.module_asm.deinit(gpa);
8804 self.string_indices.deinit(self.gpa);
8805 self.string_bytes.deinit(self.gpa);
88068840
8807 self.types.deinit(self.gpa);8841 self.string_map.deinit(gpa);
8808 self.next_unique_type_id.deinit(self.gpa);8842 self.string_indices.deinit(gpa);
8809 self.type_map.deinit(self.gpa);8843 self.string_bytes.deinit(gpa);
8810 self.type_items.deinit(self.gpa);
8811 self.type_extra.deinit(self.gpa);
88128844
8813 self.attributes.deinit(self.gpa);8845 self.types.deinit(gpa);
8814 self.attributes_map.deinit(self.gpa);8846 self.next_unique_type_id.deinit(gpa);
8815 self.attributes_indices.deinit(self.gpa);8847 self.type_map.deinit(gpa);
8816 self.attributes_extra.deinit(self.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);8856 self.function_attributes_set.deinit(gpa);
8821 self.next_unique_global_id.deinit(self.gpa);8857
8822 self.aliases.deinit(self.gpa);8858 self.globals.deinit(gpa);
8823 self.variables.deinit(self.gpa);8859 self.next_unique_global_id.deinit(gpa);
8824 for (self.functions.items) |*function| function.deinit(self.gpa);8860 self.aliases.deinit(gpa);
8825 self.functions.deinit(self.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);8869 self.constant_map.deinit(gpa);
8828 self.strtab_string_indices.deinit(self.gpa);8870 self.constant_items.deinit(gpa);
8829 self.strtab_string_bytes.deinit(self.gpa);8871 self.constant_extra.deinit(gpa);
8872 self.constant_limbs.deinit(gpa);
88308873
8831 self.constant_map.deinit(self.gpa);8874 self.alignment_forward_references.deinit(gpa);
8832 self.constant_items.deinit(self.gpa);
8833 self.constant_extra.deinit(self.gpa);
8834 self.constant_limbs.deinit(self.gpa);
88358875
8836 self.metadata_map.deinit(self.gpa);8876 self.metadata_map.deinit(gpa);
8837 self.metadata_items.deinit(self.gpa);8877 self.metadata_items.deinit(gpa);
8838 self.metadata_extra.deinit(self.gpa);8878 self.metadata_extra.deinit(gpa);
8839 self.metadata_limbs.deinit(self.gpa);8879 self.metadata_limbs.deinit(gpa);
8840 self.metadata_forward_references.deinit(self.gpa);8880 self.metadata_forward_references.deinit(gpa);
8841 self.metadata_named.deinit(self.gpa);8881 self.metadata_named.deinit(gpa);
88428882
8843 self.metadata_string_map.deinit(self.gpa);8883 self.metadata_string_map.deinit(gpa);
8844 self.metadata_string_indices.deinit(self.gpa);8884 self.metadata_string_indices.deinit(gpa);
8845 self.metadata_string_bytes.deinit(self.gpa);8885 self.metadata_string_bytes.deinit(gpa);
88468886
8847 self.* = undefined;8887 self.* = undefined;
8848}8888}
...@@ -8960,7 +9000,7 @@ pub fn structType(...@@ -8960,7 +9000,7 @@ pub fn structType(
8960pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {9000pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {
8961 try self.string_map.ensureUnusedCapacity(self.gpa, 1);9001 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
8962 if (name.slice(self)) |id| {9002 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)});
8964 try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);9004 try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);
8965 }9005 }
8966 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);9006 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
...@@ -9576,6 +9616,21 @@ pub fn asmValue(...@@ -9576,6 +9616,21 @@ pub fn asmValue(
9576 return (try self.asmConst(ty, info, assembly, constraints)).toValue();9616 return (try self.asmConst(ty, info, assembly, constraints)).toValue();
9577}9617}
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
9579pub fn dump(b: *Builder, io: Io) void {9634pub fn dump(b: *Builder, io: Io) void {
9580 var buffer: [4000]u8 = undefined;9635 var buffer: [4000]u8 = undefined;
9581 const stderr: Io.File = .stderr();9636 const stderr: Io.File = .stderr();
...@@ -10463,15 +10518,18 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -10463,15 +10518,18 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
10463 },10518 },
10464 .derived_pointer_type,10519 .derived_pointer_type,
10465 .derived_member_type,10520 .derived_member_type,
10521 .derived_typedef_type,
10466 => |kind| {10522 => |kind| {
10467 const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data);10523 const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data);
10468 try metadata_formatter.specialized(.@"!", .DIDerivedType, .{10524 try metadata_formatter.specialized(.@"!", .DIDerivedType, .{
10469 .tag = @as(enum {10525 .tag = @as(enum {
10470 DW_TAG_pointer_type,10526 DW_TAG_pointer_type,
10471 DW_TAG_member,10527 DW_TAG_member,
10528 DW_TAG_typedef,
10472 }, switch (kind) {10529 }, switch (kind) {
10473 .derived_pointer_type => .DW_TAG_pointer_type,10530 .derived_pointer_type => .DW_TAG_pointer_type,
10474 .derived_member_type => .DW_TAG_member,10531 .derived_member_type => .DW_TAG_member,
10532 .derived_typedef_type => .DW_TAG_typedef,
10475 else => unreachable,10533 else => unreachable,
10476 }),10534 }),
10477 .name = extra.name,10535 .name = extra.name,
...@@ -10510,7 +10568,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -10510,7 +10568,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
10510 string: [10568 string: [
10511 (std.math.big.int.Const{10569 (std.math.big.int.Const{
10512 .limbs = &([1]std.math.big.Limb{10570 .limbs = &([1]std.math.big.Limb{
10513 std.math.maxInt(std.math.big.Limb),10571 maxInt(std.math.big.Limb),
10514 } ** expected_limbs),10572 } ** expected_limbs),
10515 .positive = false,10573 .positive = false,
10516 }).sizeInBaseUpperBound(10)10574 }).sizeInBaseUpperBound(10)
...@@ -10660,7 +10718,7 @@ fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, w: *Writer) Writ...@@ -10660,7 +10718,7 @@ fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, w: *Writer) Writ
10660fn ensureUnusedGlobalCapacity(self: *Builder, name: StrtabString) Allocator.Error!void {10718fn ensureUnusedGlobalCapacity(self: *Builder, name: StrtabString) Allocator.Error!void {
10661 try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1);10719 try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1);
10662 if (name.slice(self)) |id| {10720 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)});
10664 try self.strtab_string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);10722 try self.strtab_string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);
10665 }10723 }
10666 try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1);10724 try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1);
...@@ -12069,7 +12127,7 @@ pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String {...@@ -12069,7 +12127,7 @@ pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String {
12069 const start = self.metadata_string_indices.getLast();12127 const start = self.metadata_string_indices.getLast();
12070 const bytes: []const u8 = self.metadata_string_bytes.items[start..];12128 const bytes: []const u8 = self.metadata_string_bytes.items[start..];
12071 assert(bytes.len > 0);12129 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 });
12073 if (gop.found_existing) {12131 if (gop.found_existing) {
12074 self.metadata_string_bytes.shrinkRetainingCapacity(start);12132 self.metadata_string_bytes.shrinkRetainingCapacity(start);
12075 } else {12133 } else {
...@@ -12360,6 +12418,30 @@ pub fn debugMemberType(...@@ -12360,6 +12418,30 @@ pub fn debugMemberType(
12360 );12418 );
12361}12419}
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
12363pub fn debugSubroutineType(self: *Builder, types_tuple: ?Metadata) Allocator.Error!Metadata {12445pub fn debugSubroutineType(self: *Builder, types_tuple: ?Metadata) Allocator.Error!Metadata {
12364 try self.ensureUnusedMetadataCapacity(1, Metadata.SubroutineType, 0);12446 try self.ensureUnusedMetadataCapacity(1, Metadata.SubroutineType, 0);
12365 return self.debugSubroutineTypeAssumeCapacity(types_tuple);12447 return self.debugSubroutineTypeAssumeCapacity(types_tuple);
...@@ -12467,11 +12549,12 @@ pub fn metadataConstant(self: *Builder, value: Constant) Allocator.Error!Metadat...@@ -12467,11 +12549,12 @@ pub fn metadataConstant(self: *Builder, value: Constant) Allocator.Error!Metadat
12467 return self.metadataConstantAssumeCapacity(value);12549 return self.metadataConstantAssumeCapacity(value);
12468}12550}
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.
12470pub fn resolveDebugForwardReference(self: *Builder, fwd_ref: Metadata, value: Metadata) void {12554pub fn resolveDebugForwardReference(self: *Builder, fwd_ref: Metadata, value: Metadata) void {
12471 assert(fwd_ref.kind == .forward);12555 assert(fwd_ref.kind == .forward);
12472 const resolved = &self.metadata_forward_references.items[fwd_ref.index];12556 assert(value.kind != .forward);
12473 assert(resolved.is_none);12557 self.metadata_forward_references.items[fwd_ref.index] = value.toOptional();
12474 resolved.* = value.toOptional();
12475}12558}
1247612559
12477fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata {12560fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata {
...@@ -12874,6 +12957,33 @@ fn debugMemberTypeAssumeCapacity(...@@ -12874,6 +12957,33 @@ fn debugMemberTypeAssumeCapacity(
12874 });12957 });
12875}12958}
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
12877fn debugSubroutineTypeAssumeCapacity(self: *Builder, types_tuple: ?Metadata) Metadata {12987fn debugSubroutineTypeAssumeCapacity(self: *Builder, types_tuple: ?Metadata) Metadata {
12878 assert(!self.strip);12988 assert(!self.strip);
12879 return self.metadataSimpleAssumeCapacity(.subroutine_type, Metadata.SubroutineType{12989 return self.metadataSimpleAssumeCapacity(.subroutine_type, Metadata.SubroutineType{
...@@ -13461,7 +13571,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13461,7 +13571,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13461 try record.ensureUnusedCapacity(self.gpa, 3);13571 try record.ensureUnusedCapacity(self.gpa, 3);
13462 record.appendAssumeCapacity(1);13572 record.appendAssumeCapacity(1);
13463 record.appendAssumeCapacity(@intFromEnum(kind));13573 record.appendAssumeCapacity(@intFromEnum(kind));
13464 record.appendAssumeCapacity(alignment.toByteUnits() orelse 0);13574 record.appendAssumeCapacity(alignment.resolve(self).toByteUnits() orelse 0);
13465 },13575 },
13466 .dereferenceable,13576 .dereferenceable,
13467 .dereferenceable_or_null,13577 .dereferenceable_or_null,
...@@ -14222,12 +14332,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -14222,12 +14332,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
14222 },14332 },
14223 .derived_pointer_type,14333 .derived_pointer_type,
14224 .derived_member_type,14334 .derived_member_type,
14335 .derived_typedef_type,
14225 => |kind| {14336 => |kind| {
14226 const extra = self.metadataExtraData(Metadata.DerivedType, data);14337 const extra = self.metadataExtraData(Metadata.DerivedType, data);
14227 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{14338 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{
14228 .tag = switch (kind) {14339 .tag = switch (kind) {
14229 .derived_pointer_type => DW.TAG.pointer_type,14340 .derived_pointer_type => DW.TAG.pointer_type,
14230 .derived_member_type => DW.TAG.member,14341 .derived_member_type => DW.TAG.member,
14342 .derived_typedef_type => DW.TAG.typedef,
14231 else => unreachable,14343 else => unreachable,
14232 },14344 },
14233 .name = extra.name,14345 .name = extra.name,
lib/std/zig/target.zig+9-8
...@@ -503,8 +503,7 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 {...@@ -503,8 +503,7 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 {
503pub fn intAlignment(target: *const std.Target, bits: u16) u16 {503pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
504 return switch (target.cpu.arch) {504 return switch (target.cpu.arch) {
505 .x86 => switch (bits) {505 .x86 => switch (bits) {
506 0 => 0,506 0...8 => 1,
507 1...8 => 1,
508 9...16 => 2,507 9...16 => 2,
509 17...32 => 4,508 17...32 => 4,
510 33...64 => switch (target.os.tag) {509 33...64 => switch (target.os.tag) {
...@@ -514,17 +513,19 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 {...@@ -514,17 +513,19 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
514 else => 16,513 else => 16,
515 },514 },
516 .x86_64 => switch (bits) {515 .x86_64 => switch (bits) {
517 0 => 0,516 0...8 => 1,
518 1...8 => 1,
519 9...16 => 2,517 9...16 => 2,
520 17...32 => 4,518 17...32 => 4,
521 33...64 => 8,519 33...64 => 8,
522 else => 16,520 else => 16,
523 },521 },
524 else => return @min(522 else => switch (bits) {
525 std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),523 0 => 1,
526 target.cMaxIntAlignment(),524 else => @min(
527 ),525 std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)),
526 target.cMaxIntAlignment(),
527 ),
528 },
528 };529 };
529}530}
530531
lib/std/zon/Serializer.zig+3-1
...@@ -793,9 +793,11 @@ test checkValueDepth {...@@ -793,9 +793,11 @@ test checkValueDepth {
793 try expectValueDepthEquals(2, @as(?u32, 1));793 try expectValueDepthEquals(2, @as(?u32, 1));
794 try expectValueDepthEquals(1, @as(?u32, null));794 try expectValueDepthEquals(1, @as(?u32, null));
795 try expectValueDepthEquals(1, null);795 try expectValueDepthEquals(1, null);
796 try expectValueDepthEquals(2, &1);
797 try expectValueDepthEquals(3, &@as(?u32, 1));796 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
799 const Union = union(enum) {801 const Union = union(enum) {
800 x: u32,802 x: u32,
801 y: struct { x: u32 },803 y: struct { x: u32 },
lib/std/zon/parse.zig+3-3
...@@ -591,7 +591,7 @@ const Parser = struct {...@@ -591,7 +591,7 @@ const Parser = struct {
591 if (pointer.child == u8 and591 if (pointer.child == u8 and
592 pointer.is_const and592 pointer.is_const and
593 (pointer.sentinel() == null or pointer.sentinel() == 0) and593 (pointer.sentinel() == null or pointer.sentinel() == 0) and
594 pointer.alignment == 1)594 (pointer.alignment == null or pointer.alignment == 1))
595 {595 {
596 if (opt) {596 if (opt) {
597 return self.failNode(node, "expected optional string");597 return self.failNode(node, "expected optional string");
...@@ -717,7 +717,7 @@ const Parser = struct {...@@ -717,7 +717,7 @@ const Parser = struct {
717 pointer.size != .slice or717 pointer.size != .slice or
718 !pointer.is_const or718 !pointer.is_const or
719 (pointer.sentinel() != null and pointer.sentinel() != 0) or719 (pointer.sentinel() != null and pointer.sentinel() != 0) or
720 pointer.alignment != 1)720 (pointer.alignment != null and pointer.alignment != 1))
721 {721 {
722 return error.WrongType;722 return error.WrongType;
723 }723 }
...@@ -742,7 +742,7 @@ const Parser = struct {...@@ -742,7 +742,7 @@ const Parser = struct {
742 const slice = try self.gpa.allocWithOptions(742 const slice = try self.gpa.allocWithOptions(
743 pointer.child,743 pointer.child,
744 nodes.len,744 nodes.len,
745 .fromByteUnits(pointer.alignment),745 .fromByteUnitsOptional(pointer.alignment),
746 pointer.sentinel(),746 pointer.sentinel(),
747 );747 );
748 errdefer self.gpa.free(slice);748 errdefer self.gpa.free(slice);
lib/zig.h+9-1
...@@ -151,6 +151,14 @@...@@ -151,6 +151,14 @@
151#define zig_has_attribute(attribute) 0151#define zig_has_attribute(attribute) 0
152#endif152#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
154#if __STDC_VERSION__ >= 202311L162#if __STDC_VERSION__ >= 202311L
155#define zig_threadlocal thread_local163#define zig_threadlocal thread_local
156#elif __STDC_VERSION__ >= 201112L164#elif __STDC_VERSION__ >= 201112L
...@@ -259,7 +267,7 @@...@@ -259,7 +267,7 @@
259#endif267#endif
260268
261#if zig_has_attribute(packed) || defined(zig_tinyc)269#if zig_has_attribute(packed) || defined(zig_tinyc)
262#define zig_packed(definition) __attribute__((packed)) definition270#define zig_packed(definition) definition __attribute__((packed))
263#elif defined(zig_msvc)271#elif defined(zig_msvc)
264#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())272#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())
265#else273#else
src/Air.zig+5-8
...@@ -14,7 +14,6 @@ const Type = @import("Type.zig");...@@ -14,7 +14,6 @@ const Type = @import("Type.zig");
14const Value = @import("Value.zig");14const Value = @import("Value.zig");
15const Zcu = @import("Zcu.zig");15const Zcu = @import("Zcu.zig");
16const print = @import("Air/print.zig");16const print = @import("Air/print.zig");
17const types_resolved = @import("Air/types_resolved.zig");
1817
19pub const Legalize = @import("Air/Legalize.zig");18pub const Legalize = @import("Air/Legalize.zig");
20pub const Liveness = @import("Air/Liveness.zig");19pub const Liveness = @import("Air/Liveness.zig");
...@@ -173,8 +172,8 @@ pub const Inst = struct {...@@ -173,8 +172,8 @@ pub const Inst = struct {
173 /// outside the provenance of the operand, the result is undefined.172 /// outside the provenance of the operand, the result is undefined.
174 ///173 ///
175 /// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,174 /// 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 may175 /// rhs is the offset. Result type is the same as lhs. The operand type's
177 /// be a slice.176 /// pointer size may be `.slice`, `.many`, or `.c`.
178 ptr_add,177 ptr_add,
179 /// Subtract an offset, in element type units, from a pointer,178 /// Subtract an offset, in element type units, from a pointer,
180 /// returning a new pointer. Element type may not be zero bits.179 /// returning a new pointer. Element type may not be zero bits.
...@@ -183,8 +182,8 @@ pub const Inst = struct {...@@ -183,8 +182,8 @@ pub const Inst = struct {
183 /// outside the provenance of the operand, the result is undefined.182 /// outside the provenance of the operand, the result is undefined.
184 ///183 ///
185 /// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,184 /// 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 may185 /// rhs is the offset. Result type is the same as lhs. The operand type's
187 /// be a slice.186 /// pointer size may be `.slice`, `.many`, or `.c`.
188 ptr_sub,187 ptr_sub,
189 /// Given two operands which can be floats, integers, or vectors, returns the188 /// Given two operands which can be floats, integers, or vectors, returns the
190 /// greater of the operands. For vectors it operates element-wise.189 /// greater of the operands. For vectors it operates element-wise.
...@@ -693,6 +692,7 @@ pub const Inst = struct {...@@ -693,6 +692,7 @@ pub const Inst = struct {
693 /// Uses the `ty_pl` field with payload `Bin`.692 /// Uses the `ty_pl` field with payload `Bin`.
694 slice_elem_ptr,693 slice_elem_ptr,
695 /// Given a pointer value, and element index, return the element value at that index.694 /// Given a pointer value, and element index, return the element value at that index.
695 /// The pointer size is either `.c` or `.many`.
696 /// Result type is the element type of the pointer operand.696 /// Result type is the element type of the pointer operand.
697 /// Uses the `bin_op` field.697 /// Uses the `bin_op` field.
698 ptr_elem_val,698 ptr_elem_val,
...@@ -2440,9 +2440,6 @@ pub fn unwrapShuffleTwo(air: *const Air, zcu: *const Zcu, inst_index: Inst.Index...@@ -2440,9 +2440,6 @@ pub fn unwrapShuffleTwo(air: *const Air, zcu: *const Zcu, inst_index: Inst.Index
2440 };2440 };
2441}2441}
24422442
2443pub const typesFullyResolved = types_resolved.typesFullyResolved;
2444pub const typeFullyResolved = types_resolved.checkType;
2445pub const valFullyResolved = types_resolved.checkVal;
2446pub const legalize = Legalize.legalize;2443pub const legalize = Legalize.legalize;
2447pub const write = print.write;2444pub const write = print.write;
2448pub const writeInst = print.writeInst;2445pub 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...@@ -153,8 +153,8 @@ pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Li
153 usize,153 usize,
154 (air.instructions.len * bpi + @bitSizeOf(usize) - 1) / @bitSizeOf(usize),154 (air.instructions.len * bpi + @bitSizeOf(usize) - 1) / @bitSizeOf(usize),
155 ),155 ),
156 .extra = .{},156 .extra = .empty,
157 .special = .{},157 .special = .empty,
158 .intern_pool = intern_pool,158 .intern_pool = intern_pool,
159 };159 };
160 errdefer gpa.free(a.tomb_bits);160 errdefer gpa.free(a.tomb_bits);
...@@ -175,7 +175,7 @@ pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Li...@@ -175,7 +175,7 @@ pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Li
175 var data: LivenessPassData(.main_analysis) = .{};175 var data: LivenessPassData(.main_analysis) = .{};
176 defer data.deinit(gpa);176 defer data.deinit(gpa);
177 data.old_extra = a.extra;177 data.old_extra = a.extra;
178 a.extra = .{};178 a.extra = .empty;
179 try analyzeBody(&a, .main_analysis, &data, main_body);179 try analyzeBody(&a, .main_analysis, &data, main_body);
180 assert(data.live_set.count() == 0);180 assert(data.live_set.count() == 0);
181 }181 }
...@@ -999,7 +999,7 @@ fn analyzeInstBlock(...@@ -999,7 +999,7 @@ fn analyzeInstBlock(
999999
1000 // If the block is noreturn, block deaths not only aren't useful, they're impossible to1000 // If the block is noreturn, block deaths not only aren't useful, they're impossible to
1001 // find: there could be more stuff alive after the block than before it!1001 // 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)) {
1003 // The block kills the difference in the live sets1003 // The block kills the difference in the live sets
1004 const block_scope = data.block_scopes.get(inst).?;1004 const block_scope = data.block_scopes.get(inst).?;
1005 const num_deaths = data.live_set.count() - block_scope.live_set.count();1005 const num_deaths = data.live_set.count() - block_scope.live_set.count();
...@@ -1360,7 +1360,7 @@ fn analyzeInstSwitchBr(...@@ -1360,7 +1360,7 @@ fn analyzeInstSwitchBr(
1360 const mirrored_deaths = try gpa.alloc(DeathList, ncases + 1);1360 const mirrored_deaths = try gpa.alloc(DeathList, ncases + 1);
1361 defer gpa.free(mirrored_deaths);1361 defer gpa.free(mirrored_deaths);
13621362
1363 @memset(mirrored_deaths, .{});1363 @memset(mirrored_deaths, .empty);
1364 defer for (mirrored_deaths) |*md| md.deinit(gpa);1364 defer for (mirrored_deaths) |*md| md.deinit(gpa);
13651365
1366 {1366 {
src/Air/Liveness/Verify.zig+1-1
...@@ -465,7 +465,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {...@@ -465,7 +465,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
465465
466 for (block_liveness.deaths) |death| try self.verifyDeath(inst, death);466 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)) {
469 assert(!self.blocks.contains(inst));469 assert(!self.blocks.contains(inst));
470 } else {470 } else {
471 var live = if (self.blocks.fetchRemove(inst)) |kv| kv.value else {471 var live = if (self.blocks.fetchRemove(inst)) |kv| kv.value else {
src/Air/print.zig+17-27
...@@ -692,33 +692,23 @@ const Writer = struct {...@@ -692,33 +692,23 @@ const Writer = struct {
692692
693 const zcu = w.pt.zcu;693 const zcu = w.pt.zcu;
694 const ip = &zcu.intern_pool;694 const ip = &zcu.intern_pool;
695 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;695 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
696 const struct_type: Type = .fromInterned(aggregate.ty);696 const clobbers_ty = clobbers_val.typeOf(zcu);
697 switch (aggregate.storage) {697 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
698 .elems => |elems| for (elems, 0..) |elem, i| {698 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
699 switch (elem) {699 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
700 .bool_true => {700 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
701 const clobber = struct_type.structFieldName(i, zcu).toSlice(ip).?;701 const limb_bits = @bitSizeOf(std.math.big.Limb);
702 assert(clobber.len != 0);702 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
703 try s.writeAll(", ~{");703 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
704 try s.writeAll(clobber);704 0 => continue, // field is false
705 try s.writeAll("}");705 1 => {}, // field is true
706 },706 }
707 .bool_false => continue,707 const clobber = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
708 else => unreachable,708 assert(clobber.len != 0);
709 }709 try s.writeAll(", ~{");
710 },710 try s.writeAll(clobber);
711 .repeated_elem => |elem| {711 try s.writeAll("}");
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 },
722 }712 }
723 const asm_source = unwrapped_asm.source;713 const asm_source = unwrapped_asm.source;
724 try s.print(", \"{f}\"", .{std.zig.fmtString(asm_source)});714 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");...@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
21const link = @import("link.zig");21const link = @import("link.zig");
22const tracy = @import("tracy.zig");22const tracy = @import("tracy.zig");
23const trace = tracy.trace;23const trace = tracy.trace;
24const traceNamed = tracy.traceNamed;
25const build_options = @import("build_options");24const build_options = @import("build_options");
26const LibCInstallation = std.zig.LibCInstallation;25const LibCInstallation = std.zig.LibCInstallation;
27const glibc = @import("libs/glibc.zig");26const glibc = @import("libs/glibc.zig");
...@@ -89,6 +88,9 @@ framework_dirs: []const []const u8,...@@ -89,6 +88,9 @@ framework_dirs: []const []const u8,
89/// These are only for DLLs dependencies fulfilled by the `.def` files shipped88/// These are only for DLLs dependencies fulfilled by the `.def` files shipped
90/// with Zig. Static libraries are provided as `link.Input` values.89/// with Zig. Static libraries are provided as `link.Input` values.
91windows_libs: std.StringArrayHashMapUnmanaged(void),90windows_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,
92version: ?std.SemanticVersion,94version: ?std.SemanticVersion,
93libc_installation: ?*const LibCInstallation,95libc_installation: ?*const LibCInstallation,
94skip_linker_dependencies: bool,96skip_linker_dependencies: bool,
...@@ -126,16 +128,6 @@ oneshot_prelink_tasks: std.ArrayList(link.PrelinkTask),...@@ -126,16 +128,6 @@ oneshot_prelink_tasks: std.ArrayList(link.PrelinkTask),
126/// work is queued or not.128/// work is queued or not.
127queued_jobs: QueuedJobs,129queued_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
139/// These jobs are to invoke the Clang compiler to create an object file, which131/// These jobs are to invoke the Clang compiler to create an object file, which
140/// gets linked with the Compilation.132/// gets linked with the Compilation.
141c_object_work_queue: std.Deque(*CObject),133c_object_work_queue: std.Deque(*CObject),
...@@ -962,65 +954,6 @@ pub const RcSourceFile = struct {...@@ -962,65 +954,6 @@ pub const RcSourceFile = struct {
962 extra_flags: []const []const u8 = &.{},954 extra_flags: []const []const u8 = &.{},
963};955};
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
1024pub const CObject = struct {957pub const CObject = struct {
1025 /// Relative to cwd. Owned by arena.958 /// Relative to cwd. Owned by arena.
1026 src: CSourceFile,959 src: CSourceFile,
...@@ -1412,7 +1345,6 @@ pub const MiscTask = enum {...@@ -1412,7 +1345,6 @@ pub const MiscTask = enum {
1412 wasi_libc_crt_file,1345 wasi_libc_crt_file,
1413 compiler_rt,1346 compiler_rt,
1414 libzigc,1347 libzigc,
1415 analyze_mod,
1416 link_depfile,1348 link_depfile,
1417 docs_copy,1349 docs_copy,
1418 docs_wasm,1350 docs_wasm,
...@@ -2297,7 +2229,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2297,7 +2229,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2297 .root_mod = options.root_mod,2229 .root_mod = options.root_mod,
2298 .config = options.config,2230 .config = options.config,
2299 .dirs = options.dirs,2231 .dirs = options.dirs,
2300 .work_queues = @splat(.empty),
2301 .c_object_work_queue = .empty,2232 .c_object_work_queue = .empty,
2302 .win32_resource_work_queue = .empty,2233 .win32_resource_work_queue = .empty,
2303 .c_source_files = options.c_source_files,2234 .c_source_files = options.c_source_files,
...@@ -2331,6 +2262,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2331,6 +2262,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2331 .root_name = root_name,2262 .root_name = root_name,
2332 .sysroot = sysroot,2263 .sysroot = sysroot,
2333 .windows_libs = .empty,2264 .windows_libs = .empty,
2265 .windows_libs_num_done = 0,
2334 .version = options.version,2266 .version = options.version,
2335 .libc_installation = libc_dirs.libc_installation,2267 .libc_installation = libc_dirs.libc_installation,
2336 .compiler_rt_strat = compiler_rt_strat,2268 .compiler_rt_strat = compiler_rt_strat,
...@@ -2693,16 +2625,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2693,16 +2625,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2693 }2625 }
2694 }2626 }
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 }
2706 if (comp.wantBuildLibUnwindFromSource()) {2628 if (comp.wantBuildLibUnwindFromSource()) {
2707 comp.queued_jobs.libunwind = true;2629 comp.queued_jobs.libunwind = true;
2708 }2630 }
...@@ -2786,7 +2708,6 @@ pub fn destroy(comp: *Compilation) void {...@@ -2786,7 +2708,6 @@ pub fn destroy(comp: *Compilation) void {
2786 if (comp.zcu) |zcu| zcu.deinit();2708 if (comp.zcu) |zcu| zcu.deinit();
2787 comp.cache_use.deinit(io);2709 comp.cache_use.deinit(io);
27882710
2789 for (&comp.work_queues) |*work_queue| work_queue.deinit(gpa);
2790 comp.c_object_work_queue.deinit(gpa);2711 comp.c_object_work_queue.deinit(gpa);
2791 comp.win32_resource_work_queue.deinit(gpa);2712 comp.win32_resource_work_queue.deinit(gpa);
27922713
...@@ -3461,9 +3382,6 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel...@@ -3461,9 +3382,6 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel
3461 error.OutOfMemory, error.Canceled => |e| return e,3382 error.OutOfMemory, error.Canceled => |e| return e,
3462 };3383 };
3463 }3384 }
3464 if (comp.zcu) |zcu| {
3465 try link.File.C.flushEmitH(zcu);
3466 }
3467}3385}
34683386
3469/// This function is called by the frontend before flush(). It communicates that3387/// This function is called by the frontend before flush(). It communicates that
...@@ -3728,7 +3646,9 @@ const Header = extern struct {...@@ -3728,7 +3646,9 @@ const Header = extern struct {
3728 src_hash_deps_len: u32,3646 src_hash_deps_len: u32,
3729 nav_val_deps_len: u32,3647 nav_val_deps_len: u32,
3730 nav_ty_deps_len: u32,3648 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,
3732 zon_file_deps_len: u32,3652 zon_file_deps_len: u32,
3733 embed_file_deps_len: u32,3653 embed_file_deps_len: u32,
3734 namespace_deps_len: u32,3654 namespace_deps_len: u32,
...@@ -3776,7 +3696,9 @@ pub fn saveState(comp: *Compilation) !void {...@@ -3776,7 +3696,9 @@ pub fn saveState(comp: *Compilation) !void {
3776 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),3696 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
3777 .nav_val_deps_len = @intCast(ip.nav_val_deps.count()),3697 .nav_val_deps_len = @intCast(ip.nav_val_deps.count()),
3778 .nav_ty_deps_len = @intCast(ip.nav_ty_deps.count()),3698 .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()),
3780 .zon_file_deps_len = @intCast(ip.zon_file_deps.count()),3702 .zon_file_deps_len = @intCast(ip.zon_file_deps.count()),
3781 .embed_file_deps_len = @intCast(ip.embed_file_deps.count()),3703 .embed_file_deps_len = @intCast(ip.embed_file_deps.count()),
3782 .namespace_deps_len = @intCast(ip.namespace_deps.count()),3704 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
...@@ -3800,7 +3722,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -3800,7 +3722,7 @@ pub fn saveState(comp: *Compilation) !void {
3800 },3722 },
3801 });3723 });
38023724
3803 try bufs.ensureTotalCapacityPrecise(22 + 9 * pt_headers.items.len);3725 try bufs.ensureTotalCapacityPrecise(26 + 9 * pt_headers.items.len);
3804 addBuf(&bufs, mem.asBytes(&header));3726 addBuf(&bufs, mem.asBytes(&header));
3805 addBuf(&bufs, @ptrCast(pt_headers.items));3727 addBuf(&bufs, @ptrCast(pt_headers.items));
38063728
...@@ -3810,8 +3732,12 @@ pub fn saveState(comp: *Compilation) !void {...@@ -3810,8 +3732,12 @@ pub fn saveState(comp: *Compilation) !void {
3810 addBuf(&bufs, @ptrCast(ip.nav_val_deps.values()));3732 addBuf(&bufs, @ptrCast(ip.nav_val_deps.values()));
3811 addBuf(&bufs, @ptrCast(ip.nav_ty_deps.keys()));3733 addBuf(&bufs, @ptrCast(ip.nav_ty_deps.keys()));
3812 addBuf(&bufs, @ptrCast(ip.nav_ty_deps.values()));3734 addBuf(&bufs, @ptrCast(ip.nav_ty_deps.values()));
3813 addBuf(&bufs, @ptrCast(ip.interned_deps.keys()));3735 addBuf(&bufs, @ptrCast(ip.type_layout_deps.keys()));
3814 addBuf(&bufs, @ptrCast(ip.interned_deps.values()));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()));
3815 addBuf(&bufs, @ptrCast(ip.zon_file_deps.keys()));3741 addBuf(&bufs, @ptrCast(ip.zon_file_deps.keys()));
3816 addBuf(&bufs, @ptrCast(ip.zon_file_deps.values()));3742 addBuf(&bufs, @ptrCast(ip.zon_file_deps.values()));
3817 addBuf(&bufs, @ptrCast(ip.embed_file_deps.keys()));3743 addBuf(&bufs, @ptrCast(ip.embed_file_deps.keys()));
...@@ -4128,21 +4054,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4128,21 +4054,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4128 const SortOrder = struct {4054 const SortOrder = struct {
4129 zcu: *Zcu,4055 zcu: *Zcu,
4130 errors: []const *Zcu.ErrorMsg,4056 errors: []const *Zcu.ErrorMsg,
4131 read_err: *?ReadError,
4132 const ReadError = struct {
4133 file: *Zcu.File,
4134 err: Zcu.File.GetSourceError,
4135 };
4136 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {4057 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
4137 if (ctx.read_err.* != null) return lhs_index < rhs_index;4058 return Zcu.ErrorMsg.order(
4138 var bad_file: *Zcu.File = undefined;4059 ctx.errors[lhs_index],
4139 return ctx.errors[lhs_index].src_loc.lessThan(ctx.errors[rhs_index].src_loc, ctx.zcu, &bad_file) catch |err| {4060 ctx.errors[rhs_index],
4140 ctx.read_err.* = .{4061 ctx.zcu,
4141 .file = bad_file,4062 ).compare(.lt);
4142 .err = err,
4143 };
4144 return lhs_index < rhs_index;
4145 };
4146 }4063 }
4147 };4064 };
41484065
...@@ -4152,16 +4069,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4152,16 +4069,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4152 var entries = try zcu.failed_analysis.entries.clone(gpa);4069 var entries = try zcu.failed_analysis.entries.clone(gpa);
4153 errdefer entries.deinit(gpa);4070 errdefer entries.deinit(gpa);
41544071
4155 var read_err: ?SortOrder.ReadError = null;
4156 entries.sort(SortOrder{4072 entries.sort(SortOrder{
4157 .zcu = zcu,4073 .zcu = zcu,
4158 .errors = entries.items(.value),4074 .errors = entries.items(.value),
4159 .read_err = &read_err,
4160 });4075 });
4161 if (read_err) |e| {
4162 try unableToLoadZcuFile(zcu, &bundle, e.file, e.err);
4163 break :zcu_errors;
4164 }
4165 break :s entries.slice();4076 break :s entries.slice();
4166 };4077 };
4167 defer sorted_failed_analysis.deinit(gpa);4078 defer sorted_failed_analysis.deinit(gpa);
...@@ -4200,6 +4111,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4200,6 +4111,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4200 }4111 }
4201 }4112 }
4202 }4113 }
4114 try zcu.addDependencyLoopErrors(&bundle);
4203 for (zcu.failed_codegen.values()) |error_msg| {4115 for (zcu.failed_codegen.values()) |error_msg| {
4204 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);4116 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
4205 }4117 }
...@@ -4219,7 +4131,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4219,7 +4131,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4219 .notes_len = 1,4131 .notes_len = 1,
4220 });4132 });
4221 const notes_start = try bundle.reserveNotes(1);4133 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(.{
4223 .msg = try bundle.printString("use '--error-limit {d}' to increase limit", .{4135 .msg = try bundle.printString("use '--error-limit {d}' to increase limit", .{
4224 actual_error_count,4136 actual_error_count,
4225 }),4137 }),
...@@ -4241,10 +4153,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4241,10 +4153,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4241 .notes_len = 2,4153 .notes_len = 2,
4242 });4154 });
4243 const notes_start = try bundle.reserveNotes(2);4155 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(.{
4245 .msg = try bundle.addString("run 'zig libc -h' to learn about libc installations"),4157 .msg = try bundle.addString("run 'zig libc -h' to learn about libc installations"),
4246 }));4158 }));
4247 bundle.extra.items[notes_start + 1] = @intFromEnum(try bundle.addErrorMessage(.{4159 bundle.extra.items[notes_start + 1] = @intFromEnum(bundle.addErrorMessageAssumeCapacity(.{
4248 .msg = try bundle.addString("run 'zig targets' to see the targets for which zig can always provide libc"),4160 .msg = try bundle.addString("run 'zig targets' to see the targets for which zig can always provide libc"),
4249 }));4161 }));
4250 }4162 }
...@@ -4268,7 +4180,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4268,7 +4180,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4268 if (!refs.contains(logging_unit)) continue;4180 if (!refs.contains(logging_unit)) continue;
4269 try messages.append(gpa, .{4181 try messages.append(gpa, .{
4270 .src_loc = compile_log.src(),4182 .src_loc = compile_log.src(),
4271 .msg = undefined, // populated later4183 .msg = "", // populated later, but must be valid for `sort` call below
4272 .notes = &.{},4184 .notes = &.{},
4273 // We actually clear this later for most of these, but we populate4185 // We actually clear this later for most of these, but we populate
4274 // this field for now to avoid having to allocate more data to track4186 // 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 {...@@ -4281,33 +4193,11 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42814193
4282 // Okay, there *are* referenced compile logs. Sort them into a consistent order.4194 // Okay, there *are* referenced compile logs. Sort them into a consistent order.
42834195
4284 {4196 std.mem.sort(Zcu.ErrorMsg, messages.items, zcu, struct {
4285 const SortContext = struct {4197 fn lessThan(zcu_inner: *Zcu, lhs: Zcu.ErrorMsg, rhs: Zcu.ErrorMsg) bool {
4286 zcu: *Zcu,4198 return Zcu.ErrorMsg.order(&lhs, &rhs, zcu_inner).compare(.lt);
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 "";
4309 }4199 }
4310 }4200 }.lessThan);
43114201
4312 var log_text: std.ArrayList(u8) = .empty;4202 var log_text: std.ArrayList(u8) = .empty;
4313 defer log_text.deinit(gpa);4203 defer log_text.deinit(gpa);
...@@ -4331,6 +4221,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4331,6 +4221,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
43314221
4332 break :compile_log_text try log_text.toOwnedSlice(gpa);4222 break :compile_log_text try log_text.toOwnedSlice(gpa);
4333 };4223 };
4224 defer gpa.free(compile_log_text);
43344225
4335 // TODO: eventually, this should be behind `std.debug.runtime_safety`. But right now, this is a4226 // TODO: eventually, this should be behind `std.debug.runtime_safety`. But right now, this is a
4336 // very common way for incremental compilation bugs to manifest, so let's always check it.4227 // very common way for incremental compilation bugs to manifest, so let's always check it.
...@@ -4439,7 +4330,6 @@ pub fn addModuleErrorMsg(...@@ -4439,7 +4330,6 @@ pub fn addModuleErrorMsg(
4439 already_added_error: bool,4330 already_added_error: bool,
4440) Allocator.Error!void {4331) Allocator.Error!void {
4441 const gpa = eb.gpa;4332 const gpa = eb.gpa;
4442 const ip = &zcu.intern_pool;
4443 const err_src_loc = module_err_msg.src_loc.upgrade(zcu);4333 const err_src_loc = module_err_msg.src_loc.upgrade(zcu);
4444 const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| {4334 const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| {
4445 return unableToLoadZcuFile(zcu, eb, err_src_loc.file_scope, err);4335 return unableToLoadZcuFile(zcu, eb, err_src_loc.file_scope, err);
...@@ -4452,66 +4342,12 @@ pub fn addModuleErrorMsg(...@@ -4452,66 +4342,12 @@ pub fn addModuleErrorMsg(
4452 var ref_traces: std.ArrayList(ErrorBundle.ReferenceTrace) = .empty;4342 var ref_traces: std.ArrayList(ErrorBundle.ReferenceTrace) = .empty;
4453 defer ref_traces.deinit(gpa);4343 defer ref_traces.deinit(gpa);
44544344
4455 rt: {4345 if (module_err_msg.reference_trace_root.unwrap()) |root| {
4456 const rt_root = module_err_msg.reference_trace_root.unwrap() orelse break :rt;4346 const frame_limit: u32 = zcu.comp.reference_trace orelse refs: {
4457 const max_references = zcu.comp.reference_trace orelse refs: {4347 if (already_added_error) break :refs 0;
4458 if (already_added_error) break :rt;
4459 break :refs default_reference_trace_len;4348 break :refs default_reference_trace_len;
4460 };4349 };
44614350 try zcu.populateReferenceTrace(root, frame_limit, eb, &ref_traces);
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 }
4515 }4351 }
45164352
4517 const src_loc = try eb.addSourceLocation(.{4353 const src_loc = try eb.addSourceLocation(.{
...@@ -4576,43 +4412,10 @@ pub fn addModuleErrorMsg(...@@ -4576,43 +4412,10 @@ pub fn addModuleErrorMsg(
4576 const notes_start = try eb.reserveNotes(notes_len);4412 const notes_start = try eb.reserveNotes(notes_len);
45774413
4578 for (notes_start.., notes.keys()) |i, note| {4414 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));
4580 }4416 }
4581}4417}
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
4616fn addWholeFileError(4419fn addWholeFileError(
4617 zcu: *Zcu,4420 zcu: *Zcu,
4618 eb: *ErrorBundle.Wip,4421 eb: *ErrorBundle.Wip,
...@@ -4669,13 +4472,7 @@ fn performAllTheWork(...@@ -4669,13 +4472,7 @@ fn performAllTheWork(
4669 comp: *Compilation,4472 comp: *Compilation,
4670 main_progress_node: std.Progress.Node,4473 main_progress_node: std.Progress.Node,
4671 update_arena: Allocator,4474 update_arena: Allocator,
4672) JobError!void {4475) (Allocator.Error || Io.Cancelable)!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
4679 const io = comp.io;4476 const io = comp.io;
46804477
4681 // This is awkward: we don't want to start the timer until later, but we won't want to stop it4478 // 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(...@@ -4708,216 +4505,32 @@ fn performAllTheWork(
4708 misc_group.async(io, workerDocsWasm, .{ comp, main_progress_node });4505 misc_group.async(io, workerDocsWasm, .{ comp, main_progress_node });
4709 }4506 }
47104507
4711 if (comp.zcu) |zcu| {4508 defer if (comp.zcu) |zcu| zcu.codegen_task_pool.cancel(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
4778 if (comp.zcu) |zcu| {4509 if (comp.zcu) |zcu| {
4779 const pt: Zcu.PerThread = .activate(zcu, .main);4510 const pt: Zcu.PerThread = .activate(zcu, .main);
4780 defer pt.deactivate();4511 defer {
47814512 pt.deactivate();
4782 const gpa = zcu.gpa;4513 // Regardless of errors, `comp.zcu` needs to update its generation number.
47834514 zcu.generation += 1;
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);
4886 }4515 }
4516 try pt.update(main_progress_node, &decl_work_timer);
4887 }4517 }
48884518
4889 if (comp.zcu != null) {4519 comp.link_queue.finishZcuQueue(comp);
4890 // Start the timer for the "decls" part of the pipeline (Sema, CodeGen, link).
4891 decl_work_timer = comp.startTimer();
4892 }
48934520
4894 work: while (true) {4521 // This has to happen after the main semantic analysis loop because it is possible for Sema to
4895 for (&comp.work_queues) |*work_queue| if (work_queue.popFront()) |job| {4522 // call `addLinkLib` and hence add more items to `comp.windows_libs`.
4896 try processOneJob(.main, comp, job);4523 for (comp.windows_libs.keys()[comp.windows_libs_num_done..]) |link_lib| {
4897 continue :work;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 );
4898 };4531 };
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;
4918 }4532 }
49194533 comp.windows_libs_num_done = @intCast(comp.windows_libs.count());
4920 comp.link_queue.finishZcuQueue(comp);
49214534
4922 // Main thread work is all done, now just wait for all async work.4535 // Main thread work is all done, now just wait for all async work.
4923 try misc_group.await(io);4536 try misc_group.await(io);
...@@ -5148,172 +4761,6 @@ fn dispatchPrelinkWork(comp: *Compilation, main_progress_node: std.Progress.Node...@@ -5148,172 +4761,6 @@ fn dispatchPrelinkWork(comp: *Compilation, main_progress_node: std.Progress.Node
5148 };4761 };
5149}4762}
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
5317fn createDepFile(comp: *Compilation, dep_file: []const u8, bin_file: Cache.Path) anyerror!void {4764fn createDepFile(comp: *Compilation, dep_file: []const u8, bin_file: Cache.Path) anyerror!void {
5318 const io = comp.io;4765 const io = comp.io;
53194766
...@@ -5641,112 +5088,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU...@@ -5641,112 +5088,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
5641 };5088 };
5642}5089}
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
5750pub fn obtainCObjectCacheManifest(5091pub fn obtainCObjectCacheManifest(
5751 comp: *const Compilation,5092 comp: *const Compilation,
5752 owner_mod: *Package.Module,5093 owner_mod: *Package.Module,
...@@ -8375,12 +7716,10 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -8375,12 +7716,10 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
8375 // If we haven't seen this library yet and we're targeting Windows, we need7716 // If we haven't seen this library yet and we're targeting Windows, we need
8376 // to queue up a work item to produce the DLL import library for this.7717 // to queue up a work item to produce the DLL import library for this.
8377 const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);7718 const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
8378 if (gop.found_existing) return;7719 if (!gop.found_existing) {
8379 {
8380 errdefer _ = comp.windows_libs.pop();7720 errdefer _ = comp.windows_libs.pop();
8381 gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);7721 gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
8382 }7722 }
8383 try comp.queueJob(.{ .windows_import_lib = gop.index });
8384}7723}
83857724
8386/// This decides the optimization mode for all zig-provided libraries, including7725/// 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...@@ -306,12 +306,8 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const
306 try w.print("[{d}] ", .{i});306 try w.print("[{d}] ", .{i});
307 switch (dependee) {307 switch (dependee) {
308 .src_hash, .namespace, .namespace_name, .zon_file, .embed_file => try w.print("{f}", .{zcu.fmtDependee(dependee)}),308 .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) }),309 .nav_val, .nav_ty => |nav| try w.print("{t} {d}", .{ dependee, @intFromEnum(nav) }),
310 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {310 .type_layout, .struct_defaults, .func_ies => |ip_index| try w.print("{t} {d}", .{ dependee, @intFromEnum(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 },
315 .memoized_state => |stage| try w.print("memoized_state {s}", .{@tagName(stage)}),311 .memoized_state => |stage| try w.print("memoized_state {s}", .{@tagName(stage)}),
316 }312 }
317 try w.writeByte('\n');313 try w.writeByte('\n');
...@@ -376,8 +372,10 @@ fn parseAnalUnit(str: []const u8) ?AnalUnit {...@@ -376,8 +372,10 @@ fn parseAnalUnit(str: []const u8) ?AnalUnit {
376 return .wrap(.{ .nav_val = @enumFromInt(parseIndex(idx_str) orelse return null) });372 return .wrap(.{ .nav_val = @enumFromInt(parseIndex(idx_str) orelse return null) });
377 } else if (std.mem.eql(u8, kind, "nav_ty")) {373 } else if (std.mem.eql(u8, kind, "nav_ty")) {
378 return .wrap(.{ .nav_ty = @enumFromInt(parseIndex(idx_str) orelse return null) });374 return .wrap(.{ .nav_ty = @enumFromInt(parseIndex(idx_str) orelse return null) });
379 } else if (std.mem.eql(u8, kind, "type")) {375 } else if (std.mem.eql(u8, kind, "type_layout")) {
380 return .wrap(.{ .type = @enumFromInt(parseIndex(idx_str) orelse return null) });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) });
381 } else if (std.mem.eql(u8, kind, "func")) {379 } else if (std.mem.eql(u8, kind, "func")) {
382 return .wrap(.{ .func = @enumFromInt(parseIndex(idx_str) orelse return null) });380 return .wrap(.{ .func = @enumFromInt(parseIndex(idx_str) orelse return null) });
383 } else if (std.mem.eql(u8, kind, "memoized_state")) {381 } else if (std.mem.eql(u8, kind, "memoized_state")) {
src/InternPool.zig+2670-2835
...@@ -17,6 +17,7 @@ const Hash = std.hash.Wyhash;...@@ -17,6 +17,7 @@ const Hash = std.hash.Wyhash;
17const Zir = std.zig.Zir;17const Zir = std.zig.Zir;
1818
19const Zcu = @import("Zcu.zig");19const Zcu = @import("Zcu.zig");
20const TypeClass = @import("Type.zig").Class;
2021
21/// One item per thread, indexed by `tid`, which is dense and unique per thread.22/// One item per thread, indexed by `tid`, which is dense and unique per thread.
22locals: []Local,23locals: []Local,
...@@ -47,11 +48,15 @@ nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index),...@@ -47,11 +48,15 @@ nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index),
47/// Dependencies on the type of a Nav.48/// Dependencies on the type of a Nav.
48/// Value is index into `dep_entries` of the first dependency on this Nav value.49/// Value is index into `dep_entries` of the first dependency on this Nav value.
49nav_ty_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index),50nav_ty_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index),
50/// Dependencies on an interned value, either:51/// Dependencies on a function's inferred error set. Key is the function body, not the IES.
51/// * a runtime function (invalidated when its IES changes)52/// Value is index into `dep_entries` of the first dependency on this function's IES.
52/// * a container type requiring resolution (invalidated when the type must be recreated at a new index)53func_ies_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index),
53/// Value is index into `dep_entries` of the first dependency on this interned value.54/// Dependencies on the resolved layout of a `struct`, `union`, or `enum` type.
54interned_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index),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),
55/// Dependencies on a ZON file. Triggered by `@import` of ZON.60/// Dependencies on a ZON file. Triggered by `@import` of ZON.
56/// Value is index into `dep_entries` of the first dependency on this ZON file.61/// Value is index into `dep_entries` of the first dependency on this ZON file.
57zon_file_deps: std.AutoArrayHashMapUnmanaged(FileIndex, DepEntry.Index),62zon_file_deps: std.AutoArrayHashMapUnmanaged(FileIndex, DepEntry.Index),
...@@ -104,7 +109,9 @@ pub const empty: InternPool = .{...@@ -104,7 +109,9 @@ pub const empty: InternPool = .{
104 .src_hash_deps = .empty,109 .src_hash_deps = .empty,
105 .nav_val_deps = .empty,110 .nav_val_deps = .empty,
106 .nav_ty_deps = .empty,111 .nav_ty_deps = .empty,
107 .interned_deps = .empty,112 .func_ies_deps = .empty,
113 .type_layout_deps = .empty,
114 .struct_defaults_deps = .empty,
108 .zon_file_deps = .empty,115 .zon_file_deps = .empty,
109 .embed_file_deps = .empty,116 .embed_file_deps = .empty,
110 .namespace_deps = .empty,117 .namespace_deps = .empty,
...@@ -415,7 +422,8 @@ pub const AnalUnit = packed struct(u64) {...@@ -415,7 +422,8 @@ pub const AnalUnit = packed struct(u64) {
415 @"comptime",422 @"comptime",
416 nav_val,423 nav_val,
417 nav_ty,424 nav_ty,
418 type,425 type_layout,
426 struct_defaults,
419 func,427 func,
420 memoized_state,428 memoized_state,
421 };429 };
...@@ -427,9 +435,10 @@ pub const AnalUnit = packed struct(u64) {...@@ -427,9 +435,10 @@ pub const AnalUnit = packed struct(u64) {
427 nav_val: Nav.Index,435 nav_val: Nav.Index,
428 /// This `AnalUnit` resolves the type of the given `Nav`.436 /// This `AnalUnit` resolves the type of the given `Nav`.
429 nav_ty: Nav.Index,437 nav_ty: Nav.Index,
430 /// This `AnalUnit` resolves the given `struct`/`union`/`enum` type.438 /// This `AnalUnit` resolves the layout of the given `struct`, `union`, or `enum` type.
431 /// Generated tag enums are never used here (they do not undergo type resolution).439 type_layout: InternPool.Index,
432 type: InternPool.Index,440 /// This `AnalUnit` resolves the default field values of the given `struct` type.
441 struct_defaults: InternPool.Index,
433 /// This `AnalUnit` analyzes the body of the given runtime function.442 /// This `AnalUnit` analyzes the body of the given runtime function.
434 func: InternPool.Index,443 func: InternPool.Index,
435 /// This `AnalUnit` resolves all state which is memoized in fields on `Zcu`.444 /// This `AnalUnit` resolves all state which is memoized in fields on `Zcu`.
...@@ -538,6 +547,8 @@ pub const Nav = struct {...@@ -538,6 +547,8 @@ pub const Nav = struct {
538 analysis: ?struct {547 analysis: ?struct {
539 namespace: NamespaceIndex,548 namespace: NamespaceIndex,
540 zir_index: TrackedInst.Index,549 zir_index: TrackedInst.Index,
550 /// Initially `false`. Set to `true` by `setWantNavAnalysis`.
551 wanted: bool,
541 },552 },
542 status: union(enum) {553 status: union(enum) {
543 /// This `Nav` is pending semantic analysis.554 /// This `Nav` is pending semantic analysis.
...@@ -735,7 +746,7 @@ pub const Nav = struct {...@@ -735,7 +746,7 @@ pub const Nav = struct {
735 const Repr = struct {746 const Repr = struct {
736 name: NullTerminatedString,747 name: NullTerminatedString,
737 fqn: NullTerminatedString,748 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`.
739 analysis_namespace: OptionalNamespaceIndex,750 analysis_namespace: OptionalNamespaceIndex,
740 analysis_zir_index: TrackedInst.Index.Optional,751 analysis_zir_index: TrackedInst.Index.Optional,
741 /// Populated only if `bits.status != .unresolved`.752 /// Populated only if `bits.status != .unresolved`.
...@@ -754,7 +765,7 @@ pub const Nav = struct {...@@ -754,7 +765,7 @@ pub const Nav = struct {
754 @"addrspace": std.builtin.AddressSpace,765 @"addrspace": std.builtin.AddressSpace,
755 /// Populated only if `bits.status == .type_resolved`.766 /// Populated only if `bits.status == .type_resolved`.
756 is_threadlocal: bool,767 is_threadlocal: bool,
757 _: u1 = 0,768 want_analysis: bool,
758 };769 };
759770
760 fn unpack(repr: Repr) Nav {771 fn unpack(repr: Repr) Nav {
...@@ -764,6 +775,7 @@ pub const Nav = struct {...@@ -764,6 +775,7 @@ pub const Nav = struct {
764 .analysis = if (repr.analysis_namespace.unwrap()) |namespace| .{775 .analysis = if (repr.analysis_namespace.unwrap()) |namespace| .{
765 .namespace = namespace,776 .namespace = namespace,
766 .zir_index = repr.analysis_zir_index.unwrap().?,777 .zir_index = repr.analysis_zir_index.unwrap().?,
778 .wanted = repr.bits.want_analysis,
767 } else a: {779 } else a: {
768 assert(repr.analysis_zir_index == .none);780 assert(repr.analysis_zir_index == .none);
769 break :a null;781 break :a null;
...@@ -816,6 +828,7 @@ pub const Nav = struct {...@@ -816,6 +828,7 @@ pub const Nav = struct {
816 .alignment = .none,828 .alignment = .none,
817 .@"addrspace" = .generic,829 .@"addrspace" = .generic,
818 .is_threadlocal = false,830 .is_threadlocal = false,
831 .want_analysis = if (nav.analysis) |a| a.wanted else false,
819 },832 },
820 .type_resolved => |r| .{833 .type_resolved => |r| .{
821 .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved,834 .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved,
...@@ -823,6 +836,7 @@ pub const Nav = struct {...@@ -823,6 +836,7 @@ pub const Nav = struct {
823 .alignment = r.alignment,836 .alignment = r.alignment,
824 .@"addrspace" = r.@"addrspace",837 .@"addrspace" = r.@"addrspace",
825 .is_threadlocal = r.is_threadlocal,838 .is_threadlocal = r.is_threadlocal,
839 .want_analysis = if (nav.analysis) |a| a.wanted else false,
826 },840 },
827 .fully_resolved => |r| .{841 .fully_resolved => |r| .{
828 .status = .fully_resolved,842 .status = .fully_resolved,
...@@ -830,6 +844,7 @@ pub const Nav = struct {...@@ -830,6 +844,7 @@ pub const Nav = struct {
830 .alignment = r.alignment,844 .alignment = r.alignment,
831 .@"addrspace" = r.@"addrspace",845 .@"addrspace" = r.@"addrspace",
832 .is_threadlocal = false,846 .is_threadlocal = false,
847 .want_analysis = if (nav.analysis) |a| a.wanted else false,
833 },848 },
834 },849 },
835 };850 };
...@@ -840,7 +855,10 @@ pub const Dependee = union(enum) {...@@ -840,7 +855,10 @@ pub const Dependee = union(enum) {
840 src_hash: TrackedInst.Index,855 src_hash: TrackedInst.Index,
841 nav_val: Nav.Index,856 nav_val: Nav.Index,
842 nav_ty: Nav.Index,857 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,
844 zon_file: FileIndex,862 zon_file: FileIndex,
845 embed_file: Zcu.EmbedFile.Index,863 embed_file: Zcu.EmbedFile.Index,
846 namespace: TrackedInst.Index,864 namespace: TrackedInst.Index,
...@@ -892,7 +910,9 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI...@@ -892,7 +910,9 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI
892 .src_hash => |x| ip.src_hash_deps.get(x),910 .src_hash => |x| ip.src_hash_deps.get(x),
893 .nav_val => |x| ip.nav_val_deps.get(x),911 .nav_val => |x| ip.nav_val_deps.get(x),
894 .nav_ty => |x| ip.nav_ty_deps.get(x),912 .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),
896 .zon_file => |x| ip.zon_file_deps.get(x),916 .zon_file => |x| ip.zon_file_deps.get(x),
897 .embed_file => |x| ip.embed_file_deps.get(x),917 .embed_file => |x| ip.embed_file_deps.get(x),
898 .namespace => |x| ip.namespace_deps.get(x),918 .namespace => |x| ip.namespace_deps.get(x),
...@@ -965,7 +985,9 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend...@@ -965,7 +985,9 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
965 .src_hash => ip.src_hash_deps,985 .src_hash => ip.src_hash_deps,
966 .nav_val => ip.nav_val_deps,986 .nav_val => ip.nav_val_deps,
967 .nav_ty => ip.nav_ty_deps,987 .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,
969 .zon_file => ip.zon_file_deps,991 .zon_file => ip.zon_file_deps,
970 .embed_file => ip.embed_file_deps,992 .embed_file => ip.embed_file_deps,
971 .namespace => ip.namespace_deps,993 .namespace => ip.namespace_deps,
...@@ -2065,15 +2087,15 @@ pub const Key = union(enum) {...@@ -2065,15 +2087,15 @@ pub const Key = union(enum) {
2065 simple_type: SimpleType,2087 simple_type: SimpleType,
2066 /// This represents a struct that has been explicitly declared in source code,2088 /// This represents a struct that has been explicitly declared in source code,
2067 /// or was created with `@Struct`. It is unique and based on a declaration.2089 /// or was created with `@Struct`. It is unique and based on a declaration.
2068 struct_type: NamespaceType,2090 struct_type: ContainerType,
2069 /// This is a tuple type. Tuples are logically similar to structs, but have some2091 /// This is a tuple type. Tuples are logically similar to structs, but have some
2070 /// important differences in semantics; they do not undergo staged type resolution,2092 /// important differences in semantics; they do not undergo staged type resolution,
2071 /// so cannot be self-referential, and they are not considered container/namespace2093 /// so cannot be self-referential, and they are not considered container/namespace
2072 /// types, so cannot have declarations and have structural equality properties.2094 /// types, so cannot have declarations and have structural equality properties.
2073 tuple_type: TupleType,2095 tuple_type: TupleType,
2074 union_type: NamespaceType,2096 union_type: ContainerType,
2075 opaque_type: NamespaceType,2097 opaque_type: ContainerType,
2076 enum_type: NamespaceType,2098 enum_type: ContainerType,
2077 func_type: FuncType,2099 func_type: FuncType,
2078 error_set_type: ErrorSetType,2100 error_set_type: ErrorSetType,
2079 /// The payload is the function body, either a `func_decl` or `func_instance`.2101 /// The payload is the function body, either a `func_decl` or `func_instance`.
...@@ -2092,10 +2114,6 @@ pub const Key = union(enum) {...@@ -2092,10 +2114,6 @@ pub const Key = union(enum) {
2092 enum_literal: NullTerminatedString,2114 enum_literal: NullTerminatedString,
2093 /// A specific enum tag, indicated by the integer tag value.2115 /// A specific enum tag, indicated by the integer tag value.
2094 enum_tag: EnumTag,2116 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,
2099 float: Float,2117 float: Float,
2100 ptr: Ptr,2118 ptr: Ptr,
2101 slice: Slice,2119 slice: Slice,
...@@ -2109,6 +2127,8 @@ pub const Key = union(enum) {...@@ -2109,6 +2127,8 @@ pub const Key = union(enum) {
2109 aggregate: Aggregate,2127 aggregate: Aggregate,
2110 /// An instance of a union.2128 /// An instance of a union.
2111 un: Union,2129 un: Union,
2130 /// An instance of a `packed struct` or `packed union`.
2131 bitpack: Bitpack,
21122132
2113 /// A comptime function call with a memoized result.2133 /// A comptime function call with a memoized result.
2114 memoized_call: Key.MemoizedCall,2134 memoized_call: Key.MemoizedCall,
...@@ -2211,16 +2231,10 @@ pub const Key = union(enum) {...@@ -2211,16 +2231,10 @@ pub const Key = union(enum) {
2211 /// * `loadUnionType`2231 /// * `loadUnionType`
2212 /// * `loadEnumType`2232 /// * `loadEnumType`
2213 /// * `loadOpaqueType`2233 /// * `loadOpaqueType`
2214 pub const NamespaceType = union(enum) {2234 pub const ContainerType = union(enum) {
2215 /// This type corresponds to an actual source declaration, e.g. `struct { ... }`.2235 /// This type corresponds to an actual source declaration, e.g. `struct { ... }`.
2216 /// It is hashed based on its ZIR instruction index and set of captures.2236 /// It is hashed based on its ZIR instruction index and set of captures.
2217 declared: Declared,2237 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 },
2224 /// This type originates from a reification via `@Enum`, `@Struct`, `@Union` or from an anonymous initialization.2238 /// This type originates from a reification via `@Enum`, `@Struct`, `@Union` or from an anonymous initialization.
2225 /// It is hashed based on its ZIR instruction index and fields, attributes, etc.2239 /// It is hashed based on its ZIR instruction index and fields, attributes, etc.
2226 /// To avoid making this key overly complex, the type-specific data is hashed by Sema.2240 /// To avoid making this key overly complex, the type-specific data is hashed by Sema.
...@@ -2231,6 +2245,9 @@ pub const Key = union(enum) {...@@ -2231,6 +2245,9 @@ pub const Key = union(enum) {
2231 /// A hash of this type's attributes, fields, etc, generated by Sema.2245 /// A hash of this type's attributes, fields, etc, generated by Sema.
2232 type_hash: u64,2246 type_hash: u64,
2233 },2247 },
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
2235 pub const Declared = struct {2252 pub const Declared = struct {
2236 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.2253 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
...@@ -2254,7 +2271,6 @@ pub const Key = union(enum) {...@@ -2254,7 +2271,6 @@ pub const Key = union(enum) {
2254 noalias_bits: u32,2271 noalias_bits: u32,
2255 cc: std.builtin.CallingConvention,2272 cc: std.builtin.CallingConvention,
2256 is_var_args: bool,2273 is_var_args: bool,
2257 is_generic: bool,
2258 is_noinline: bool,2274 is_noinline: bool,
22592275
2260 pub fn paramIsComptime(self: @This(), i: u5) bool {2276 pub fn paramIsComptime(self: @This(), i: u5) bool {
...@@ -2273,7 +2289,6 @@ pub const Key = union(enum) {...@@ -2273,7 +2289,6 @@ pub const Key = union(enum) {
2273 a.comptime_bits == b.comptime_bits and2289 a.comptime_bits == b.comptime_bits and
2274 a.noalias_bits == b.noalias_bits and2290 a.noalias_bits == b.noalias_bits and
2275 a.is_var_args == b.is_var_args and2291 a.is_var_args == b.is_var_args and
2276 a.is_generic == b.is_generic and
2277 a.is_noinline == b.is_noinline and2292 a.is_noinline == b.is_noinline and
2278 std.meta.eql(a.cc, b.cc);2293 std.meta.eql(a.cc, b.cc);
2279 }2294 }
...@@ -2287,7 +2302,6 @@ pub const Key = union(enum) {...@@ -2287,7 +2302,6 @@ pub const Key = union(enum) {
2287 std.hash.autoHash(hasher, self.noalias_bits);2302 std.hash.autoHash(hasher, self.noalias_bits);
2288 std.hash.autoHash(hasher, self.cc);2303 std.hash.autoHash(hasher, self.cc);
2289 std.hash.autoHash(hasher, self.is_var_args);2304 std.hash.autoHash(hasher, self.is_var_args);
2290 std.hash.autoHash(hasher, self.is_generic);
2291 std.hash.autoHash(hasher, self.is_noinline);2305 std.hash.autoHash(hasher, self.is_noinline);
2292 }2306 }
2293 };2307 };
...@@ -2403,17 +2417,6 @@ pub const Key = union(enum) {...@@ -2403,17 +2417,6 @@ pub const Key = union(enum) {
2403 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);2417 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
2404 }2418 }
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
2417 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.2420 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
2418 fn zirBodyInstPtr(func: Func, ip: *const InternPool) *TrackedInst.Index {2421 fn zirBodyInstPtr(func: Func, ip: *const InternPool) *TrackedInst.Index {
2419 const extra = ip.getLocalShared(func.tid).extra.acquire();2422 const extra = ip.getLocalShared(func.tid).extra.acquire();
...@@ -2471,8 +2474,6 @@ pub const Key = union(enum) {...@@ -2471,8 +2474,6 @@ pub const Key = union(enum) {
2471 u64: u64,2474 u64: u64,
2472 i64: i64,2475 i64: i64,
2473 big_int: BigIntConst,2476 big_int: BigIntConst,
2474 lazy_align: Index,
2475 lazy_size: Index,
24762477
2477 /// Big enough to fit any non-BigInt value2478 /// Big enough to fit any non-BigInt value
2478 pub const BigIntSpace = struct {2479 pub const BigIntSpace = struct {
...@@ -2485,7 +2486,6 @@ pub const Key = union(enum) {...@@ -2485,7 +2486,6 @@ pub const Key = union(enum) {
2485 return switch (storage) {2486 return switch (storage) {
2486 .big_int => |x| x,2487 .big_int => |x| x,
2487 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),2488 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),
2488 .lazy_align, .lazy_size => unreachable,
2489 };2489 };
2490 }2490 }
2491 };2491 };
...@@ -2680,6 +2680,15 @@ pub const Key = union(enum) {...@@ -2680,6 +2680,15 @@ pub const Key = union(enum) {
2680 };2680 };
2681 };2681 };
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
2683 pub const MemoizedCall = struct {2692 pub const MemoizedCall = struct {
2684 func: Index,2693 func: Index,
2685 arg_values: []const Index,2694 arg_values: []const Index,
...@@ -2710,7 +2719,6 @@ pub const Key = union(enum) {...@@ -2710,7 +2719,6 @@ pub const Key = union(enum) {
2710 .err,2719 .err,
2711 .enum_literal,2720 .enum_literal,
2712 .enum_tag,2721 .enum_tag,
2713 .empty_enum_value,
2714 .inferred_error_set_type,2722 .inferred_error_set_type,
2715 .un,2723 .un,
2716 => |x| Hash.hash(seed, asBytes(&x)),2724 => |x| Hash.hash(seed, asBytes(&x)),
...@@ -2742,13 +2750,13 @@ pub const Key = union(enum) {...@@ -2742,13 +2750,13 @@ pub const Key = union(enum) {
2742 std.hash.autoHash(&hasher, cv);2750 std.hash.autoHash(&hasher, cv);
2743 }2751 }
2744 },2752 },
2745 .generated_tag => |generated_tag| {
2746 std.hash.autoHash(&hasher, generated_tag.union_type);
2747 },
2748 .reified => |reified| {2753 .reified => |reified| {
2749 std.hash.autoHash(&hasher, reified.zir_index);2754 std.hash.autoHash(&hasher, reified.zir_index);
2750 std.hash.autoHash(&hasher, reified.type_hash);2755 std.hash.autoHash(&hasher, reified.type_hash);
2751 },2756 },
2757 .generated_union_tag => |union_type| {
2758 std.hash.autoHash(&hasher, union_type);
2759 },
2752 }2760 }
2753 return hasher.final();2761 return hasher.final();
2754 },2762 },
...@@ -2756,23 +2764,12 @@ pub const Key = union(enum) {...@@ -2756,23 +2764,12 @@ pub const Key = union(enum) {
2756 .int => |int| {2764 .int => |int| {
2757 var hasher = Hash.init(seed);2765 var hasher = Hash.init(seed);
2758 // Canonicalize all integers by converting them to BigIntConst.2766 // Canonicalize all integers by converting them to BigIntConst.
2759 switch (int.storage) {2767 var buffer: Key.Int.Storage.BigIntSpace = undefined;
2760 .u64, .i64, .big_int => {2768 const big_int = int.storage.toBigInt(&buffer);
2761 var buffer: Key.Int.Storage.BigIntSpace = undefined;2769
2762 const big_int = int.storage.toBigInt(&buffer);2770 std.hash.autoHash(&hasher, int.ty);
27632771 std.hash.autoHash(&hasher, big_int.positive);
2764 std.hash.autoHash(&hasher, int.ty);2772 for (big_int.limbs) |limb| std.hash.autoHash(&hasher, limb);
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 }
2776 return hasher.final();2773 return hasher.final();
2777 },2774 },
27782775
...@@ -2929,6 +2926,8 @@ pub const Key = union(enum) {...@@ -2929,6 +2926,8 @@ pub const Key = union(enum) {
2929 asBytes(&e.relocation) ++2926 asBytes(&e.relocation) ++
2930 asBytes(&e.is_const) ++ asBytes(&e.alignment) ++ asBytes(&e.@"addrspace") ++2927 asBytes(&e.is_const) ++ asBytes(&e.alignment) ++ asBytes(&e.@"addrspace") ++
2931 asBytes(&e.zir_index) ++ &[1]u8{@intFromEnum(e.source)}),2928 asBytes(&e.zir_index) ++ &[1]u8{@intFromEnum(e.source)}),
2929
2930 .bitpack => |bitpack| Hash.hash(seed, asBytes(&bitpack.ty) ++ asBytes(&bitpack.backing_int_val)),
2932 };2931 };
2933 }2932 }
29342933
...@@ -3002,9 +3001,9 @@ pub const Key = union(enum) {...@@ -3002,9 +3001,9 @@ pub const Key = union(enum) {
3002 const b_info = b.enum_tag;3001 const b_info = b.enum_tag;
3003 return std.meta.eql(a_info, b_info);3002 return std.meta.eql(a_info, b_info);
3004 },3003 },
3005 .empty_enum_value => |a_info| {3004 .bitpack => |a_info| {
3006 const b_info = b.empty_enum_value;3005 const b_info = b.bitpack;
3007 return a_info == b_info;3006 return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val;
3008 },3007 },
30093008
3010 .variable => |a_info| {3009 .variable => |a_info| {
...@@ -3102,27 +3101,16 @@ pub const Key = union(enum) {...@@ -3102,27 +3101,16 @@ pub const Key = union(enum) {
3102 .u64 => |bb| aa == bb,3101 .u64 => |bb| aa == bb,
3103 .i64 => |bb| aa == bb,3102 .i64 => |bb| aa == bb,
3104 .big_int => |bb| bb.orderAgainstScalar(aa) == .eq,3103 .big_int => |bb| bb.orderAgainstScalar(aa) == .eq,
3105 .lazy_align, .lazy_size => false,
3106 },3104 },
3107 .i64 => |aa| switch (b_info.storage) {3105 .i64 => |aa| switch (b_info.storage) {
3108 .u64 => |bb| aa == bb,3106 .u64 => |bb| aa == bb,
3109 .i64 => |bb| aa == bb,3107 .i64 => |bb| aa == bb,
3110 .big_int => |bb| bb.orderAgainstScalar(aa) == .eq,3108 .big_int => |bb| bb.orderAgainstScalar(aa) == .eq,
3111 .lazy_align, .lazy_size => false,
3112 },3109 },
3113 .big_int => |aa| switch (b_info.storage) {3110 .big_int => |aa| switch (b_info.storage) {
3114 .u64 => |bb| aa.orderAgainstScalar(bb) == .eq,3111 .u64 => |bb| aa.orderAgainstScalar(bb) == .eq,
3115 .i64 => |bb| aa.orderAgainstScalar(bb) == .eq,3112 .i64 => |bb| aa.orderAgainstScalar(bb) == .eq,
3116 .big_int => |bb| aa.eql(bb),3113 .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,
3126 },3114 },
3127 };3115 };
3128 },3116 },
...@@ -3175,12 +3163,12 @@ pub const Key = union(enum) {...@@ -3175,12 +3163,12 @@ pub const Key = union(enum) {
3175 };3163 };
3176 return std.mem.eql(u32, @ptrCast(a_captures), @ptrCast(b_captures));3164 return std.mem.eql(u32, @ptrCast(a_captures), @ptrCast(b_captures));
3177 },3165 },
3178 .generated_tag => |a_gt| return a_gt.union_type == b_info.generated_tag.union_type,
3179 .reified => |a_r| {3166 .reified => |a_r| {
3180 const b_r = b_info.reified;3167 const b_r = b_info.reified;
3181 return a_r.zir_index == b_r.zir_index and3168 return a_r.zir_index == b_r.zir_index and
3182 a_r.type_hash == b_r.type_hash;3169 a_r.type_hash == b_r.type_hash;
3183 },3170 },
3171 .generated_union_tag => |a_union_ty| return a_union_ty == b_info.generated_union_tag,
3184 }3172 }
3185 },3173 },
3186 .aggregate => |a_info| {3174 .aggregate => |a_info| {
...@@ -3292,19 +3280,17 @@ pub const Key = union(enum) {...@@ -3292,19 +3280,17 @@ pub const Key = union(enum) {
3292 .enum_tag,3280 .enum_tag,
3293 .aggregate,3281 .aggregate,
3294 .un,3282 .un,
3283 .bitpack,
3295 => |x| x.ty,3284 => |x| x.ty,
32963285
3297 .enum_literal => .enum_literal_type,3286 .enum_literal => .enum_literal_type,
32983287
3299 .undef => |x| x,3288 .undef => |x| x,
3300 .empty_enum_value => |x| x,
33013289
3302 .simple_value => |s| switch (s) {3290 .simple_value => |s| switch (s) {
3303 .undefined => .undefined_type,
3304 .void => .void_type,3291 .void => .void_type,
3305 .null => .null_type,3292 .null => .null_type,
3306 .false, .true => .bool_type,3293 .false, .true => .bool_type,
3307 .empty_tuple => .empty_tuple_type,
3308 .@"unreachable" => .noreturn_type,3294 .@"unreachable" => .noreturn_type,
3309 },3295 },
33103296
...@@ -3313,374 +3299,53 @@ pub const Key = union(enum) {...@@ -3313,374 +3299,53 @@ pub const Key = union(enum) {
3313 }3299 }
3314};3300};
33153301
3316pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };3302pub const LoadedStructType = struct {
33173303 /// Index of the `struct_decl` or `reify` ZIR instruction.
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.
3343 zir_index: TrackedInst.Index,3304 zir_index: TrackedInst.Index,
3344 captures: CaptureValue.Slice,3305 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,
3665 // TODO: the non-fqn will be needed by the new dwarf structure3308 // TODO: the non-fqn will be needed by the new dwarf structure
3666 /// The name of this struct type.3309 /// The name of this struct type.
3667 name: NullTerminatedString,3310 name: NullTerminatedString,
3668 namespace: NamespaceIndex,
3669 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.3311 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3670 /// Otherwise, or if this is a file's root struct type, this is `.none`.3312 /// Otherwise, or if this is a file's root struct type, this is `.none`.
3671 name_nav: Nav.Index.Optional,3313 name_nav: Nav.Index.Optional,
3672 /// Index of the `struct_decl` or `reify` ZIR instruction.3314 namespace: NamespaceIndex,
3673 zir_index: TrackedInst.Index,3315
3674 layout: std.builtin.Type.ContainerLayout,3316 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,
3675 field_names: NullTerminatedString.Slice,3332 field_names: NullTerminatedString.Slice,
3676 field_types: Index.Slice,3333 field_types: Index.Slice,
3677 field_inits: Index.Slice,3334 field_defaults: Index.Slice,
3678 field_aligns: Alignment.Slice,3335 field_aligns: Alignment.Slice,
3679 runtime_order: RuntimeOrder.Slice,3336 field_is_comptime_bits: ComptimeBits,
3680 comptime_bits: ComptimeBits,3337 /// If `layout` is `.@"packed"`, this is `.empty`.
3681 offsets: Offsets,3338 field_runtime_order: RuntimeOrder.Slice,
3682 names_map: OptionalMapIndex,3339 /// If `layout` is `.@"packed"`, this is `.empty`.
3683 captures: CaptureValue.Slice,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
3685 pub const ComptimeBits = struct {3350 pub const ComptimeBits = struct {
3686 tid: Zcu.PerThread.Id,3351 tid: Zcu.PerThread.Id,
...@@ -3690,22 +3355,14 @@ pub const LoadedStructType = struct {...@@ -3690,22 +3355,14 @@ pub const LoadedStructType = struct {
36903355
3691 pub const empty: ComptimeBits = .{ .tid = .main, .start = 0, .len = 0 };3356 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 {
3694 const extra = ip.getLocalShared(this.tid).extra.acquire();3359 const extra = ip.getLocalShared(this.tid).extra.acquire();
3695 return extra.view().items(.@"0")[this.start..][0..this.len];3360 return extra.view().items(.@"0")[this.start..][0..this.len];
3696 }3361 }
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 {
3699 if (this.len == 0) return false;3364 if (this.len == 0) return false;
3700 return @as(u1, @truncate(this.get(ip)[i / 32] >> @intCast(i % 32))) != 0;3365 return @as(u1, @truncate(this.getAll(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));
3709 }3366 }
3710 };3367 };
37113368
...@@ -3753,865 +3410,602 @@ pub const LoadedStructType = struct {...@@ -3753,865 +3410,602 @@ pub const LoadedStructType = struct {
37533410
3754 /// Look up field index based on field name.3411 /// Look up field index based on field name.
3755 pub fn nameIndex(s: LoadedStructType, ip: *const InternPool, name: NullTerminatedString) ?u32 {3412 pub fn nameIndex(s: LoadedStructType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
3756 const names_map = s.names_map.unwrap() orelse {3413 const map = s.field_name_map.get(ip);
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);
3762 const adapter: NullTerminatedString.Adapter = .{ .strings = s.field_names.get(ip) };3414 const adapter: NullTerminatedString.Adapter = .{ .strings = s.field_names.get(ip) };
3763 const field_index = map.getIndexAdapted(name, adapter) orelse return null;3415 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
3764 return @intCast(field_index);3416 return @intCast(field_index);
3765 }3417 }
37663418
3767 /// Returns the already-existing field with the same name, if any.3419 /// Iterates over non-comptime fields in the order they are laid out in memory at runtime.
3768 pub fn addFieldName(3420 /// May or may not include zero-bit fields.
3769 s: LoadedStructType,3421 /// Asserts the struct is not packed.
3770 ip: *InternPool,3422 pub fn iterateRuntimeOrder(s: *const LoadedStructType, ip: *const InternPool) RuntimeOrderIterator {
3771 name: NullTerminatedString,3423 switch (s.layout) {
3772 ) ?u32 {3424 .auto => {
3773 const extra = ip.getLocalShared(s.tid).extra.acquire();3425 const ro = std.mem.sliceTo(s.field_runtime_order.get(ip), .omitted);
3774 return ip.addFieldName(extra, s.names_map.unwrap().?, s.field_names.start, name);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 }
3775 }3439 }
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 {3453 pub fn iterateRuntimeOrderReverse(s: *const LoadedStructType, ip: *InternPool) ReverseRuntimeOrderIterator {
3778 if (s.field_aligns.len == 0) return .none;3454 switch (s.layout) {
3779 return s.field_aligns.get(ip)[i];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 }
3780 }3468 }
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 {3482/// Unlike `Tag.TypeUnion` which is an encoding, and `Key.UnionType` which is a
3783 if (s.field_inits.len == 0) return .none;3483/// minimal hashmap key, this type is a convenience type that contains info
3784 assert(s.haveFieldInits(ip));3484/// needed by semantic analysis.
3785 return s.field_inits.get(ip)[i];3485pub const LoadedUnionType = struct {
3786 }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 {3491 // TODO: the non-fqn will be needed by the new dwarf structure
3789 return s.field_names.get(ip)[i];3492 /// The name of this union type.
3790 }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 {3499 layout: std.builtin.Type.ContainerLayout,
3793 return s.comptime_bits.getBit(ip, i);3500 enum_tag_mode: BackingTypeMode,
3794 }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 {3519 // The remaining fields are only valid once the union's layout is resolved.
3797 s.comptime_bits.setBit(ip, i);3520 field_types: Index.Slice,
3798 }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`.3549pub const LoadedEnumType = struct {
3801 /// Asserts the struct is not packed.3550 /// This is `none` iff this is a generated tag type.
3802 fn flagsPtr(s: LoadedStructType, ip: *const InternPool) *Tag.TypeStruct.Flags {3551 /// Otherwise, index of the `enum_decl` or `reify` ZIR instruction.
3803 assert(s.layout != .@"packed");3552 zir_index: TrackedInst.Index.Optional,
3804 const extra = ip.getLocalShared(s.tid).extra.acquire();3553 captures: CaptureValue.Slice,
3805 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;3554 /// If `zir_index` is `.none`, this is the union type for which this enum is the tag type.
3806 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + flags_field_index]);3555 owner_union: Index,
3807 }3556 is_reified: bool,
38083557
3809 pub fn flagsUnordered(s: LoadedStructType, ip: *const InternPool) Tag.TypeStruct.Flags {3558 // TODO: the non-fqn will be needed by the new dwarf structure
3810 return @atomicLoad(Tag.TypeStruct.Flags, s.flagsPtr(ip), .unordered);3559 /// The name of this enum type.
3811 }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`.3566 int_tag_mode: BackingTypeMode,
3814 /// Asserts that the struct is packed.3567 nonexhaustive: bool,
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 }
38213568
3822 pub fn packedFlagsUnordered(s: LoadedStructType, ip: *const InternPool) Tag.TypeStructPacked.Flags {3569 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3823 return @atomicLoad(Tag.TypeStructPacked.Flags, s.packedFlagsPtr(ip), .unordered);3570 /// layout is encountered, after which it is never reset to `false`, even across incremental
3824 }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 more3579 // The remaining fields are only valid once the enum's layout is resolved.
3827 /// complicated logic.3580 int_tag_type: Index,
3828 pub fn knownNonOpv(s: LoadedStructType, ip: *const InternPool) bool {3581 field_name_map: MapIndex,
3829 return switch (s.layout) {3582 field_names: NullTerminatedString.Slice,
3830 .@"packed" => false,3583 field_value_map: OptionalMapIndex,
3831 .auto, .@"extern" => s.flagsUnordered(ip).known_non_opv,3584 field_values: Index.Slice,
3832 };
3833 }
38343585
3835 pub fn requiresComptime(s: LoadedStructType, ip: *const InternPool) RequiresComptime {3586 /// Look up field index based on field name.
3836 return s.flagsUnordered(ip).requires_comptime;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);
3837 }3592 }
38383593
3839 pub fn setRequiresComptimeWip(s: LoadedStructType, ip: *InternPool, io: Io) RequiresComptime {3594 /// Look up field index based on integer tag value.
3840 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;3595 /// Asserts that the type of `tag_val` is `enum_obj.int_tag_type`.
3841 extra_mutex.lockUncancelable(io);3596 /// Asserts that `tag_val` is not `undefined`.
3842 defer extra_mutex.unlock(io);3597 pub fn tagValueIndex(e: LoadedEnumType, ip: *const InternPool, tag_val: Index) ?u32 {
38433598 assert(ip.typeOf(tag_val) == e.int_tag_type);
3844 const flags_ptr = s.flagsPtr(ip);3599 assert(ip.indexToKey(tag_val) == .int);
3845 var flags = flags_ptr.*;3600 if (e.field_value_map.unwrap()) |field_value_map| {
3846 defer if (flags.requires_comptime == .unknown) {3601 const map = field_value_map.get(ip);
3847 flags.requires_comptime = .wip;3602 const adapter: Index.Adapter = .{ .indexes = e.field_values.get(ip) };
3848 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);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,
3849 };3610 };
3850 return flags.requires_comptime;3611 return if (field_index < e.field_names.len) field_index else null;
3851 }3612 }
3613};
38523614
3853 pub fn setRequiresComptime(s: LoadedStructType, ip: *InternPool, io: Io, requires_comptime: RequiresComptime) void {3615pub const LoadedOpaqueType = struct {
3854 assert(requires_comptime != .wip); // see setRequiresComptimeWip3616 /// 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;3620 // TODO: the non-fqn will be needed by the new dwarf structure
3857 extra_mutex.lockUncancelable(io);3621 /// The name of this opaque type.
3858 defer extra_mutex.unlock(io);3622 name: NullTerminatedString,
38593623 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3860 const flags_ptr = s.flagsPtr(ip);3624 /// Otherwise, this is `.none`.
3861 var flags = flags_ptr.*;3625 name_nav: Nav.Index.Optional,
3862 flags.requires_comptime = requires_comptime;3626 namespace: NamespaceIndex,
3863 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);3627};
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};
42503628
4251pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {3629pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4252 const unwrapped_index = index.unwrap(ip);3630 const unwrapped_index = index.unwrap(ip);
4253 const extra_list = unwrapped_index.getExtra(ip);3631 const extra_list = unwrapped_index.getExtra(ip);
4254 const extra_items = extra_list.view().items(.@"0");3632 const extra_items = extra_list.view().items(.@"0");
4255 const item = unwrapped_index.getItem(ip);3633 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 },
4257 .type_struct => {3640 .type_struct => {
4258 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);3641 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);
4259 const name_nav: Nav.Index.Optional = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?]);3642 var extra_index = extra.end;
4260 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);3643 const captures: CaptureValue.Slice = switch (extra.data.flags.any_captures) {
4261 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);3644 .reified => captures: {
4262 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];3645 extra_index += 2; // type_hash: PackedU64
4263 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));3646 break :captures .empty;
4264 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).@"struct".fields.len);3647 },
4265 const captures_len = if (flags.any_captures) c: {3648 .false => .empty,
4266 const len = extra_list.view().items(.@"0")[extra_index];3649 .true => captures: {
4267 extra_index += 1;3650 const len = extra_items[extra_index];
4268 break :c len;3651 extra_index += 1;
4269 } else 0;3652 break :captures .{
4270 const captures: CaptureValue.Slice = .{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 = .{
4271 .tid = unwrapped_index.tid,3661 .tid = unwrapped_index.tid,
4272 .start = extra_index,3662 .start = extra_index,
4273 .len = captures_len,3663 .len = extra.data.fields_len,
4274 };3664 };
4275 extra_index += captures_len;3665 extra_index += field_names.len;
4276 if (flags.is_reified) {
4277 extra_index += 2; // type_hash: PackedU64
4278 }
4279 const field_types: Index.Slice = .{3666 const field_types: Index.Slice = .{
4280 .tid = unwrapped_index.tid,3667 .tid = unwrapped_index.tid,
4281 .start = extra_index,3668 .start = extra_index,
4282 .len = fields_len,3669 .len = extra.data.fields_len,
4283 };3670 };
4284 extra_index += fields_len;3671 extra_index += field_types.len;
4285 const names_map: OptionalMapIndex, const names = n: {3672 const field_defaults: Index.Slice = if (extra.data.flags.any_field_defaults) .{
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 .{
4343 .tid = unwrapped_index.tid,3673 .tid = unwrapped_index.tid,
4344 .extra_index = item.data,3674 .start = extra_index,
4345 .name = name,3675 .len = extra.data.fields_len,
4346 .name_nav = name_nav,3676 } else .empty;
4347 .namespace = namespace,3677 extra_index += field_defaults.len;
4348 .zir_index = zir_index,3678 const field_aligns: Alignment.Slice = if (extra.data.flags.any_field_aligns) .{
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 = .{
4377 .tid = unwrapped_index.tid,3679 .tid = unwrapped_index.tid,
4378 .start = extra_index,3680 .start = extra_index,
4379 .len = captures_len,3681 .len = extra.data.fields_len,
4380 };3682 } else .empty;
4381 extra_index += captures_len;3683 extra_index += std.math.divCeil(u32, field_aligns.len, 4) catch unreachable;
4382 if (flags.is_reified) {3684 const field_is_comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) .{
4383 extra_index += 2; // PackedU64
4384 }
4385 const field_types: Index.Slice = .{
4386 .tid = unwrapped_index.tid,3685 .tid = unwrapped_index.tid,
4387 .start = extra_index,3686 .start = extra_index,
4388 .len = fields_len,3687 .len = std.math.divCeil(u32, extra.data.fields_len, 32) catch unreachable,
4389 };3688 } else .empty;
4390 extra_index += fields_len;3689 extra_index += field_is_comptime_bits.len;
4391 const field_names: NullTerminatedString.Slice = .{3690 const field_runtime_order: LoadedStructType.RuntimeOrder.Slice = if (extra.data.flags.layout == .auto) .{
4392 .tid = unwrapped_index.tid,3691 .tid = unwrapped_index.tid,
4393 .start = extra_index,3692 .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,
4395 };3700 };
4396 extra_index += fields_len;3701 extra_index += field_offsets.len;
4397 const field_inits: Index.Slice = if (has_inits) inits: {3702
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;
4406 return .{3703 return .{
4407 .tid = unwrapped_index.tid,3704 .zir_index = extra.data.zir_index,
4408 .extra_index = item.data,3705 .captures = captures,
4409 .name = name,3706 .is_reified = extra.data.flags.any_captures == .reified,
4410 .name_nav = name_nav,3707 .name = extra.data.name,
4411 .namespace = namespace,3708 .name_nav = extra.data.name_nav,
4412 .zir_index = zir_index,3709 .namespace = extra.data.namespace,
4413 .layout = .@"packed",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,
4414 .field_names = field_names,3719 .field_names = field_names,
4415 .field_types = field_types,3720 .field_types = field_types,
4416 .field_inits = field_inits,3721 .field_defaults = field_defaults,
4417 .field_aligns = Alignment.Slice.empty,3722 .field_aligns = field_aligns,
4418 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,3723 .field_is_comptime_bits = field_is_comptime_bits,
4419 .comptime_bits = LoadedStructType.ComptimeBits.empty,3724 .field_runtime_order = field_runtime_order,
4420 .offsets = LoadedStructType.Offsets.empty,3725 .field_offsets = field_offsets,
4421 .names_map = names_map.toOptional(),3726 .packed_backing_int_type = .none,
4422 .captures = captures,3727 .class = extra.data.flags.class,
3728 .size = extra.data.size,
3729 .alignment = extra.data.flags.alignment,
4423 };3730 };
4424 },3731 },
4425 else => unreachable,3732 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,
4465 };3733 };
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.3776 .want_layout = extra.data.bits.want_layout,
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 }
44743777
4475 /// Look up field index based on tag value.3778 .field_name_map = extra.data.field_name_map,
4476 /// Asserts that `values_map` is not `none`.3779 .field_names = field_names,
4477 /// This function returns `null` when `tag_val` does not have the3780 .field_types = field_types,
4478 /// integer tag type of the enum.3781 .field_defaults = field_defaults,
4479 pub fn tagValueIndex(self: LoadedEnumType, ip: *const InternPool, tag_val: Index) ?u32 {3782 .field_aligns = .empty,
4480 assert(tag_val != .none);3783 .field_is_comptime_bits = .empty,
4481 // TODO: we should probably decide a single interface for this function, but currently3784 .field_runtime_order = .empty,
4482 // it's being called with both tag values and underlying ints. Fix this!3785 .field_offsets = .empty,
4483 const int_tag_val = switch (ip.indexToKey(tag_val)) {3786 .packed_backing_int_type = extra.data.backing_int_type,
4484 .enum_tag => |enum_tag| enum_tag.int,3787 .class = undefined,
4485 .int => tag_val,3788 .size = undefined,
4486 else => unreachable,3789 .alignment = undefined,
4487 };3790 };
4488 if (self.values_map.unwrap()) |values_map| {3791}
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};
45033792
4504pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {3793pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
4505 const unwrapped_index = index.unwrap(ip);3794 const unwrapped_index = index.unwrap(ip);
4506 const extra_list = unwrapped_index.getExtra(ip);3795 const extra_list = unwrapped_index.getExtra(ip);
3796 const extra_items = extra_list.view().items(.@"0");
4507 const item = unwrapped_index.getItem(ip);3797 const item = unwrapped_index.getItem(ip);
4508 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {3798 // Exiting this `switch` means this is a `packed union`.
4509 .type_enum_auto => {3799 const backing_mode: BackingTypeMode = switch (item.tag) {
4510 const extra = extraDataTrail(extra_list, EnumAuto, item.data);3800 .type_union_packed_auto => .auto,
4511 var extra_index: u32 = @intCast(extra.end);3801 .type_union_packed_explicit => .explicit,
4512 if (extra.data.zir_index == .none) {3802 .type_union => {
4513 extra_index += 1; // owner_union3803 const extra = extraDataTrail(extra_list, Tag.TypeUnion, item.data);
4514 }3804 var extra_index = extra.end;
4515 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {3805 const captures: CaptureValue.Slice = switch (extra.data.flags.any_captures) {
4516 extra_index += 2; // type_hash: PackedU643806 .reified => captures: {
4517 break :c 0;3807 extra_index += 2; // type_hash: PackedU64
4518 } else extra.data.captures_len;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
4519 return .{3841 return .{
3842 .zir_index = extra.data.zir_index,
3843 .captures = captures,
3844 .is_reified = extra.data.flags.any_captures == .reified,
4520 .name = extra.data.name,3845 .name = extra.data.name,
4521 .name_nav = extra.data.name_nav,3846 .name_nav = extra.data.name_nav,
4522 .namespace = extra.data.namespace,3847 .namespace = extra.data.namespace,
4523 .tag_ty = extra.data.int_tag_type,3848 .layout = switch (extra.data.flags.layout) {
4524 .names = .{3849 .auto => .auto,
4525 .tid = unwrapped_index.tid,3850 .@"extern" => .@"extern",
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,
4538 },3851 },
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,
4539 };3866 };
4540 },3867 },
4541 .type_enum_explicit => .explicit,
4542 .type_enum_nonexhaustive => .nonexhaustive,
4543 else => unreachable,3868 else => unreachable,
4544 };3869 };
4545 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);3870 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, item.data);
4546 var extra_index: u32 = @intCast(extra.end);3871 var extra_index = extra.end;
4547 if (extra.data.zir_index == .none) {3872 const captures: CaptureValue.Slice = switch (extra.data.bits.captures_len) {
4548 extra_index += 1; // owner_union3873 .reified => captures: {
4549 }3874 extra_index += 2; // type_hash: PackedU64
4550 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {3875 break :captures .empty;
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,
4563 },3876 },
4564 .values = .{3877 _ => |n| .{
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 = .{
4574 .tid = unwrapped_index.tid,3878 .tid = unwrapped_index.tid,
4575 .start = extra_index,3879 .start = extra_index,
4576 .len = captures_len,3880 .len = @intFromEnum(n),
4577 },3881 },
4578 };3882 };
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 };
4579}3919}
45803920
4581/// Note that this type doubles as the payload for `Tag.type_opaque`.3921pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
4582pub const LoadedOpaqueType = struct {3922 const unwrapped_index = index.unwrap(ip);
4583 /// Contains the declarations inside this opaque.3923 const extra_list = unwrapped_index.getExtra(ip);
4584 namespace: NamespaceIndex,3924 const extra_items = extra_list.view().items(.@"0");
4585 // TODO: the non-fqn will be needed by the new dwarf structure3925 const item = unwrapped_index.getItem(ip);
4586 /// The name of this opaque type.3926 const explicit_int_tag: bool, const nonexhaustive: bool = switch (item.tag) {
4587 name: NullTerminatedString,3927 .type_enum_auto => .{ false, false },
4588 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.3928 .type_enum_explicit => .{ true, false },
4589 /// Otherwise, this is `.none`.3929 .type_enum_nonexhaustive => .{ true, true },
4590 name_nav: Nav.Index.Optional,3930 else => unreachable,
4591 /// Index of the `opaque_decl` or `reify` instruction.3931 };
4592 zir_index: TrackedInst.Index,3932 const extra = extraDataTrail(extra_list, Tag.TypeEnum, item.data);
4593 captures: CaptureValue.Slice,3933 var extra_index: u32 = @intCast(extra.end);
4594};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
4596pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {3994pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
4597 const unwrapped_index = index.unwrap(ip);3995 const unwrapped_index = index.unwrap(ip);
4598 const item = unwrapped_index.getItem(ip);3996 const item = unwrapped_index.getItem(ip);
4599 assert(item.tag == .type_opaque);3997 assert(item.tag == .type_opaque);
4600 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, item.data);3998 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;
4605 return .{3999 return .{
4606 .name = extra.data.name,
4607 .name_nav = extra.data.name_nav,
4608 .namespace = extra.data.namespace,
4609 .zir_index = extra.data.zir_index,4000 .zir_index = extra.data.zir_index,
4610 .captures = .{4001 .captures = .{
4611 .tid = unwrapped_index.tid,4002 .tid = unwrapped_index.tid,
4612 .start = extra.end,4003 .start = extra.end,
4613 .len = captures_len,4004 .len = extra.data.captures_len,
4614 },4005 },
4006 .name = extra.data.name,
4007 .name_nav = extra.data.name_nav,
4008 .namespace = extra.data.namespace,
4615 };4009 };
4616}4010}
46174011
...@@ -4816,6 +4210,13 @@ pub const Index = enum(u32) {...@@ -4816,6 +4210,13 @@ pub const Index = enum(u32) {
4816 const extra = ip.getLocalShared(slice.tid).extra.acquire();4210 const extra = ip.getLocalShared(slice.tid).extra.acquire();
4817 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);4211 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
4818 }4212 }
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 }
4819 };4220 };
48204221
4821 /// Used for a map of `Index` values to the index within a list of `Index` values.4222 /// 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) {...@@ -4891,26 +4292,6 @@ pub const Index = enum(u32) {
4891 /// Tag to encoding mapping to facilitate fancy debug printing for this type.4292 /// Tag to encoding mapping to facilitate fancy debug printing for this type.
4892 fn dbHelper(self: *Index, tag_to_encoding_map: *struct {4293 fn dbHelper(self: *Index, tag_to_encoding_map: *struct {
4893 const DataIsIndex = struct { data: Index };4294 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
4915 removed: void,4296 removed: void,
4916 type_int_signed: struct { data: u32 },4297 type_int_signed: struct { data: u32 },
...@@ -4931,31 +4312,40 @@ pub const Index = enum(u32) {...@@ -4931,31 +4312,40 @@ pub const Index = enum(u32) {
4931 trailing: struct { names: []NullTerminatedString },4312 trailing: struct { names: []NullTerminatedString },
4932 },4313 },
4933 type_inferred_error_set: DataIsIndex,4314 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 {
4935 const @"data.fields_len" = opaque {};4327 const @"data.fields_len" = opaque {};
4936 data: *EnumAuto,4328 data: *TypeTuple,
4937 @"trailing.names.len": *@"data.fields_len",4329 @"trailing.types.len": *@"data.fields_len",
4938 trailing: struct { names: []NullTerminatedString },4330 @"trailing.values.len": *@"data.fields_len",
4331 trailing: struct {
4332 types: []Index,
4333 values: []Index,
4334 },
4939 },4335 },
4940 type_enum_explicit: DataIsExtraIndexOfEnumExplicit,4336
4941 type_enum_nonexhaustive: DataIsExtraIndexOfEnumExplicit,
4942 simple_type: void,
4943 type_opaque: struct { data: *Tag.TypeOpaque },
4944 type_struct: struct { data: *Tag.TypeStruct },4337 type_struct: struct { data: *Tag.TypeStruct },
4945 type_struct_packed: struct { data: *Tag.TypeStructPacked },4338 type_struct_packed_auto: struct { data: *Tag.TypeStructPacked },
4946 type_struct_packed_inits: struct { data: *Tag.TypeStructPacked },4339 type_struct_packed_explicit: struct { data: *Tag.TypeStructPacked },
4947 type_tuple: DataIsExtraIndexOfTypeTuple,4340 type_struct_packed_auto_defaults: struct { data: *Tag.TypeStructPacked },
4341 type_struct_packed_explicit_defaults: struct { data: *Tag.TypeStructPacked },
4948 type_union: struct { data: *Tag.TypeUnion },4342 type_union: struct { data: *Tag.TypeUnion },
4949 type_function: struct {4343 type_union_packed_auto: struct { data: *Tag.TypeUnionPacked },
4950 const @"data.flags.has_comptime_bits" = opaque {};4344 type_union_packed_explicit: struct { data: *Tag.TypeUnionPacked },
4951 const @"data.flags.has_noalias_bits" = opaque {};4345 type_enum_auto: struct { data: *Tag.TypeEnum },
4952 const @"data.params_len" = opaque {};4346 type_enum_explicit: struct { data: *Tag.TypeEnum },
4953 data: *Tag.TypeFunction,4347 type_enum_nonexhaustive: struct { data: *Tag.TypeEnum },
4954 @"trailing.comptime_bits.len": *@"data.flags.has_comptime_bits",4348 type_opaque: struct { data: *Tag.TypeOpaque },
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 },
49594349
4960 undef: DataIsIndex,4350 undef: DataIsIndex,
4961 simple_value: void,4351 simple_value: void,
...@@ -4982,8 +4372,6 @@ pub const Index = enum(u32) {...@@ -4982,8 +4372,6 @@ pub const Index = enum(u32) {
4982 int_small: struct { data: *IntSmall },4372 int_small: struct { data: *IntSmall },
4983 int_positive: struct { data: u32 },4373 int_positive: struct { data: u32 },
4984 int_negative: struct { data: u32 },4374 int_negative: struct { data: u32 },
4985 int_lazy_align: struct { data: *IntLazy },
4986 int_lazy_size: struct { data: *IntLazy },
4987 error_set_error: struct { data: *Key.Error },4375 error_set_error: struct { data: *Key.Error },
4988 error_union_error: struct { data: *Key.Error },4376 error_union_error: struct { data: *Key.Error },
4989 error_union_payload: struct { data: *Tag.TypeValue },4377 error_union_payload: struct { data: *Tag.TypeValue },
...@@ -5027,6 +4415,7 @@ pub const Index = enum(u32) {...@@ -5027,6 +4415,7 @@ pub const Index = enum(u32) {
5027 trailing: struct { element_values: []Index },4415 trailing: struct { element_values: []Index },
5028 },4416 },
5029 repeated: struct { data: *Repeated },4417 repeated: struct { data: *Repeated },
4418 bitpack: struct { data: *Key.Bitpack },
50304419
5031 memoized_call: struct {4420 memoized_call: struct {
5032 const @"data.args_len" = opaque {};4421 const @"data.args_len" = opaque {};
...@@ -5037,7 +4426,7 @@ pub const Index = enum(u32) {...@@ -5037,7 +4426,7 @@ pub const Index = enum(u32) {
5037 }) void {4426 }) void {
5038 _ = self;4427 _ = self;
5039 const map_fields = @typeInfo(@typeInfo(@TypeOf(tag_to_encoding_map)).pointer.child).@"struct".fields;4428 const map_fields = @typeInfo(@typeInfo(@TypeOf(tag_to_encoding_map)).pointer.child).@"struct".fields;
5040 @setEvalBranchQuota(2_000);4429 @setEvalBranchQuota(3_000);
5041 inline for (@typeInfo(Tag).@"enum".fields, 0..) |tag, start| {4430 inline for (@typeInfo(Tag).@"enum".fields, 0..) |tag, start| {
5042 inline for (0..map_fields.len) |offset| {4431 inline for (0..map_fields.len) |offset| {
5043 if (comptime std.mem.eql(u8, tag.name, map_fields[(start + offset) % map_fields.len].name)) break;4432 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 = .{...@@ -5409,7 +4798,7 @@ pub const static_keys: [static_len]Key = .{
5409 .values = .empty,4798 .values = .empty,
5410 } },4799 } },
54114800
5412 .{ .simple_value = .undefined },4801 .{ .undef = .undefined_type },
5413 .{ .undef = .bool_type },4802 .{ .undef = .bool_type },
5414 .{ .undef = .usize_type },4803 .{ .undef = .usize_type },
5415 .{ .undef = .u1_type },4804 .{ .undef = .u1_type },
...@@ -5469,7 +4858,11 @@ pub const static_keys: [static_len]Key = .{...@@ -5469,7 +4858,11 @@ pub const static_keys: [static_len]Key = .{
5469 .{ .simple_value = .null },4858 .{ .simple_value = .null },
5470 .{ .simple_value = .true },4859 .{ .simple_value = .true },
5471 .{ .simple_value = .false },4860 .{ .simple_value = .false },
5472 .{ .simple_value = .empty_tuple },4861
4862 .{ .aggregate = .{
4863 .ty = .empty_tuple_type,
4864 .storage = .{ .elems = &.{} },
4865 } },
5473};4866};
54744867
5475/// How many items in the InternPool are statically known.4868/// How many items in the InternPool are statically known.
...@@ -5485,6 +4878,8 @@ pub const Tag = enum(u8) {...@@ -5485,6 +4878,8 @@ pub const Tag = enum(u8) {
5485 /// assert not this tag. `data` is unused.4878 /// assert not this tag. `data` is unused.
5486 removed,4879 removed,
54874880
4881 /// A type that can be represented with only an enum tag.
4882 simple_type,
5488 /// An integer type.4883 /// An integer type.
5489 /// data is number of bits4884 /// data is number of bits
5490 type_int_signed,4885 type_int_signed,
...@@ -5524,41 +4919,68 @@ pub const Tag = enum(u8) {...@@ -5524,41 +4919,68 @@ pub const Tag = enum(u8) {
5524 /// The inferred error set type of a function.4919 /// The inferred error set type of a function.
5525 /// data is `Index` of a `func_decl` or `func_instance`.4920 /// data is `Index` of a `func_decl` or `func_instance`.
5526 type_inferred_error_set,4921 type_inferred_error_set,
5527 /// An enum type with auto-numbered tag values.4922 /// A function body type.
5528 /// The enum is exhaustive.4923 /// `data` is extra index to `TypeFunction`.
5529 /// data is payload index to `EnumAuto`.4924 type_function,
5530 type_enum_auto,4925 /// A `TupleType`.
5531 /// An enum type with an explicitly provided integer tag type.4926 /// data is extra index of `TypeTuple`.
5532 /// The enum is exhaustive.4927 type_tuple,
5533 /// data is payload index to `EnumExplicit`.4928
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,
5544 /// A non-packed struct type.4929 /// A non-packed struct type.
5545 /// data is 0 or extra index of `TypeStruct`.4930 /// data is extra index of `TypeStruct`.
5546 type_struct,4931 type_struct,
5547 /// A packed struct, no fields have any init values.4932 /// `packed struct { ... }` with no default field values.
5548 /// data is extra index of `TypeStructPacked`.4933 /// data is extra index of `TypeStructPacked`.
5549 type_struct_packed,4934 type_struct_packed_auto,
5550 /// A packed struct, one or more fields have init values.4935 /// `packed struct(T) { ... }` with no default field values.
5551 /// data is extra index of `TypeStructPacked`.4936 /// data is extra index of `TypeStructPacked`.
5552 type_struct_packed_inits,4937 type_struct_packed_explicit,
5553 /// A `TupleType`.4938 /// `packed struct { ... }` with one or more default field values.
5554 /// data is extra index of `TypeTuple`.4939 /// data is extra index of `TypeStructPacked`.
5555 type_tuple,4940 type_struct_packed_auto_defaults,
5556 /// A union type.4941 /// `packed struct(T) { ... }` with one or more default field values.
5557 /// `data` is extra index of `TypeUnion`.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`.
5558 type_union,4947 type_union,
5559 /// A function body type.4948 /// `packed union { ... }`.
5560 /// `data` is extra index to `TypeFunction`.4949 /// data is extra index of `TypeUnionPacked`.
5561 type_function,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
5563 /// Typed `undefined`.4985 /// Typed `undefined`.
5564 /// `data` is `Index` of the type.4986 /// `data` is `Index` of the type.
...@@ -5644,12 +5066,6 @@ pub const Tag = enum(u8) {...@@ -5644,12 +5066,6 @@ pub const Tag = enum(u8) {
5644 /// A negative integer value.5066 /// A negative integer value.
5645 /// data is a limbs index to `Int`.5067 /// data is a limbs index to `Int`.
5646 int_negative,5068 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,
5653 /// An error value.5069 /// An error value.
5654 /// data is extra index of `Key.Error`.5070 /// data is extra index of `Key.Error`.
5655 error_set_error,5071 error_set_error,
...@@ -5735,6 +5151,9 @@ pub const Tag = enum(u8) {...@@ -5735,6 +5151,9 @@ pub const Tag = enum(u8) {
5735 /// An instance of an array or vector with every element being the same value.5151 /// An instance of an array or vector with every element being the same value.
5736 /// data is extra index to `Repeated`.5152 /// data is extra index to `Repeated`.
5737 repeated,5153 repeated,
5154 /// An instance of a `packed struct` or `packed union`.
5155 /// data is extra index to `Key.Bitpack`.
5156 bitpack,
57385157
5739 /// A memoized comptime function call result.5158 /// A memoized comptime function call result.
5740 /// data is extra index to `MemoizedCall`5159 /// data is extra index to `MemoizedCall`
...@@ -5747,24 +5166,77 @@ pub const Tag = enum(u8) {...@@ -5747,24 +5166,77 @@ pub const Tag = enum(u8) {
5747 const Union = Key.Union;5166 const Union = Key.Union;
5748 const TypePointer = Key.PtrType;5167 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 = .{
5751 .summary = .@"{.payload.name%summary#\"}",5206 .summary = .@"{.payload.name%summary#\"}",
5752 .payload = EnumExplicit,5207 .payload = TypeUnionPacked,
5753 .trailing = struct {5208 .trailing = struct {
5754 owner_union: Index,5209 type_hash: ?u64,
5755 captures: ?[]CaptureValue,5210 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,
5756 type_hash: ?u64,5226 type_hash: ?u64,
5227 captures: ?[]CaptureValue,
5228 field_value_map: MapIndex,
5757 field_names: []NullTerminatedString,5229 field_names: []NullTerminatedString,
5758 tag_values: []Index,5230 field_values: []Index,
5759 },5231 },
5760 .config = .{5232 .config = .{
5761 .@"trailing.owner_union.?" = .@"payload.zir_index == .none",5233 .@"trailing.owner_union.?" = .@"payload.captures_len == .generated_union_tag",
5762 .@"trailing.cau.?" = .@"payload.zir_index != .none",5234 .@"trailing.zir_index.?" = .@"payload.captures_len != .generated_union_tag",
5763 .@"trailing.captures.?" = .@"payload.captures_len < 0xffffffff",5235 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5764 .@"trailing.captures.?.len" = .@"payload.captures_len",5236 .@"trailing.captures.?" = .@"payload.captures_len != .reified and payload.captures_len != .generated_enum_tag",
5765 .@"trailing.type_hash.?" = .@"payload.captures_len == 0xffffffff",5237 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
5766 .@"trailing.field_names.len" = .@"payload.fields_len",5238 .@"trailing.field_names.len" = .@"payload.fields_len",
5767 .@"trailing.tag_values.len" = .@"payload.fields_len",5239 .@"trailing.field_values.len" = .@"payload.fields_len",
5768 },5240 },
5769 };5241 };
5770 const encodings = .{5242 const encodings = .{
...@@ -5792,153 +5264,121 @@ pub const Tag = enum(u8) {...@@ -5792,153 +5264,121 @@ pub const Tag = enum(u8) {
5792 .summary = .@"@typeInfo(@typeInfo(@TypeOf({.data%summary})).@\"fn\".return_type.?).error_union.error_set",5264 .summary = .@"@typeInfo(@typeInfo(@TypeOf({.data%summary})).@\"fn\".return_type.?).error_union.error_set",
5793 .data = Index,5265 .data = Index,
5794 },5266 },
5795 .type_enum_auto = .{5267 .simple_type = .{ .summary = .@"{.index%value#.}", .index = SimpleType },
5796 .summary = .@"{.payload.name%summary#\"}",5268 .type_tuple = .{
5797 .payload = EnumAuto,5269 .summary = .@"struct {...}",
5270 .payload = TypeTuple,
5798 .trailing = struct {5271 .trailing = struct {
5799 owner_union: ?Index,5272 field_types: []Index,
5800 captures: ?[]CaptureValue,5273 field_values: []Index,
5801 type_hash: ?u64,
5802 field_names: []NullTerminatedString,
5803 },5274 },
5804 .config = .{5275 .config = .{
5805 .@"trailing.owner_union.?" = .@"payload.zir_index == .none",5276 .@"trailing.field_types.len" = .@"payload.fields_len",
5806 .@"trailing.cau.?" = .@"payload.zir_index != .none",5277 .@"trailing.field_values.len" = .@"payload.fields_len",
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",
5811 },5278 },
5812 },5279 },
5813 .type_enum_explicit = enum_explicit_encoding,5280 .type_function = .{
5814 .type_enum_nonexhaustive = enum_explicit_encoding,5281 .summary = .@"fn (...) ... {.payload.return_type%summary}",
5815 .simple_type = .{ .summary = .@"{.index%value#.}", .index = SimpleType },5282 .payload = TypeFunction,
5816 .type_opaque = .{5283 .trailing = struct {
5817 .summary = .@"{.payload.name%summary#\"}",5284 param_comptime_bits: ?[]u32,
5818 .payload = TypeOpaque,5285 param_noalias_bits: ?[]u32,
5819 .trailing = struct { captures: []CaptureValue },5286 param_type: []Index,
5820 .config = .{ .@"trailing.captures.len" = .@"payload.captures_len" },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 },
5821 },5295 },
5296
5822 .type_struct = .{5297 .type_struct = .{
5823 .summary = .@"{.payload.name%summary#\"}",5298 .summary = .@"{.payload.name%summary#\"}",
5824 .payload = TypeStruct,5299 .payload = TypeStruct,
5825 .trailing = struct {5300 .trailing = struct {
5301 type_hash: ?u64,
5826 captures_len: ?u32,5302 captures_len: ?u32,
5827 captures: ?[]CaptureValue,5303 captures: ?[]CaptureValue,
5828 type_hash: ?u64,
5829 field_types: []Index,
5830 field_names_map: OptionalMapIndex,
5831 field_names: []NullTerminatedString,5304 field_names: []NullTerminatedString,
5832 field_inits: ?[]Index,5305 field_types: []Index,
5306 field_defaults: ?[]Index,
5833 field_aligns: ?[]Alignment,5307 field_aligns: ?[]Alignment,
5834 field_is_comptime_bits: ?[]u32,5308 field_is_comptime_bits: ?[]u32,
5835 field_index: ?[]LoadedStructType.RuntimeOrder,5309 field_runtime_order: ?[]u32,
5836 field_offset: []u32,5310 field_offsets: []u32,
5837 },5311 },
5838 .config = .{5312 .config = .{
5839 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",5313 .@"trailing.type_hash.?" = .@"payload.flags.any_captures == .reified",
5840 .@"trailing.captures.?" = .@"payload.flags.any_captures",5314 .@"trailing.captures_len.?" = .@"payload.flags.any_captures == .true",
5315 .@"trailing.captures.?" = .@"payload.flags.any_captures == .true",
5841 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",5316 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5842 .@"trailing.type_hash.?" = .@"payload.flags.is_reified",
5843 .@"trailing.field_types.len" = .@"payload.fields_len",
5844 .@"trailing.field_names.len" = .@"payload.fields_len",5317 .@"trailing.field_names.len" = .@"payload.fields_len",
5845 .@"trailing.field_inits.?" = .@"payload.flags.any_default_inits",5318 .@"trailing.field_types.len" = .@"payload.fields_len",
5846 .@"trailing.field_inits.?.len" = .@"payload.fields_len",5319 .@"trailing.field_defaults.?" = .@"payload.flags.any_field_defaults",
5847 .@"trailing.field_aligns.?" = .@"payload.flags.any_aligned_fields",5320 .@"trailing.field_defaults.?.len" = .@"payload.fields_len",
5321 .@"trailing.field_aligns.?" = .@"payload.flags.any_field_aligns",
5848 .@"trailing.field_aligns.?.len" = .@"payload.fields_len",5322 .@"trailing.field_aligns.?.len" = .@"payload.fields_len",
5849 .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields",5323 .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields",
5850 .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32",5324 .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32",
5851 .@"trailing.field_index.?" = .@"!payload.flags.is_extern",5325 .@"trailing.field_runtime_order.?" = .@"payload.flags.layout == .auto",
5852 .@"trailing.field_index.?.len" = .@"payload.fields_len",5326 .@"trailing.field_runtime_order.?.len" = .@"payload.fields_len",
5853 .@"trailing.field_offset.len" = .@"payload.fields_len",5327 .@"trailing.field_offsets.len" = .@"payload.fields_len",
5854 },5328 },
5855 },5329 },
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 = .{
5857 .summary = .@"{.payload.name%summary#\"}",5335 .summary = .@"{.payload.name%summary#\"}",
5858 .payload = TypeStructPacked,5336 .payload = TypeUnion,
5859 .trailing = struct {5337 .trailing = struct {
5338 type_hash: ?u64,
5860 captures_len: ?u32,5339 captures_len: ?u32,
5861 captures: ?[]CaptureValue,5340 captures: ?[]CaptureValue,
5862 type_hash: ?u64,
5863 field_types: []Index,5341 field_types: []Index,
5864 field_names: []NullTerminatedString,5342 field_aligns: ?[]Alignment,
5865 },5343 },
5866 .config = .{5344 .config = .{
5867 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",5345 .@"trailing.type_hash.?" = .@"payload.flags.any_captures == .reified",
5868 .@"trailing.captures.?" = .@"payload.flags.any_captures",5346 .@"trailing.captures_len.?" = .@"payload.flags.any_captures == .true",
5347 .@"trailing.captures.?" = .@"payload.flags.any_captures == .true",
5869 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",5348 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5870 .@"trailing.type_hash.?" = .@"payload.is_flags.is_reified",
5871 .@"trailing.field_types.len" = .@"payload.fields_len",5349 .@"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",
5873 },5352 },
5874 },5353 },
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 = .{
5876 .summary = .@"{.payload.name%summary#\"}",5357 .summary = .@"{.payload.name%summary#\"}",
5877 .payload = TypeStructPacked,5358 .payload = TypeEnum,
5878 .trailing = struct {5359 .trailing = struct {
5879 captures_len: ?u32,5360 owner_union: ?Index,
5880 captures: ?[]CaptureValue,5361 zir_index: ?TrackedInst.Index,
5881 type_hash: ?u64,5362 type_hash: ?u64,
5882 field_types: []Index,5363 captures: ?[]CaptureValue,
5883 field_names: []NullTerminatedString,5364 field_names: []NullTerminatedString,
5884 field_inits: []Index,
5885 },5365 },
5886 .config = .{5366 .config = .{
5887 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",5367 .@"trailing.owner_union.?" = .@"payload.captures_len == .generated_union_tag",
5888 .@"trailing.captures.?" = .@"payload.flags.any_captures",5368 .@"trailing.zir_index.?" = .@"payload.captures_len != .generated_union_tag",
5889 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",5369 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5890 .@"trailing.type_hash.?" = .@"payload.is_flags.is_reified",5370 .@"trailing.captures.?" = .@"payload.captures_len != .reified and payload.captures_len != .generated_enum_tag",
5891 .@"trailing.field_types.len" = .@"payload.fields_len",5371 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
5892 .@"trailing.field_names.len" = .@"payload.fields_len",5372 .@"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",
5906 },5373 },
5907 },5374 },
5908 .type_union = .{5375 .type_enum_explicit = enum_explicit_encoding,
5376 .type_enum_nonexhaustive = enum_explicit_encoding,
5377 .type_opaque = .{
5909 .summary = .@"{.payload.name%summary#\"}",5378 .summary = .@"{.payload.name%summary#\"}",
5910 .payload = TypeUnion,5379 .payload = TypeOpaque,
5911 .trailing = struct {5380 .trailing = struct { captures: []CaptureValue },
5912 captures_len: ?u32,5381 .config = .{ .@"trailing.captures.len" = .@"payload.captures_len" },
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 },
5942 },5382 },
59435383
5944 .undef = .{ .summary = .@"@as({.data%summary}, undefined)", .data = Index },5384 .undef = .{ .summary = .@"@as({.data%summary}, undefined)", .data = Index },
...@@ -5999,8 +5439,6 @@ pub const Tag = enum(u8) {...@@ -5999,8 +5439,6 @@ pub const Tag = enum(u8) {
5999 .int_small = .{ .summary = .@"@as({.payload.ty%summary}, {.payload.value%value})", .payload = IntSmall },5439 .int_small = .{ .summary = .@"@as({.payload.ty%summary}, {.payload.value%value})", .payload = IntSmall },
6000 .int_positive = .{},5440 .int_positive = .{},
6001 .int_negative = .{},5441 .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 },
6004 .error_set_error = .{ .summary = .@"@as({.payload.ty%summary}, error.@{.payload.name%summary})", .payload = Error },5442 .error_set_error = .{ .summary = .@"@as({.payload.ty%summary}, error.@{.payload.name%summary})", .payload = Error },
6005 .error_union_error = .{ .summary = .@"@as({.payload.ty%summary}, error.@{.payload.name%summary})", .payload = Error },5443 .error_union_error = .{ .summary = .@"@as({.payload.ty%summary}, error.@{.payload.name%summary})", .payload = Error },
6006 .error_union_payload = .{ .summary = .@"@as({.payload.ty%summary}, {.payload.val%summary})", .payload = TypeValue },5444 .error_union_payload = .{ .summary = .@"@as({.payload.ty%summary}, {.payload.val%summary})", .payload = TypeValue },
...@@ -6049,6 +5487,7 @@ pub const Tag = enum(u8) {...@@ -6049,6 +5487,7 @@ pub const Tag = enum(u8) {
6049 .config = .{ .@"trailing.elements.len" = .@"payload.ty.payload.fields_len" },5487 .config = .{ .@"trailing.elements.len" = .@"payload.ty.payload.fields_len" },
6050 },5488 },
6051 .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated },5489 .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated },
5490 .bitpack = .{ .summary = .@"@as({.payload.ty%summary}, {})", .payload = Key.Bitpack },
60525491
6053 .memoized_call = .{5492 .memoized_call = .{
6054 .summary = .@"@memoize({.payload.func%summary})",5493 .summary = .@"@memoize({.payload.func%summary})",
...@@ -6141,194 +5580,288 @@ pub const Tag = enum(u8) {...@@ -6141,194 +5580,288 @@ pub const Tag = enum(u8) {
6141 generic_owner: Index,5580 generic_owner: Index,
6142 };5581 };
61435582
6144 pub const FuncCoerced = struct {5583 pub const FuncCoerced = struct {
6145 ty: Index,5584 ty: Index,
6146 func: Index,5585 func: Index,
6147 };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:5671 _: u16 = 0,
6150 /// 0. name: NullTerminatedString for each names_len5672 };
6151 pub const ErrorSet = struct {
6152 names_len: u32,
6153 /// Maps error names to declaration index.
6154 names_map: MapIndex,
6155 };5673 };
61565674
6157 /// Trailing:5675 /// Trailing:
6158 /// 0. comptime_bits: u32, // if has_comptime_bits5676 /// 0. type_hash: PackedU64 // if `captures_len == .reified`
6159 /// 1. noalias_bits: u32, // if has_noalias_bits5677 /// 1. capture: CaptureValue // if `captures_len != .reified`; for each `captures_len`
6160 /// 2. param_type: Index for each params_len5678 /// 2. field_name: NullTerminatedString // for each `fields_len`
6161 pub const TypeFunction = struct {5679 /// 3. field_type: Index // for each `fields_len`
6162 params_len: u32,5680 /// 4. field_default: Index // if item tag implies field defaults; for each `fields_len`
6163 return_type: Index,5681 pub const TypeStructPacked = struct {
6164 flags: Flags,5682 zir_index: TrackedInst.Index,
5683 bits: Bits,
61655684
6166 pub const Flags = packed struct(u32) {5685 name: NullTerminatedString,
6167 cc: PackedCallingConvention,5686 name_nav: Nav.Index.Optional,
6168 is_var_args: bool,5687 namespace: NamespaceIndex,
6169 is_generic: bool,5688
6170 has_comptime_bits: bool,5689 /// The corresponding `BackingTypeMode` depends on the item's `Tag`.
6171 has_noalias_bits: bool,5690 backing_int_type: Index,
6172 is_noinline: bool,5691
6173 _: u9 = 0,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,
6174 };5701 };
6175 };5702 };
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 ///
6177 /// Trailing:5709 /// Trailing:
6178 /// 0. captures_len: u32 // if `any_captures`5710 /// 0. type_hash: PackedU64 // if `any_captures == .reified`
6179 /// 1. capture: CaptureValue // for each `captures_len`5711 /// 1. captures_len: u32 // if `any_captures == .true`
6180 /// 2. type_hash: PackedU64 // if `is_reified`5712 /// 2. capture: CaptureValue // if `any_captures == .true`; for each `captures_len`
6181 /// 3. field type: Index for each field; declaration order5713 /// 3. reified_field_name: NullTerminatedString // if `any_captures == .reified`; for each `fields_len`
6182 /// 4. field align: Alignment for each field; declaration order5714 /// 4. field_type: Index // for each `fields_len`
5715 /// 5. field_align: Alignment // for each `fields_len` if `any_field_aligns`
6183 pub const TypeUnion = struct {5716 pub const TypeUnion = struct {
5717 zir_index: TrackedInst.Index,
5718
6184 name: NullTerminatedString,5719 name: NullTerminatedString,
6185 name_nav: Nav.Index.Optional,5720 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
6187 /// This could be provided through the tag type, but it is more convenient5725 /// This could be provided through the tag type, but it is more convenient
6188 /// to store it directly. This is also necessary for `dumpStatsFallible` to5726 /// to store it directly. This is also necessary for `dumpStatsFallible` to
6189 /// work on unresolved types.5727 /// work on unresolved types.
6190 fields_len: u32,5728 fields_len: u32,
6191 /// Only valid after .have_layout5729
5730 /// Always 0 until layout resolved.
6192 size: u32,5731 size: u32,
6193 /// Only valid after .have_layout5732 /// Always 0 until layout resolved.
6194 padding: u32,5733 padding: u32,
6195 namespace: NamespaceIndex,5734
6196 /// The enum that provides the list of field names and values.5735 flags: Flags,
6197 tag_ty: Index,
6198 zir_index: TrackedInst.Index,
61995736
6200 pub const Flags = packed struct(u32) {5737 pub const Flags = packed struct(u32) {
6201 any_captures: bool,5738 any_captures: enum(u2) { true, false, reified },
6202 runtime_tag: LoadedUnionType.RuntimeTag,5739
6203 /// If false, the field alignment trailing data is omitted.5740 /// Whether `enum_tag_type` was explicitly specified with `union(E)` syntax.
6204 any_aligned_fields: bool,5741 ///
6205 layout: std.builtin.Type.ContainerLayout,5742 /// For `union(enum(E))` syntax, this is `false`, but the generated enum tag type is
6206 status: LoadedUnionType.Status,5743 /// considered to have an explicitly specified integer tag type.
6207 requires_comptime: RequiresComptime,5744 enum_tag_mode: BackingTypeMode,
6208 assumed_runtime_bits: bool,5745
6209 assumed_pointer_aligned: bool,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.
6210 alignment: Alignment,5756 alignment: Alignment,
6211 is_reified: bool,5757
6212 _: u12 = 0,5758 want_layout: bool,
5759
5760 _: u14 = 0,
6213 };5761 };
6214 };5762 };
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 ///
6216 /// Trailing:5769 /// Trailing:
6217 /// 0. captures_len: u32 // if `any_captures`5770 /// 0. type_hash: PackedU64 // if `captures_len == .reified`
6218 /// 1. capture: CaptureValue // for each `captures_len`5771 /// 1. capture: CaptureValue // if `captures_len != .reified`; for each `captures_len`
6219 /// 2. type_hash: PackedU64 // if `is_reified`5772 /// 2. reified_field_name: NullTerminatedString // if `captures_len == .reified`; for each `fields_len`
6220 /// 3. type: Index for each fields_len5773 /// 3. field_type: Index // for each `fields_len`
6221 /// 4. name: NullTerminatedString for each fields_len5774 pub const TypeUnionPacked = struct {
6222 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits5775 zir_index: TrackedInst.Index,
6223 pub const TypeStructPacked = struct {5776 bits: Bits,
5777
6224 name: NullTerminatedString,5778 name: NullTerminatedString,
6225 name_nav: Nav.Index.Optional,5779 name_nav: Nav.Index.Optional,
6226 zir_index: TrackedInst.Index,
6227 fields_len: u32,
6228 namespace: NamespaceIndex,5780 namespace: NamespaceIndex,
6229 backing_int_ty: Index,
6230 names_map: MapIndex,
6231 flags: Flags,
62325781
6233 pub const Flags = packed struct(u32) {5782 /// The corresponding `BackingTypeMode` depends on the item's `Tag`.
6234 any_captures: bool = false,5783 backing_int_type: Index,
6235 /// Dependency loop detection when resolving field inits.5784 /// Although packed unions do not semantically have a tag type, the compiler still assigns
6236 field_inits_wip: bool = false,5785 /// them a "hypothetical" tag type.
6237 inits_resolved: bool = false,5786 enum_tag_type: Index,
6238 is_reified: bool = false,5787
6239 _: u28 = 0,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,
6240 };5799 };
6241 };5800 };
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 ///
6257 /// Trailing:5802 /// Trailing:
6258 /// 0. captures_len: u32 // if `any_captures`5803 /// 0. owner_union: Index // if `captures_len == .generated_union_tag`
6259 /// 1. capture: CaptureValue // for each `captures_len`5804 /// 1. zir_index: TrackedInst.Index // if `captures_len != .generated_union_tag`
6260 /// 2. type_hash: PackedU64 // if `is_reified`5805 /// 2. type_hash: PackedU64 // if `captures_len == .reified`
6261 /// 3. type: Index for each field in declared order5806 /// 3. capture: CaptureValue // if `captures_len` is not a named tag; for each `captures_len`
6262 /// 4. if any_default_inits:5807 /// 4. field_value_map: MapIndex // if tag is not `.type_enum_auto`
6263 /// init: Index // for each field in declared order5808 /// 5. field_name: NullTerminatedString // for each `fields_len`
6264 /// 5. if any_aligned_fields:5809 /// 6. field_value: Index // if tag is not `.type_enum_auto`; for each `fields_len`
6265 /// align: Alignment // for each field in declared order5810 pub const TypeEnum = struct {
6266 /// 6. if any_comptime_fields:5811 bits: Bits,
6267 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 05812
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 {
6272 name: NullTerminatedString,5813 name: NullTerminatedString,
6273 name_nav: Nav.Index.Optional,5814 name_nav: Nav.Index.Optional,
6274 zir_index: TrackedInst.Index,
6275 namespace: NamespaceIndex,5815 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
6276 fields_len: u32,5821 fields_len: u32,
6277 flags: Flags,5822 field_name_map: MapIndex,
6278 size: u32,
62795823
6280 pub const Flags = packed struct(u32) {5824 const Bits = packed struct(u32) {
6281 any_captures: bool = false,5825 captures_len: enum(u31) {
6282 is_extern: bool = false,5826 reified = std.math.maxInt(u31),
6283 known_non_opv: bool = false,5827 generated_union_tag = std.math.maxInt(u31) - 1,
6284 requires_comptime: RequiresComptime = @enumFromInt(0),5828 _,
6285 assumed_runtime_bits: bool = false,5829 },
6286 assumed_pointer_aligned: bool = false,5830 want_layout: bool,
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,
6310 };5831 };
6311 };5832 };
63125833
6313 /// Trailing:5834 /// Trailing:
6314 /// 0. capture: CaptureValue // for each `captures_len`5835 /// 0. capture: CaptureValue // for each `captures_len`
6315 pub const TypeOpaque = struct {5836 pub const TypeOpaque = struct {
5837 zir_index: TrackedInst.Index,
5838 captures_len: u32,
5839
6316 name: NullTerminatedString,5840 name: NullTerminatedString,
6317 name_nav: Nav.Index.Optional,5841 name_nav: Nav.Index.Optional,
6318 /// Contains the declarations inside this opaque.
6319 namespace: NamespaceIndex,5842 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,
6324 };5843 };
6325};5844};
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
6327/// State that is mutable during semantic analysis. This data is not used for5860/// State that is mutable during semantic analysis. This data is not used for
6328/// equality or hashing, except for `inferred_error_set` which is considered5861/// equality or hashing, except for `inferred_error_set` which is considered
6329/// to be part of the type of the function.5862/// to be part of the type of the function.
6330pub const FuncAnalysis = packed struct(u32) {5863pub const FuncAnalysis = packed struct(u32) {
6331 is_analyzed: bool,5864 want_runtime_analysis: bool,
6332 branch_hint: std.builtin.BranchHint,5865 branch_hint: std.builtin.BranchHint,
6333 is_noinline: bool,5866 is_noinline: bool,
6334 has_error_trace: bool,5867 has_error_trace: bool,
...@@ -6399,13 +5932,9 @@ pub const SimpleType = enum(u32) {...@@ -6399,13 +5932,9 @@ pub const SimpleType = enum(u32) {
6399};5932};
64005933
6401pub const SimpleValue = enum(u32) {5934pub const SimpleValue = enum(u32) {
6402 /// This is untyped `undefined`.
6403 undefined = @intFromEnum(Index.undef),
6404 void = @intFromEnum(Index.void_value),5935 void = @intFromEnum(Index.void_value),
6405 /// This is untyped `null`.5936 /// This is untyped `null`.
6406 null = @intFromEnum(Index.null_value),5937 null = @intFromEnum(Index.null_value),
6407 /// This is the untyped empty struct/array literal: `.{}`
6408 empty_tuple = @intFromEnum(Index.empty_tuple),
6409 true = @intFromEnum(Index.bool_true),5938 true = @intFromEnum(Index.bool_true),
6410 false = @intFromEnum(Index.bool_false),5939 false = @intFromEnum(Index.bool_false),
6411 @"unreachable" = @intFromEnum(Index.unreachable_value),5940 @"unreachable" = @intFromEnum(Index.unreachable_value),
...@@ -6536,12 +6065,17 @@ pub const Alignment = enum(u6) {...@@ -6536,12 +6065,17 @@ pub const Alignment = enum(u6) {
6536 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };6065 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
65376066
6538 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {6067 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
6539 // TODO: implement @ptrCast between slices changing the length
6540 const extra = ip.getLocalShared(slice.tid).extra.acquire();6068 const extra = ip.getLocalShared(slice.tid).extra.acquire();
6541 //const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);6069 const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
6542 const bytes: []u8 = std.mem.sliceAsBytes(extra.view().items(.@"0")[slice.start..]);
6543 return @ptrCast(bytes[0..slice.len]);6070 return @ptrCast(bytes[0..slice.len]);
6544 }6071 }
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 }
6545 };6079 };
65466080
6547 pub fn toRelaxedCompareUnits(a: Alignment) u8 {6081 pub fn toRelaxedCompareUnits(a: Alignment) u8 {
...@@ -6596,55 +6130,6 @@ pub const Array = struct {...@@ -6596,55 +6130,6 @@ pub const Array = struct {
6596 }6130 }
6597};6131};
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
6648pub const PackedU64 = packed struct(u64) {6133pub const PackedU64 = packed struct(u64) {
6649 a: u32,6134 a: u32,
6650 b: u32,6135 b: u32,
...@@ -6827,11 +6312,6 @@ pub const IntSmall = struct {...@@ -6827,11 +6312,6 @@ pub const IntSmall = struct {
6827 value: u32,6312 value: u32,
6828};6313};
68296314
6830pub const IntLazy = struct {
6831 ty: Index,
6832 lazy_ty: Index,
6833};
6834
6835/// A f64 value, broken up into 2 u32 parts.6315/// A f64 value, broken up into 2 u32 parts.
6836pub const Float64 = struct {6316pub const Float64 = struct {
6837 piece0: u32,6317 piece0: u32,
...@@ -6994,7 +6474,9 @@ pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {...@@ -6994,7 +6474,9 @@ pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {
6994 ip.src_hash_deps.deinit(gpa);6474 ip.src_hash_deps.deinit(gpa);
6995 ip.nav_val_deps.deinit(gpa);6475 ip.nav_val_deps.deinit(gpa);
6996 ip.nav_ty_deps.deinit(gpa);6476 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);
6998 ip.zon_file_deps.deinit(gpa);6480 ip.zon_file_deps.deinit(gpa);
6999 ip.embed_file_deps.deinit(gpa);6481 ip.embed_file_deps.deinit(gpa);
7000 ip.namespace_deps.deinit(gpa);6482 ip.namespace_deps.deinit(gpa);
...@@ -7130,132 +6612,118 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7130,132 +6612,118 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
7130 .type_inferred_error_set => .{6612 .type_inferred_error_set => .{
7131 .inferred_error_set_type = @enumFromInt(data),6613 .inferred_error_set_type = @enumFromInt(data),
7132 },6614 },
71336615 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
7134 .type_opaque => .{ .opaque_type = ns: {6616 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
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 } },
71516617
7152 .type_struct => .{ .struct_type = ns: {6618 .type_struct => .{ .struct_type = ns: {
7153 const extra_list = unwrapped_index.getExtra(ip);6619 const extra_list = unwrapped_index.getExtra(ip);
7154 const extra_items = extra_list.view().items(.@"0");6620 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
7155 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);6621 break :ns switch (extra.data.flags.any_captures) {
7156 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));6622 .reified => .{ .reified = .{
7157 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).@"struct".fields.len);6623 .zir_index = extra.data.zir_index,
7158 if (flags.is_reified) {6624 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7159 assert(!flags.any_captures);6625 } },
7160 break :ns .{ .reified = .{6626 .false => .{ .declared = .{
7161 .zir_index = zir_index,6627 .zir_index = extra.data.zir_index,
7162 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),6628 .captures = .{ .owned = .empty },
7163 } };6629 } },
7164 }6630 .true => .{ .declared = .{
7165 break :ns .{ .declared = .{6631 .zir_index = extra.data.zir_index,
7166 .zir_index = zir_index,6632 .captures = .{ .owned = .{
7167 .captures = .{ .owned = if (flags.any_captures) .{6633 .tid = unwrapped_index.tid,
7168 .tid = unwrapped_index.tid,6634 .start = extra.end + 1,
7169 .start = end_extra_index + 1,6635 .len = extra_list.view().items(.@"0")[extra.end],
7170 .len = extra_list.view().items(.@"0")[end_extra_index],6636 } },
7171 } else CaptureValue.Slice.empty },6637 } },
7172 } };6638 };
7173 } },6639 } },
71746640 .type_struct_packed_auto,
7175 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {6641 .type_struct_packed_explicit,
6642 .type_struct_packed_auto_defaults,
6643 .type_struct_packed_explicit_defaults,
6644 => .{ .struct_type = ns: {
7176 const extra_list = unwrapped_index.getExtra(ip);6645 const extra_list = unwrapped_index.getExtra(ip);
7177 const extra_items = extra_list.view().items(.@"0");6646 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
7178 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);6647 break :ns switch (extra.data.bits.captures_len) {
7179 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));6648 .reified => .{ .reified = .{
7180 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).@"struct".fields.len);6649 .zir_index = extra.data.zir_index,
7181 if (flags.is_reified) {6650 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7182 assert(!flags.any_captures);6651 } },
7183 break :ns .{ .reified = .{6652 _ => |len| .{ .declared = .{
7184 .zir_index = zir_index,6653 .zir_index = extra.data.zir_index,
7185 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),6654 .captures = .{ .owned = .{
7186 } };6655 .tid = unwrapped_index.tid,
7187 }6656 .start = extra.end,
7188 break :ns .{ .declared = .{6657 .len = @intFromEnum(len),
7189 .zir_index = zir_index,6658 } },
7190 .captures = .{ .owned = if (flags.any_captures) .{6659 } },
7191 .tid = unwrapped_index.tid,6660 };
7192 .start = end_extra_index + 1,
7193 .len = extra_items[end_extra_index],
7194 } else CaptureValue.Slice.empty },
7195 } };
7196 } },6661 } },
7197 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
7198 .type_union => .{ .union_type = ns: {6662 .type_union => .{ .union_type = ns: {
7199 const extra_list = unwrapped_index.getExtra(ip);6663 const extra_list = unwrapped_index.getExtra(ip);
7200 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);6664 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
7201 if (extra.data.flags.is_reified) {6665 break :ns switch (extra.data.flags.any_captures) {
7202 assert(!extra.data.flags.any_captures);6666 .reified => .{ .reified = .{
7203 break :ns .{ .reified = .{
7204 .zir_index = extra.data.zir_index,6667 .zir_index = extra.data.zir_index,
7205 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),6668 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7206 } };6669 } },
7207 }6670 .false => .{ .declared = .{
7208 break :ns .{ .declared = .{6671 .zir_index = extra.data.zir_index,
7209 .zir_index = extra.data.zir_index,6672 .captures = .{ .owned = .empty },
7210 .captures = .{ .owned = if (extra.data.flags.any_captures) .{6673 } },
7211 .tid = unwrapped_index.tid,6674 .true => .{ .declared = .{
7212 .start = extra.end + 1,6675 .zir_index = extra.data.zir_index,
7213 .len = extra_list.view().items(.@"0")[extra.end],6676 .captures = .{ .owned = .{
7214 } else CaptureValue.Slice.empty },6677 .tid = unwrapped_index.tid,
7215 } };6678 .start = extra.end + 1,
6679 .len = extra_list.view().items(.@"0")[extra.end],
6680 } },
6681 } },
6682 };
7216 } },6683 } },
72176684 .type_union_packed_auto, .type_union_packed_explicit => .{ .union_type = ns: {
7218 .type_enum_auto => .{ .enum_type = ns: {
7219 const extra_list = unwrapped_index.getExtra(ip);6685 const extra_list = unwrapped_index.getExtra(ip);
7220 const extra = extraDataTrail(extra_list, EnumAuto, data);6686 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
7221 const zir_index = extra.data.zir_index.unwrap() orelse {6687 break :ns switch (extra.data.bits.captures_len) {
7222 assert(extra.data.captures_len == 0);6688 .reified => .{ .reified = .{
7223 break :ns .{ .generated_tag = .{6689 .zir_index = extra.data.zir_index,
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,
7230 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),6690 .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,
7239 } },6691 } },
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 };
7241 } },6701 } },
7242 .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {6702 .type_enum_auto, .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
7243 const extra_list = unwrapped_index.getExtra(ip);6703 const extra_list = unwrapped_index.getExtra(ip);
7244 const extra = extraDataTrail(extra_list, EnumExplicit, data);6704 const extra = extraDataTrail(extra_list, Tag.TypeEnum, data);
7245 const zir_index = extra.data.zir_index.unwrap() orelse {6705 break :ns switch (extra.data.bits.captures_len) {
7246 assert(extra.data.captures_len == 0);6706 .reified => .{ .reified = .{
7247 break :ns .{ .generated_tag = .{6707 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
7248 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),6708 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
7249 } };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 } },
7250 };6721 };
7251 if (extra.data.captures_len == std.math.maxInt(u32)) {6722 } },
7252 break :ns .{ .reified = .{6723 .type_opaque => .{ .opaque_type = ns: {
7253 .zir_index = zir_index,6724 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, data);
7254 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7255 } };
7256 }
7257 break :ns .{ .declared = .{6725 break :ns .{ .declared = .{
7258 .zir_index = zir_index,6726 .zir_index = extra.data.zir_index,
7259 .captures = .{ .owned = .{6727 .captures = .{ .owned = .{
7260 .tid = unwrapped_index.tid,6728 .tid = unwrapped_index.tid,
7261 .start = extra.end,6729 .start = extra.end,
...@@ -7263,7 +6731,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7263,7 +6731,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
7263 } },6731 } },
7264 } };6732 } };
7265 } },6733 } },
7266 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
72676734
7268 .undef => .{ .undef = @enumFromInt(data) },6735 .undef => .{ .undef = @enumFromInt(data) },
7269 .opt_null => .{ .opt = .{6736 .opt_null => .{ .opt = .{
...@@ -7390,17 +6857,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7390,17 +6857,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
7390 .storage = .{ .u64 = info.value },6857 .storage = .{ .u64 = info.value },
7391 } };6858 } };
7392 },6859 },
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 },
7404 .float_f16 => .{ .float = .{6860 .float_f16 => .{ .float = .{
7405 .ty = .f16_type,6861 .ty = .f16_type,
7406 .storage = .{ .f16 = @bitCast(@as(u16, @intCast(data))) },6862 .storage = .{ .f16 = @bitCast(@as(u16, @intCast(data))) },
...@@ -7488,7 +6944,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7488,7 +6944,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
7488 },6944 },
7489 .type_array_small,6945 .type_array_small,
7490 .type_vector,6946 .type_vector,
7491 .type_struct_packed,6947 .type_struct_packed_auto,
6948 .type_struct_packed_explicit,
7492 => .{ .aggregate = .{6949 => .{ .aggregate = .{
7493 .ty = ty,6950 .ty = ty,
7494 .storage = .{ .elems = &.{} },6951 .storage = .{ .elems = &.{} },
...@@ -7496,11 +6953,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7496,11 +6953,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
74966953
7497 // There is only one possible value precisely due to the6954 // There is only one possible value precisely due to the
7498 // fact that this values slice is fully populated!6955 // 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 => {
7500 const info = loadStructType(ip, ty);6960 const info = loadStructType(ip, ty);
7501 return .{ .aggregate = .{6961 return .{ .aggregate = .{
7502 .ty = ty,6962 .ty = ty,
7503 .storage = .{ .elems = @ptrCast(info.field_inits.get(ip)) },6963 .storage = .{ .elems = @ptrCast(info.field_defaults.get(ip)) },
7504 } };6964 } };
7505 },6965 },
75066966
...@@ -7516,11 +6976,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7516,11 +6976,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
7516 } };6976 } };
7517 },6977 },
75186978
7519 .type_enum_auto,
7520 .type_enum_explicit,
7521 .type_union,
7522 => .{ .empty_enum_value = ty },
7523
7524 else => unreachable,6979 else => unreachable,
7525 };6980 };
7526 },6981 },
...@@ -7566,6 +7021,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -7566,6 +7021,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
7566 },7021 },
7567 .enum_literal => .{ .enum_literal = @enumFromInt(data) },7022 .enum_literal => .{ .enum_literal = @enumFromInt(data) },
7568 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },7023 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },
7024 .bitpack => .{ .bitpack = extraData(unwrapped_index.getExtra(ip), Key.Bitpack, data) },
75697025
7570 .memoized_call => {7026 .memoized_call => {
7571 const extra_list = unwrapped_index.getExtra(ip);7027 const extra_list = unwrapped_index.getExtra(ip);
...@@ -7634,7 +7090,6 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke...@@ -7634,7 +7090,6 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
7634 .cc = type_function.data.flags.cc.unpack(),7090 .cc = type_function.data.flags.cc.unpack(),
7635 .is_var_args = type_function.data.flags.is_var_args,7091 .is_var_args = type_function.data.flags.is_var_args,
7636 .is_noinline = type_function.data.flags.is_noinline,7092 .is_noinline = type_function.data.flags.is_noinline,
7637 .is_generic = type_function.data.flags.is_generic,
7638 };7093 };
7639}7094}
76407095
...@@ -7893,45 +7348,6 @@ fn getOrPutKeyEnsuringAdditionalCapacity(...@@ -7893,45 +7348,6 @@ fn getOrPutKeyEnsuringAdditionalCapacity(
7893 .map_index = map_index,7348 .map_index = map_index,
7894 } };7349 } };
7895}7350}
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
7936pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {7352pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {
7937 var gop = try ip.getOrPutKey(gpa, io, tid, key);7353 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:...@@ -8084,12 +7500,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8084 });7500 });
8085 },7501 },
80867502
8087 .struct_type => unreachable, // use getStructType() instead7503 .struct_type => unreachable, // instead use: getDeclaredStructType, getReifiedStructType
8088 .tuple_type => unreachable, // use getTupleType() instead7504 .union_type => unreachable, // instead use: getDeclaredUnionType, getReifiedUnionType
8089 .union_type => unreachable, // use getUnionType() instead7505 .enum_type => unreachable, // instead use: getDeclaredEnumType, getReifiedEnumType, getGeneratedEnumTagType
8090 .opaque_type => unreachable, // use getOpaqueType() instead7506 .opaque_type => unreachable, // instead use: getDeclaredOpaqueType
80917507
8092 .enum_type => unreachable, // use getEnumType() instead7508 .tuple_type => unreachable, // use getTupleType() instead
8093 .func_type => unreachable, // use getFuncType() instead7509 .func_type => unreachable, // use getFuncType() instead
8094 .@"extern" => unreachable, // use getExtern() instead7510 .@"extern" => unreachable, // use getExtern() instead
8095 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead7511 .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:...@@ -8247,25 +7663,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8247 });7663 });
8248 },7664 },
82497665
8250 .int => |int| b: {7666 .int => |int| b: {
8251 assert(ip.isIntegerType(int.ty));7667 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 }
8269 switch (int.ty) {7668 switch (int.ty) {
8270 .u8_type => switch (int.storage) {7669 .u8_type => switch (int.storage) {
8271 .big_int => |big_int| {7670 .big_int => |big_int| {
...@@ -8282,7 +7681,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8282,7 +7681,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8282 });7681 });
8283 break :b;7682 break :b;
8284 },7683 },
8285 .lazy_align, .lazy_size => unreachable,
8286 },7684 },
8287 .u16_type => switch (int.storage) {7685 .u16_type => switch (int.storage) {
8288 .big_int => |big_int| {7686 .big_int => |big_int| {
...@@ -8299,7 +7697,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8299,7 +7697,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8299 });7697 });
8300 break :b;7698 break :b;
8301 },7699 },
8302 .lazy_align, .lazy_size => unreachable,
8303 },7700 },
8304 .u32_type => switch (int.storage) {7701 .u32_type => switch (int.storage) {
8305 .big_int => |big_int| {7702 .big_int => |big_int| {
...@@ -8316,7 +7713,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8316,7 +7713,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8316 });7713 });
8317 break :b;7714 break :b;
8318 },7715 },
8319 .lazy_align, .lazy_size => unreachable,
8320 },7716 },
8321 .i32_type => switch (int.storage) {7717 .i32_type => switch (int.storage) {
8322 .big_int => |big_int| {7718 .big_int => |big_int| {
...@@ -8334,7 +7730,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8334,7 +7730,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8334 });7730 });
8335 break :b;7731 break :b;
8336 },7732 },
8337 .lazy_align, .lazy_size => unreachable,
8338 },7733 },
8339 .usize_type => switch (int.storage) {7734 .usize_type => switch (int.storage) {
8340 .big_int => |big_int| {7735 .big_int => |big_int| {
...@@ -8355,7 +7750,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8355,7 +7750,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8355 break :b;7750 break :b;
8356 }7751 }
8357 },7752 },
8358 .lazy_align, .lazy_size => unreachable,
8359 },7753 },
8360 .comptime_int_type => switch (int.storage) {7754 .comptime_int_type => switch (int.storage) {
8361 .big_int => |big_int| {7755 .big_int => |big_int| {
...@@ -8390,7 +7784,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8390,7 +7784,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8390 break :b;7784 break :b;
8391 }7785 }
8392 },7786 },
8393 .lazy_align, .lazy_size => unreachable,
8394 },7787 },
8395 else => {},7788 else => {},
8396 }7789 }
...@@ -8427,7 +7820,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8427,7 +7820,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8427 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;7820 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
8428 try addInt(ip, gpa, io, tid, int.ty, tag, big_int.limbs);7821 try addInt(ip, gpa, io, tid, int.ty, tag, big_int.limbs);
8429 },7822 },
8430 .lazy_align, .lazy_size => unreachable,
8431 }7823 }
8432 },7824 },
84337825
...@@ -8468,7 +7860,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8468,7 +7860,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8468 assert(ip.isEnumType(enum_tag.ty));7860 assert(ip.isEnumType(enum_tag.ty));
8469 switch (ip.indexToKey(enum_tag.ty)) {7861 switch (ip.indexToKey(enum_tag.ty)) {
8470 .simple_type => assert(ip.isIntegerType(ip.typeOf(enum_tag.int))),7862 .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),
8472 else => unreachable,7864 else => unreachable,
8473 }7865 }
8474 items.appendAssumeCapacity(.{7866 items.appendAssumeCapacity(.{
...@@ -8477,11 +7869,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8477,11 +7869,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8477 });7869 });
8478 },7870 },
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
8485 .float => |float| {7872 .float => |float| {
8486 switch (float.ty) {7873 switch (float.ty) {
8487 .f16_type => items.appendAssumeCapacity(.{7874 .f16_type => items.appendAssumeCapacity(.{
...@@ -8525,15 +7912,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -8525,15 +7912,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8525 .aggregate => |aggregate| {7912 .aggregate => |aggregate| {
8526 const ty_key = ip.indexToKey(aggregate.ty);7913 const ty_key = ip.indexToKey(aggregate.ty);
8527 const len = ip.aggregateTypeLen(aggregate.ty);7914 const len = ip.aggregateTypeLen(aggregate.ty);
8528 const child = switch (ty_key) {7915 const child: Index, const sentinel: Index = switch (ty_key) {
8529 .array_type => |array_type| array_type.child,7916 .array_type => |array_type| .{ array_type.child, array_type.sentinel },
8530 .vector_type => |vector_type| vector_type.child,7917 .vector_type => |vector_type| .{ vector_type.child, .none },
8531 .tuple_type, .struct_type => .none,7918 .tuple_type => .{ .none, .none },
8532 else => unreachable,7919 .struct_type => child: {
8533 };7920 assert(ip.loadStructType(aggregate.ty).layout != .@"packed");
8534 const sentinel = switch (ty_key) {7921 break :child .{ .none, .none };
8535 .array_type => |array_type| array_type.sentinel,7922 },
8536 .vector_type, .tuple_type, .struct_type => .none,
8537 else => unreachable,7923 else => unreachable,
8538 };7924 };
8539 const len_including_sentinel = len + @intFromBool(sentinel != .none);7925 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:...@@ -8715,224 +8101,929 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
8715 extra.appendSliceAssumeCapacity(.{@ptrCast(aggregate.storage.elems)});8101 extra.appendSliceAssumeCapacity(.{@ptrCast(aggregate.storage.elems)});
8716 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});8102 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});
8717 },8103 },
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
8719 .memoized_call => |memoized_call| {8117 .memoized_call => |memoized_call| {
8720 for (memoized_call.arg_values) |arg| assert(arg != .none);8118 for (memoized_call.arg_values) |arg| assert(arg != .none);
8721 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".fields.len +8119 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".fields.len +
8722 memoized_call.arg_values.len);8120 memoized_call.arg_values.len);
8723 items.appendAssumeCapacity(.{8121 items.appendAssumeCapacity(.{
8724 .tag = .memoized_call,8122 .tag = .memoized_call,
8725 .data = addExtraAssumeCapacity(extra, MemoizedCall{8123 .data = addExtraAssumeCapacity(extra, MemoizedCall{
8726 .func = memoized_call.func,8124 .func = memoized_call.func,
8727 .args_len = @intCast(memoized_call.arg_values.len),8125 .args_len = @intCast(memoized_call.arg_values.len),
8728 .result = memoized_call.result,8126 .result = memoized_call.result,
8729 .branch_count = memoized_call.branch_count,8127 .branch_count = memoized_call.branch_count,
8730 }),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,
8731 });8650 });
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,
8733 },8691 },
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
8734 }8701 }
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 } };
8736}8721}
87378722
8738pub fn getUnion(8723pub fn getDeclaredEnumType(
8739 ip: *InternPool,8724 ip: *InternPool,
8740 gpa: Allocator,8725 gpa: Allocator,
8741 io: Io,8726 io: Io,
8742 tid: Zcu.PerThread.Id,8727 tid: Zcu.PerThread.Id,
8743 un: Key.Union,8728 ini: struct {
8744) Allocator.Error!Index {8729 zir_index: TrackedInst.Index,
8745 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .un = un });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 } } });
8746 defer gop.deinit();8752 defer gop.deinit();
8747 if (gop == .existing) return gop.existing;8753 if (gop == .existing) return .{ .existing = gop.existing };
8754
8748 const local = ip.getLocal(tid);8755 const local = ip.getLocal(tid);
8749 const items = local.getMutableItems(gpa, io);8756 const items = local.getMutableItems(gpa, io);
8750 const extra = local.getMutableExtra(gpa, io);8757 const extra = local.getMutableExtra(gpa, io);
8751 try items.ensureUnusedCapacity(1);8758 try items.ensureUnusedCapacity(1);
87528759
8753 assert(un.ty != .none);8760 const tag: Tag, const have_values: bool = if (ini.nonexhaustive)
8754 assert(un.val != .none);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
8755 items.appendAssumeCapacity(.{8797 items.appendAssumeCapacity(.{
8756 .tag = .union_value,8798 .tag = tag,
8757 .data = try addExtra(extra, un),8799 .data = extra_index,
8758 });8800 });
87598801 return .{ .wip = .{
8760 return gop.put();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 } };
8761}8813}
87628814
8763pub const UnionTypeInit = struct {8815pub fn getReifiedEnumType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8764 flags: packed struct {8816 zir_index: TrackedInst.Index,
8765 runtime_tag: LoadedUnionType.RuntimeTag,8817 type_hash: u64,
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 },
8774 fields_len: u32,8818 fields_len: u32,
8775 enum_tag_ty: Index,8819 nonexhaustive: bool,
8776 /// May have length 0 which leaves the values unset until later.8820 /// Explicitly specified int tag type, or `.none` if the int tag type is inferred.
8777 field_types: []const Index,8821 int_tag_type: Index,
8778 /// May have length 0 which leaves the values unset until later.8822}) Allocator.Error!WipContainerType.Result {
8779 /// The logic for `any_aligned_fields` is asserted to have been done before8823 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .enum_type = .{ .reified = .{
8780 /// calling this function.8824 .zir_index = ini.zir_index,
8781 field_aligns: []const Alignment,8825 .type_hash = ini.type_hash,
8782 key: union(enum) {8826 } } });
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);
8826 defer gop.deinit();8827 defer gop.deinit();
8827 if (gop == .existing) return .{ .existing = gop.existing };8828 if (gop == .existing) return .{ .existing = gop.existing };
88288829
8829 const local = ip.getLocal(tid);8830 const local = ip.getLocal(tid);
8830 const items = local.getMutableItems(gpa, io);8831 const items = local.getMutableItems(gpa, io);
8831 try items.ensureUnusedCapacity(1);
8832 const extra = local.getMutableExtra(gpa, io);8832 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 tag: Tag, const have_values: bool = if (ini.nonexhaustive)
8835 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);8836 .{ .type_enum_nonexhaustive, true }
8836 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".fields.len +8837 else if (ini.int_tag_type != .none)
8837 // TODO: fmt bug8838 .{ .type_enum_explicit, true }
8838 // zig fmt: off8839 else
8839 switch (ini.key) {8840 .{ .type_enum_auto, false };
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);
88468841
8847 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnion{8842 const field_name_map = try ip.addMap(gpa, io, tid, ini.fields_len);
8848 .flags = .{8843 errdefer local.mutate.maps.len -= 1;
8849 .any_captures = switch (ini.key) {8844
8850 inline .declared, .declared_owned_captures => |d| d.captures.len != 0,8845 const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined;
8851 .reified => false,8846 errdefer local.mutate.maps.len -= @intFromBool(have_values);
8852 },8847
8853 .runtime_tag = ini.flags.runtime_tag,8848 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len +
8854 .any_aligned_fields = ini.flags.any_aligned_fields,8849 1 + // zir_index
8855 .layout = ini.flags.layout,8850 2 + // type_hash
8856 .status = ini.flags.status,8851 @intFromBool(have_values) + // field_value_map
8857 .requires_comptime = ini.flags.requires_comptime,8852 ini.fields_len + // field_name
8858 .assumed_runtime_bits = ini.flags.assumed_runtime_bits,8853 (if (have_values) ini.fields_len else 0)); // field_value
8859 .assumed_pointer_aligned = ini.flags.assumed_pointer_aligned,8854
8860 .alignment = ini.flags.alignment,8855 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8861 .is_reified = switch (ini.key) {8856 .bits = .{
8862 .declared, .declared_owned_captures => false,8857 .captures_len = .reified,
8863 .reified => true,8858 .want_layout = false,
8864 },
8865 },8859 },
8866 .fields_len = ini.fields_len,
8867 .size = std.math.maxInt(u32),
8868 .padding = std.math.maxInt(u32),
8869 .name = undefined, // set by `finish`8860 .name = undefined, // set by `finish`
8870 .name_nav = undefined, // set by `finish`8861 .name_nav = undefined, // set by `finish`
8871 .namespace = undefined, // set by `finish`8862 .namespace = undefined, // set by `finish`
8872 .tag_ty = ini.enum_tag_ty,8863 .int_tag_type = ini.int_tag_type,
8873 .zir_index = switch (ini.key) {8864 .fields_len = ini.fields_len,
8874 inline else => |x| x.zir_index,8865 .field_name_map = field_name_map,
8875 },
8876 });8866 });
88778867 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
8878 items.appendAssumeCapacity(.{8874 items.appendAssumeCapacity(.{
8879 .tag = .type_union,8875 .tag = tag,
8880 .data = extra_index,8876 .data = extra_index,
8881 });8877 });
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) {8906 const local = ip.getLocal(tid);
8884 .declared => |d| if (d.captures.len != 0) {8907 const items = local.getMutableItems(gpa, io);
8885 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});8908 const extra = local.getMutableExtra(gpa, io);
8886 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});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,
8887 },8932 },
8888 .declared_owned_captures => |d| if (d.captures.len != 0) {8933 .name = undefined, // set by `finish`
8889 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});8934 .name_nav = undefined, // set by `finish`
8890 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures.get(ip))});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,
8891 },8948 },
8892 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),8949 .data = extra_index,
8893 }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 types8965pub fn getDeclaredOpaqueType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8896 if (ini.field_types.len > 0) {8966 zir_index: TrackedInst.Index,
8897 assert(ini.field_types.len == ini.fields_len);8967 captures: []const CaptureValue,
8898 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.field_types)});8968}) Allocator.Error!WipContainerType.Result {
8899 } else {8969 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .opaque_type = .{ .declared = .{
8900 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);8970 .zir_index = ini.zir_index,
8901 }8971 .captures = .{ .external = ini.captures },
8972 } } });
8973 defer gop.deinit();
8974 if (gop == .existing) return .{ .existing = gop.existing };
89028975
8903 // field alignments8976 const local = ip.getLocal(tid);
8904 if (ini.flags.any_aligned_fields) {8977 const items = local.getMutableItems(gpa, io);
8905 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);8978 const extra = local.getMutableExtra(gpa, io);
8906 if (ini.field_aligns.len > 0) {8979 try items.ensureUnusedCapacity(1);
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 }
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 });
8918 return .{ .wip = .{8994 return .{ .wip = .{
8919 .tid = tid,
8920 .index = gop.put(),8995 .index = gop.put(),
8921 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,8996 .tid = tid,
8922 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name_nav").?,8997 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
8923 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,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,
8924 } };9005 } };
8925}9006}
89269007
8927pub const WipNamespaceType = struct {9008pub const WipContainerType = struct {
8928 tid: Zcu.PerThread.Id,
8929 index: Index,9009 index: Index,
8930 type_name_extra_index: u32,9010 tid: Zcu.PerThread.Id,
8931 namespace_extra_index: u32,9011 type_name_index: u32,
8932 name_nav_extra_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
8934 pub fn setName(9025 pub fn setName(
8935 wip: WipNamespaceType,9026 wip: WipContainerType,
8936 ip: *InternPool,9027 ip: *InternPool,
8937 type_name: NullTerminatedString,9028 type_name: NullTerminatedString,
8938 /// This should be the `Nav` we are named after if we use the `.parent` name strategy; `.none` otherwise.9029 /// 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 {...@@ -8941,257 +9032,58 @@ pub const WipNamespaceType = struct {
8941 ) void {9032 ) void {
8942 const extra = ip.getLocalShared(wip.tid).extra.acquire();9033 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8943 const extra_items = extra.view().items(.@"0");9034 const extra_items = extra.view().items(.@"0");
8944 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);9035 extra_items[wip.type_name_index] = @intFromEnum(type_name);
8945 extra_items[wip.name_nav_extra_index] = @intFromEnum(name_nav);9036 extra_items[wip.name_nav_index] = @intFromEnum(name_nav);
8946 }9037 }
89479038
8948 pub fn finish(9039 pub fn finish(
8949 wip: WipNamespaceType,9040 wip: WipContainerType,
8950 ip: *InternPool,9041 ip: *InternPool,
8951 namespace: NamespaceIndex,9042 namespace: NamespaceIndex,
8952 ) Index {9043 ) Index {
8953 const extra = ip.getLocalShared(wip.tid).extra.acquire();9044 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8954 const extra_items = extra.view().items(.@"0");9045 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
8958 return wip.index;9049 return wip.index;
8959 }9050 }
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 {
8962 ip.remove(tid, wip.index);9053 ip.remove(tid, wip.index);
8963 }9054 }
89649055
8965 pub const Result = union(enum) {9056 pub const Result = union(enum) {
8966 wip: WipNamespaceType,9057 wip: WipContainerType,
8967 existing: Index,9058 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 },
9104 };9059 };
9060};
91059061
9106 const align_elements_len = if (ini.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;9062pub fn getUnion(
9107 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);9063 ip: *InternPool,
9108 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;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 +9073 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .un = un });
9111 // TODO: fmt bug9074 defer gop.deinit();
9112 // zig fmt: off9075 if (gop == .existing) return gop.existing;
9113 switch (ini.key) {9076 const local = ip.getLocal(tid);
9114 inline .declared, .declared_owned_captures => |d| @intFromBool(d.captures.len != 0) + d.captures.len,9077 const items = local.getMutableItems(gpa, io);
9115 .reified => 2, // type_hash: PackedU649078 const extra = local.getMutableExtra(gpa, io);
9116 } +9079 try items.ensureUnusedCapacity(1);
9117 // zig fmt: on9080
9118 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets9081 items.appendAssumeCapacity(.{
9119 align_elements_len + comptime_elements_len +9082 .tag = .union_value,
9120 1); // names_map9083 .data = try addExtra(extra, un),
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,
9158 });9084 });
9159 switch (ini.key) {9085
9160 .declared => |d| if (d.captures.len != 0) {9086 return gop.put();
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 } };
9195}9087}
91969088
9197pub const TupleTypeInit = struct {9089pub const TupleTypeInit = struct {
...@@ -9252,10 +9144,7 @@ pub const GetFuncTypeKey = struct {...@@ -9252,10 +9144,7 @@ pub const GetFuncTypeKey = struct {
9252 /// `null` means generic.9144 /// `null` means generic.
9253 cc: ?std.builtin.CallingConvention = .auto,9145 cc: ?std.builtin.CallingConvention = .auto,
9254 is_var_args: bool = false,9146 is_var_args: bool = false,
9255 is_generic: bool = false,
9256 is_noinline: bool = false,9147 is_noinline: bool = false,
9257 section_is_generic: bool = false,
9258 addrspace_is_generic: bool = false,
9259};9148};
92609149
9261pub fn getFuncType(9150pub fn getFuncType(
...@@ -9293,7 +9182,6 @@ pub fn getFuncType(...@@ -9293,7 +9182,6 @@ pub fn getFuncType(
9293 .is_var_args = key.is_var_args,9182 .is_var_args = key.is_var_args,
9294 .has_comptime_bits = key.comptime_bits != 0,9183 .has_comptime_bits = key.comptime_bits != 0,
9295 .has_noalias_bits = key.noalias_bits != 0,9184 .has_noalias_bits = key.noalias_bits != 0,
9296 .is_generic = key.is_generic,
9297 .is_noinline = key.is_noinline,9185 .is_noinline = key.is_noinline,
9298 },9186 },
9299 });9187 });
...@@ -9427,7 +9315,7 @@ pub fn getFuncDecl(...@@ -9427,7 +9315,7 @@ pub fn getFuncDecl(
94279315
9428 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{9316 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
9429 .analysis = .{9317 .analysis = .{
9430 .is_analyzed = false,9318 .want_runtime_analysis = false,
9431 .branch_hint = .none,9319 .branch_hint = .none,
9432 .is_noinline = key.is_noinline,9320 .is_noinline = key.is_noinline,
9433 .has_error_trace = false,9321 .has_error_trace = false,
...@@ -9480,7 +9368,6 @@ pub const GetFuncDeclIesKey = struct {...@@ -9480,7 +9368,6 @@ pub const GetFuncDeclIesKey = struct {
9480 /// null means generic.9368 /// null means generic.
9481 cc: ?std.builtin.CallingConvention,9369 cc: ?std.builtin.CallingConvention,
9482 is_var_args: bool,9370 is_var_args: bool,
9483 is_generic: bool,
9484 is_noinline: bool,9371 is_noinline: bool,
9485 zir_body_inst: TrackedInst.Index,9372 zir_body_inst: TrackedInst.Index,
9486 lbrace_line: u32,9373 lbrace_line: u32,
...@@ -9538,7 +9425,7 @@ pub fn getFuncDeclIes(...@@ -9538,7 +9425,7 @@ pub fn getFuncDeclIes(
95389425
9539 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{9426 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
9540 .analysis = .{9427 .analysis = .{
9541 .is_analyzed = false,9428 .want_runtime_analysis = false,
9542 .branch_hint = .none,9429 .branch_hint = .none,
9543 .is_noinline = key.is_noinline,9430 .is_noinline = key.is_noinline,
9544 .has_error_trace = false,9431 .has_error_trace = false,
...@@ -9564,7 +9451,6 @@ pub fn getFuncDeclIes(...@@ -9564,7 +9451,6 @@ pub fn getFuncDeclIes(
9564 .is_var_args = key.is_var_args,9451 .is_var_args = key.is_var_args,
9565 .has_comptime_bits = key.comptime_bits != 0,9452 .has_comptime_bits = key.comptime_bits != 0,
9566 .has_noalias_bits = key.noalias_bits != 0,9453 .has_noalias_bits = key.noalias_bits != 0,
9567 .is_generic = key.is_generic,
9568 .is_noinline = key.is_noinline,9454 .is_noinline = key.is_noinline,
9569 },9455 },
9570 });9456 });
...@@ -9737,7 +9623,7 @@ pub fn getFuncInstance(...@@ -9737,7 +9623,7 @@ pub fn getFuncInstance(
97379623
9738 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{9624 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
9739 .analysis = .{9625 .analysis = .{
9740 .is_analyzed = false,9626 .want_runtime_analysis = false,
9741 .branch_hint = .none,9627 .branch_hint = .none,
9742 .is_noinline = arg.is_noinline,9628 .is_noinline = arg.is_noinline,
9743 .has_error_trace = false,9629 .has_error_trace = false,
...@@ -9838,7 +9724,7 @@ fn getFuncInstanceIes(...@@ -9838,7 +9724,7 @@ fn getFuncInstanceIes(
98389724
9839 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{9725 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
9840 .analysis = .{9726 .analysis = .{
9841 .is_analyzed = false,9727 .want_runtime_analysis = false,
9842 .branch_hint = .none,9728 .branch_hint = .none,
9843 .is_noinline = arg.is_noinline,9729 .is_noinline = arg.is_noinline,
9844 .has_error_trace = false,9730 .has_error_trace = false,
...@@ -9864,7 +9750,6 @@ fn getFuncInstanceIes(...@@ -9864,7 +9750,6 @@ fn getFuncInstanceIes(
9864 .is_var_args = false,9750 .is_var_args = false,
9865 .has_comptime_bits = false,9751 .has_comptime_bits = false,
9866 .has_noalias_bits = arg.noalias_bits != 0,9752 .has_noalias_bits = arg.noalias_bits != 0,
9867 .is_generic = false,
9868 .is_noinline = arg.is_noinline,9753 .is_noinline = arg.is_noinline,
9869 },9754 },
9870 });9755 });
...@@ -9972,444 +9857,6 @@ fn finishFuncInstance(...@@ -9972,444 +9857,6 @@ fn finishFuncInstance(
9972 ] = @intFromEnum(nav_index);9857 ] = @intFromEnum(nav_index);
9973}9858}
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
10413pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {9860pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
10414 const full_hash = key.hash64(ip);9861 const full_hash = key.hash64(ip);
10415 const hash: u32 = @truncate(full_hash >> 32);9862 const hash: u32 = @truncate(full_hash >> 32);
...@@ -10427,28 +9874,15 @@ pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {...@@ -10427,28 +9874,15 @@ pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
10427 }9874 }
10428}9875}
104299876
10430fn addStringsToMap(9877fn 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(
10444 ip: *InternPool,9878 ip: *InternPool,
10445 map_index: MapIndex,9879 map_index: MapIndex,
10446 indexes: []const Index,9880 strings: []const NullTerminatedString,
10447) void {9881) void {
10448 const map = map_index.get(ip);9882 const map = map_index.get(ip);
10449 const adapter: Index.Adapter = .{ .indexes = indexes };9883 const adapter: NullTerminatedString.Adapter = .{ .strings = strings };
10450 for (indexes) |index| {9884 for (strings) |string| {
10451 const gop = map.getOrPutAssumeCapacityAdapted(index, adapter);9885 const gop = map.getOrPutAssumeCapacityAdapted(string, adapter);
10452 assert(!gop.found_existing);9886 assert(!gop.found_existing);
10453 }9887 }
10454}9888}
...@@ -10545,7 +9979,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -10545,7 +9979,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
10545 Tag.TypePointer.PackedOffset,9979 Tag.TypePointer.PackedOffset,
10546 Tag.TypeUnion.Flags,9980 Tag.TypeUnion.Flags,
10547 Tag.TypeStruct.Flags,9981 Tag.TypeStruct.Flags,
10548 Tag.TypeStructPacked.Flags,9982 Tag.TypeStructPacked.Bits,
9983 Tag.TypeUnionPacked.Bits,
9984 Tag.TypeEnum.Bits,
10549 => @bitCast(@field(item, field.name)),9985 => @bitCast(@field(item, field.name)),
105509986
10551 else => @compileError("bad field type: " ++ @typeName(field.type)),9987 else => @compileError("bad field type: " ++ @typeName(field.type)),
...@@ -10607,8 +10043,10 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -10607,8 +10043,10 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
10607 Tag.TypePointer.PackedOffset,10043 Tag.TypePointer.PackedOffset,
10608 Tag.TypeUnion.Flags,10044 Tag.TypeUnion.Flags,
10609 Tag.TypeStruct.Flags,10045 Tag.TypeStruct.Flags,
10610 Tag.TypeStructPacked.Flags,
10611 FuncAnalysis,10046 FuncAnalysis,
10047 Tag.TypeStructPacked.Bits,
10048 Tag.TypeUnionPacked.Bits,
10049 Tag.TypeEnum.Bits,
10612 => @bitCast(extra_item),10050 => @bitCast(extra_item),
1061310051
10614 else => @compileError("bad field type: " ++ @typeName(field.type)),10052 else => @compileError("bad field type: " ++ @typeName(field.type)),
...@@ -10786,7 +10224,7 @@ pub fn getCoerced(...@@ -10786,7 +10224,7 @@ pub fn getCoerced(
10786 .int => |int| switch (ip.indexToKey(new_ty)) {10224 .int => |int| switch (ip.indexToKey(new_ty)) {
10787 .enum_type => return ip.get(gpa, io, tid, .{ .enum_tag = .{10225 .enum_type => return ip.get(gpa, io, tid, .{ .enum_tag = .{
10788 .ty = new_ty,10226 .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),
10790 } }),10228 } }),
10791 .ptr_type => switch (int.storage) {10229 .ptr_type => switch (int.storage) {
10792 inline .u64, .i64 => |int_val| return ip.get(gpa, io, tid, .{ .ptr = .{10230 inline .u64, .i64 => |int_val| return ip.get(gpa, io, tid, .{ .ptr = .{
...@@ -10795,7 +10233,6 @@ pub fn getCoerced(...@@ -10795,7 +10233,6 @@ pub fn getCoerced(
10795 .byte_offset = @intCast(int_val),10233 .byte_offset = @intCast(int_val),
10796 } }),10234 } }),
10797 .big_int => unreachable, // must be a usize10235 .big_int => unreachable, // must be a usize
10798 .lazy_align, .lazy_size => {},
10799 },10236 },
10800 else => if (ip.isIntegerType(new_ty))10237 else => if (ip.isIntegerType(new_ty))
10801 return ip.getCoercedInts(gpa, io, tid, int, new_ty),10238 return ip.getCoercedInts(gpa, io, tid, int, new_ty),
...@@ -10825,11 +10262,11 @@ pub fn getCoerced(...@@ -10825,11 +10262,11 @@ pub fn getCoerced(
10825 const index = enum_type.nameIndex(ip, enum_literal).?;10262 const index = enum_type.nameIndex(ip, enum_literal).?;
10826 return ip.get(gpa, io, tid, .{ .enum_tag = .{10263 return ip.get(gpa, io, tid, .{ .enum_tag = .{
10827 .ty = new_ty,10264 .ty = new_ty,
10828 .int = if (enum_type.values.len != 0)10265 .int = if (enum_type.field_values.len != 0)
10829 enum_type.values.get(ip)[index]10266 enum_type.field_values.get(ip)[index]
10830 else10267 else
10831 try ip.get(gpa, io, tid, .{ .int = .{10268 try ip.get(gpa, io, tid, .{ .int = .{
10832 .ty = enum_type.tag_ty,10269 .ty = enum_type.int_tag_type,
10833 .storage = .{ .u64 = index },10270 .storage = .{ .u64 = index },
10834 } }),10271 } }),
10835 } });10272 } });
...@@ -11193,10 +10630,78 @@ pub fn dump(ip: *const InternPool) void {...@@ -11193,10 +10630,78 @@ pub fn dump(ip: *const InternPool) void {
11193 const stderr = std.debug.lockStderr(&buffer);10630 const stderr = std.debug.lockStderr(&buffer);
11194 defer std.debug.unlockStderr();10631 defer std.debug.unlockStderr();
11195 const w = &stderr.file_writer.interface;10632 const w = &stderr.file_writer.interface;
10633 dumpDependencyStatsFallible(ip, w) catch return;
11196 dumpStatsFallible(ip, w, std.heap.page_allocator) catch return;10634 dumpStatsFallible(ip, w, std.heap.page_allocator) catch return;
11197 dumpAllFallible(ip, w) catch return;10635 dumpAllFallible(ip, w) catch return;
11198}10636}
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
11200fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !void {10705fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !void {
11201 var items_len: usize = 0;10706 var items_len: usize = 0;
11202 var extra_len: usize = 0;10707 var extra_len: usize = 0;
...@@ -11211,10 +10716,10 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -11211,10 +10716,10 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
11211 const limbs_size = 8 * limbs_len;10716 const limbs_size = 8 * limbs_len;
1121210717
11213 // TODO: map overhead size is not taken into account10718 // 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(10721 try w.print(
11217 \\InternPool size: {d} bytes10722 \\InternPool values: {d} bytes
11218 \\ {d} items: {d} bytes10723 \\ {d} items: {d} bytes
11219 \\ {d} extra: {d} bytes10724 \\ {d} extra: {d} bytes
11220 \\ {d} limbs: {d} bytes10725 \\ {d} limbs: {d} bytes
...@@ -11235,6 +10740,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -11235,6 +10740,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
11235 };10740 };
11236 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);10741 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
11237 for (ip.locals) |*local| {10742 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;
11238 const items = local.shared.items.view().slice();10745 const items = local.shared.items.view().slice();
11239 const extra_list = local.shared.extra;10746 const extra_list = local.shared.extra;
11240 const extra_items = extra_list.view().items(.@"0");10747 const extra_items = extra_list.view().items(.@"0");
...@@ -11266,98 +10773,137 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -11266,98 +10773,137 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
11266 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);10773 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
11267 },10774 },
11268 .type_inferred_error_set => 0,10775 .type_inferred_error_set => 0,
11269 .type_enum_explicit, .type_enum_nonexhaustive => b: {10776 .type_tuple => b: {
11270 const info = extraData(extra_list, EnumExplicit, data);10777 const info = extraData(extra_list, TypeTuple, data);
11271 var ints = @typeInfo(EnumExplicit).@"struct".fields.len;10778 break :b @sizeOf(TypeTuple) + (@sizeOf(u32) * 2 * info.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;
11285 },10779 },
11286 .type_opaque => b: {10780 .type_function => b: {
11287 const info = extraData(extra_list, Tag.TypeOpaque, data);10781 const info = extraData(extra_list, Tag.TypeFunction, data);
11288 const ints = @typeInfo(Tag.TypeOpaque).@"struct".fields.len + info.captures_len;10782 break :b @sizeOf(Tag.TypeFunction) +
11289 break :b @sizeOf(u32) * ints;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));
11290 },10786 },
10787
11291 .type_struct => b: {10788 .type_struct => b: {
10789 var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
11292 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);10790 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
11293 const info = extra.data;10791 switch (extra.data.flags.any_captures) {
11294 var ints: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;10792 .reified => n += 2, // type_hash: PackedU64
11295 if (info.flags.any_captures) {10793 .true => {
11296 const captures_len = extra_items[extra.end];10794 n += 1; // captures_len: u32
11297 ints += 1 + captures_len;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
11298 }10806 }
11299 ints += info.fields_len; // types10807 if (extra.data.flags.any_comptime_fields) {
11300 ints += 1; // names_map10808 n += (extra.data.fields_len + 31) / 32; // field_is_comptime_bits: u32
11301 ints += info.fields_len; // names10809 }
11302 if (info.flags.any_default_inits)10810 if (extra.data.flags.layout == .auto) {
11303 ints += info.fields_len; // inits10811 n += extra.data.fields_len; // field_runtime_order: RuntimeOrder
11304 if (info.flags.any_aligned_fields)10812 }
11305 ints += (info.fields_len + 3) / 4; // aligns10813 n += extra.data.fields_len; // field_offset: u32
11306 if (info.flags.any_comptime_fields)10814 break :b n * @sizeOf(u32);
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;
11312 },10815 },
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;
11314 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);10818 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
11315 const captures_len = if (extra.data.flags.any_captures)10819 switch (extra.data.bits.captures_len) {
11316 extra_items[extra.end]10820 .reified => n += 2, // type_hash: PackedU64
11317 else10821 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
11318 0;10822 }
11319 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +10823 n += extra.data.fields_len; // field_name: NullTerminatedString
11320 @intFromBool(extra.data.flags.any_captures) + captures_len +10824 n += extra.data.fields_len; // field_type: Index
11321 extra.data.fields_len * 2);10825 break :b n * @sizeOf(u32);
11322 },10826 },
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;
11324 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);10829 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
11325 const captures_len = if (extra.data.flags.any_captures)10830 switch (extra.data.bits.captures_len) {
11326 extra_items[extra.end]10831 .reified => n += 2, // type_hash: PackedU64
11327 else10832 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
11328 0;10833 }
11329 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +10834 n += extra.data.fields_len; // field_name: NullTerminatedString
11330 @intFromBool(extra.data.flags.any_captures) + captures_len +10835 n += extra.data.fields_len; // field_type: Index
11331 extra.data.fields_len * 3);10836 n += extra.data.fields_len; // field_default: Index
11332 },10837 break :b n * @sizeOf(u32);
11333 .type_tuple => b: {
11334 const info = extraData(extra_list, TypeTuple, data);
11335 break :b @sizeOf(TypeTuple) + (@sizeOf(u32) * 2 * info.fields_len);
11336 },10838 },
11337
11338 .type_union => b: {10839 .type_union => b: {
10840 var n: usize = @typeInfo(Tag.TypeUnion).@"struct".fields.len;
11339 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);10841 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
11340 const captures_len = if (extra.data.flags.any_captures)10842 switch (extra.data.flags.any_captures) {
11341 extra_items[extra.end]10843 .reified => n += 2, // type_hash: PackedU64
11342 else10844 .true => {
11343 0;10845 n += 1; // captures_len: u32
11344 const per_field = @sizeOf(u32); // field type10846 n += extra_items[extra.end]; // capture: CaptureValue
11345 // 1 byte per field for alignment, rounded up to the nearest 4 bytes10847 },
11346 const alignments = if (extra.data.flags.any_aligned_fields)10848 .false => {},
11347 ((extra.data.fields_len + 3) / 4) * 410849 }
11348 else10850 n += extra.data.fields_len; // field_type: Index
11349 0;10851 if (extra.data.flags.any_field_aligns) {
11350 break :b @sizeOf(Tag.TypeUnion) +10852 n += (extra.data.fields_len + 3) / 4; // field_align: Alignment
11351 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +10853 }
11352 (extra.data.fields_len * per_field) + alignments;10854 break :b n * @sizeOf(u32);
11353 },10855 },
1135410856 .type_union_packed_auto, .type_union_packed_explicit => b: {
11355 .type_function => b: {10857 var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".fields.len;
11356 const info = extraData(extra_list, Tag.TypeFunction, data);10858 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
11357 break :b @sizeOf(Tag.TypeFunction) +10859 switch (extra.data.bits.captures_len) {
11358 (@sizeOf(Index) * info.params_len) +10860 .reified => n += 2, // type_hash: PackedU64
11359 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +10861 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
11360 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));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);
11361 },10907 },
1136210908
11363 .undef => 0,10909 .undef => 0,
...@@ -11393,8 +10939,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -11393,8 +10939,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
11393 break :b @sizeOf(Int) + int.limbs_len * @sizeOf(Limb);10939 break :b @sizeOf(Int) + int.limbs_len * @sizeOf(Limb);
11394 },10940 },
1139510941
11396 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
11397
11398 .error_set_error, .error_union_error => @sizeOf(Key.Error),10942 .error_set_error, .error_union_error => @sizeOf(Key.Error),
11399 .error_union_payload => @sizeOf(Tag.TypeValue),10943 .error_union_payload => @sizeOf(Tag.TypeValue),
11400 .enum_literal => 0,10944 .enum_literal => 0,
...@@ -11432,6 +10976,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -11432,6 +10976,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
11432 .func_coerced => @sizeOf(Tag.FuncCoerced),10976 .func_coerced => @sizeOf(Tag.FuncCoerced),
11433 .only_possible_value => 0,10977 .only_possible_value => 0,
11434 .union_value => @sizeOf(Key.Union),10978 .union_value => @sizeOf(Key.Union),
10979 .bitpack => 2 * @sizeOf(u32),
1143510980
11436 .memoized_call => b: {10981 .memoized_call => b: {
11437 const info = extraData(extra_list, MemoizedCall, data);10982 const info = extraData(extra_list, MemoizedCall, data);
...@@ -11458,6 +11003,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -11458,6 +11003,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1145811003
11459fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {11004fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
11460 for (ip.locals, 0..) |*local, tid| {11005 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;
11461 const items = local.shared.items.view();11008 const items = local.shared.items.view();
11462 for (11009 for (
11463 items.items(.tag)[0..local.mutate.items.len],11010 items.items(.tag)[0..local.mutate.items.len],
...@@ -11484,16 +11031,20 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {...@@ -11484,16 +11031,20 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
11484 .type_anyerror_union,11031 .type_anyerror_union,
11485 .type_error_set,11032 .type_error_set,
11486 .type_inferred_error_set,11033 .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,
11487 .type_enum_explicit,11045 .type_enum_explicit,
11488 .type_enum_nonexhaustive,11046 .type_enum_nonexhaustive,
11489 .type_enum_auto,
11490 .type_opaque,11047 .type_opaque,
11491 .type_struct,
11492 .type_struct_packed,
11493 .type_struct_packed_inits,
11494 .type_tuple,
11495 .type_union,
11496 .type_function,
11497 .undef,11048 .undef,
11498 .ptr_nav,11049 .ptr_nav,
11499 .ptr_comptime_alloc,11050 .ptr_comptime_alloc,
...@@ -11517,8 +11068,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {...@@ -11517,8 +11068,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
11517 .int_small,11068 .int_small,
11518 .int_positive,11069 .int_positive,
11519 .int_negative,11070 .int_negative,
11520 .int_lazy_align,
11521 .int_lazy_size,
11522 .error_set_error,11071 .error_set_error,
11523 .error_union_error,11072 .error_union_error,
11524 .error_union_payload,11073 .error_union_payload,
...@@ -11542,6 +11091,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {...@@ -11542,6 +11091,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
11542 .func_instance,11091 .func_instance,
11543 .func_coerced,11092 .func_coerced,
11544 .union_value,11093 .union_value,
11094 .bitpack,
11545 .memoized_call,11095 .memoized_call,
11546 => try w.print("{d}", .{data}),11096 => try w.print("{d}", .{data}),
1154711097
...@@ -11581,7 +11131,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator,...@@ -11581,7 +11131,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator,
11581 const info = extraData(extra_list, Tag.FuncInstance, data);11131 const info = extraData(extra_list, Tag.FuncInstance, data);
1158211132
11583 const gop = try instances.getOrPut(arena, info.generic_owner);11133 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
11586 try gop.value_ptr.append(11136 try gop.value_ptr.append(
11587 arena,11137 arena,
...@@ -11722,6 +11272,7 @@ pub fn createDeclNav(...@@ -11722,6 +11272,7 @@ pub fn createDeclNav(
11722 .analysis = .{11272 .analysis = .{
11723 .namespace = namespace,11273 .namespace = namespace,
11724 .zir_index = zir_index,11274 .zir_index = zir_index,
11275 .wanted = false,
11725 },11276 },
11726 .status = .unresolved,11277 .status = .unresolved,
11727 }));11278 }));
...@@ -12245,16 +11796,20 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -12245,16 +11796,20 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
12245 .type_anyerror_union,11796 .type_anyerror_union,
12246 .type_error_set,11797 .type_error_set,
12247 .type_inferred_error_set,11798 .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,
12248 .type_enum_auto,11809 .type_enum_auto,
12249 .type_enum_explicit,11810 .type_enum_explicit,
12250 .type_enum_nonexhaustive,11811 .type_enum_nonexhaustive,
12251 .type_opaque,11812 .type_opaque,
12252 .type_struct,
12253 .type_struct_packed,
12254 .type_struct_packed_inits,
12255 .type_tuple,
12256 .type_union,
12257 .type_function,
12258 => .type_type,11813 => .type_type,
1225911814
12260 .undef,11815 .undef,
...@@ -12278,8 +11833,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -12278,8 +11833,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
12278 .opt_payload,11833 .opt_payload,
12279 .error_union_payload,11834 .error_union_payload,
12280 .int_small,11835 .int_small,
12281 .int_lazy_align,
12282 .int_lazy_size,
12283 .error_set_error,11836 .error_set_error,
12284 .error_union_error,11837 .error_union_error,
12285 .enum_tag,11838 .enum_tag,
...@@ -12293,6 +11846,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -12293,6 +11846,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
12293 .bytes,11846 .bytes,
12294 .aggregate,11847 .aggregate,
12295 .repeated,11848 .repeated,
11849 .bitpack,
12296 => |t| {11850 => |t| {
12297 const extra_list = unwrapped_index.getExtra(ip);11851 const extra_list = unwrapped_index.getExtra(ip);
12298 return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]);11852 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 {...@@ -12389,20 +11943,6 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
12389 ]);11943 ]);
12390}11944}
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
12406pub fn isUndef(ip: *const InternPool, val: Index) bool {11946pub fn isUndef(ip: *const InternPool, val: Index) bool {
12407 return val == .undef or val.unwrap(ip).getTag(ip) == .undef;11947 return val == .undef or val.unwrap(ip).getTag(ip) == .undef;
12408}11948}
...@@ -12613,22 +12153,26 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {...@@ -12613,22 +12153,26 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
12613 .type_inferred_error_set,12153 .type_inferred_error_set,
12614 => .error_set,12154 => .error_set,
1261512155
12616 .type_enum_auto,
12617 .type_enum_explicit,
12618 .type_enum_nonexhaustive,
12619 => .@"enum",
12620
12621 .simple_type => unreachable, // handled via Index tag above12156 .simple_type => unreachable, // handled via Index tag above
1262212157
12623 .type_opaque => .@"opaque",12158 .type_tuple => .@"struct",
1262412159
12625 .type_struct,12160 .type_struct,
12626 .type_struct_packed,12161 .type_struct_packed_auto,
12627 .type_struct_packed_inits,12162 .type_struct_packed_explicit,
12628 .type_tuple,12163 .type_struct_packed_auto_defaults,
12164 .type_struct_packed_explicit_defaults,
12629 => .@"struct",12165 => .@"struct",
1263012166 .type_union,
12631 .type_union => .@"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
12633 .type_function => .@"fn",12177 .type_function => .@"fn",
1263412178
...@@ -12658,8 +12202,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {...@@ -12658,8 +12202,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
12658 .int_small,12202 .int_small,
12659 .int_positive,12203 .int_positive,
12660 .int_negative,12204 .int_negative,
12661 .int_lazy_align,
12662 .int_lazy_size,
12663 .error_set_error,12205 .error_set_error,
12664 .error_union_error,12206 .error_union_error,
12665 .error_union_payload,12207 .error_union_payload,
...@@ -12684,6 +12226,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {...@@ -12684,6 +12226,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
12684 .bytes,12226 .bytes,
12685 .aggregate,12227 .aggregate,
12686 .repeated,12228 .repeated,
12229 .bitpack,
12687 // memoization, not types12230 // memoization, not types
12688 .memoized_call,12231 .memoized_call,
12689 => unreachable,12232 => unreachable,
...@@ -12871,22 +12414,42 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {...@@ -12871,22 +12414,42 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
12871 };12414 };
12872}12415}
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.
12875pub fn addFieldName(12420pub fn addFieldName(
12876 ip: *InternPool,12421 ip: *InternPool,
12877 extra: Local.Extra,12422 names: NullTerminatedString.Slice,
12878 names_map: MapIndex,12423 map: MapIndex,
12879 names_start: u32,
12880 name: NullTerminatedString,12424 name: NullTerminatedString,
12881) ?u32 {12425) ?u32 {
12882 const extra_items = extra.view().items(.@"0");12426 const m = map.get(ip);
12883 const map = names_map.get(ip);12427 const field_idx = m.count();
12884 const field_index = map.count();12428 const names_slice = names.get(ip);
12885 const strings = extra_items[names_start..][0..field_index];12429 names_slice[field_idx] = name;
12886 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };12430 const adapter: NullTerminatedString.Adapter = .{ .strings = names_slice[0..field_idx] };
12887 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);12431 const gop = m.getOrPutAssumeCapacityAdapted(name, adapter);
12888 if (gop.found_existing) return @intCast(gop.index);12432 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);
12890 return null;12453 return null;
12891}12454}
1289212455
...@@ -13169,3 +12732,275 @@ const PackedCallingConvention = packed struct(u18) {...@@ -13169,3 +12732,275 @@ const PackedCallingConvention = packed struct(u18) {
13169 };12732 };
13170 }12733 }
13171};12734};
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...@@ -66,7 +66,7 @@ pub fn parse(gpa: Allocator, ast: *const Ast, rng: std.Random, options: ParseOpt
66 .gpa = gpa,66 .gpa = gpa,
67 .ast = ast.*,67 .ast = ast.*,
68 .arena = arena_instance.allocator(),68 .arena = arena_instance.allocator(),
69 .errors = .{},69 .errors = .empty,
7070
71 .name = undefined,71 .name = undefined,
72 .id = 0,72 .id = 0,
...@@ -74,10 +74,10 @@ pub fn parse(gpa: Allocator, ast: *const Ast, rng: std.Random, options: ParseOpt...@@ -74,10 +74,10 @@ pub fn parse(gpa: Allocator, ast: *const Ast, rng: std.Random, options: ParseOpt
74 .version_node = undefined,74 .version_node = undefined,
75 .dependencies = .{},75 .dependencies = .{},
76 .dependencies_node = .none,76 .dependencies_node = .none,
77 .paths = .{},77 .paths = .empty,
78 .allow_missing_paths_field = options.allow_missing_paths_field,78 .allow_missing_paths_field = options.allow_missing_paths_field,
79 .minimum_zig_version = null,79 .minimum_zig_version = null,
80 .buf = .{},80 .buf = .empty,
81 };81 };
82 defer p.buf.deinit(gpa);82 defer p.buf.deinit(gpa);
83 defer p.errors.deinit(gpa);83 defer p.errors.deinit(gpa);
src/Sema.zig+4104-7112
...@@ -173,13 +173,20 @@ const ComptimeAlloc = struct {...@@ -173,13 +173,20 @@ const ComptimeAlloc = struct {
173 runtime_index: RuntimeIndex,173 runtime_index: RuntimeIndex,
174};174};
175175
176/// Asserts that `ty` is not an OPV type.
176/// `src` may be `null` if `is_const` will be set.177/// `src` may be `null` if `is_const` will be set.
177fn newComptimeAlloc(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, alignment: Alignment) !ComptimeAllocIndex {178fn newComptimeAlloc(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, alignment: Alignment) !ComptimeAllocIndex {
178 const pt = sema.pt;179 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
180 const idx = sema.comptime_allocs.items.len;187 const idx = sema.comptime_allocs.items.len;
181 try sema.comptime_allocs.append(sema.gpa, .{188 try sema.comptime_allocs.append(sema.gpa, .{
182 .val = .{ .interned = init_val.toIntern() },189 .val = .{ .interned = (try pt.undefValue(ty)).toIntern() },
183 .is_const = false,190 .is_const = false,
184 .src = src,191 .src = src,
185 .alignment = alignment,192 .alignment = alignment,
...@@ -393,7 +400,7 @@ pub const Block = struct {...@@ -393,7 +400,7 @@ pub const Block = struct {
393 /// The name of the current "context" for naming namespace types.400 /// The name of the current "context" for naming namespace types.
394 /// The interpretation of this depends on the name strategy in ZIR, but the name401 /// The interpretation of this depends on the name strategy in ZIR, but the name
395 /// is always incorporated into the type name somehow.402 /// is always incorporated into the type name somehow.
396 /// See `Sema.createTypeName`.403 /// See `Sema.setTypeName`.
397 type_name_ctx: InternPool.NullTerminatedString,404 type_name_ctx: InternPool.NullTerminatedString,
398405
399 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.406 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.
...@@ -409,7 +416,7 @@ pub const Block = struct {...@@ -409,7 +416,7 @@ pub const Block = struct {
409 return block.comptime_reason != null;416 return block.comptime_reason != null;
410 }417 }
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 {
413 return block.src(.{ .node_offset_builtin_call_arg = .{420 return block.src(.{ .node_offset_builtin_call_arg = .{
414 .builtin_call_node = builtin_call_node,421 .builtin_call_node = builtin_call_node,
415 .arg_index = arg_index,422 .arg_index = arg_index,
...@@ -1082,7 +1089,7 @@ fn analyzeInlineBody(...@@ -1082,7 +1089,7 @@ fn analyzeInlineBody(
1082 // This control flow goes further up the stack.1089 // This control flow goes further up the stack.
1083 return error.ComptimeBreak;1090 return error.ComptimeBreak;
1084 }1091 }
1085 return try sema.resolveInst(break_inst.data.@"break".operand);1092 return sema.resolveInst(break_inst.data.@"break".operand);
1086}1093}
10871094
1088/// Like `analyzeInlineBody`, but if the body does not break with a value, returns1095/// Like `analyzeInlineBody`, but if the body does not break with a value, returns
...@@ -1154,7 +1161,7 @@ fn analyzeBodyInner(...@@ -1154,7 +1161,7 @@ fn analyzeBodyInner(
1154 }, inst });1161 }, inst });
1155 }1162 }
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)]) {
1158 // zig fmt: off1165 // zig fmt: off
1159 .alloc => try sema.zirAlloc(block, inst),1166 .alloc => try sema.zirAlloc(block, inst),
1160 .alloc_inferred => try sema.zirAllocInferred(block, true),1167 .alloc_inferred => try sema.zirAllocInferred(block, true),
...@@ -1382,10 +1389,10 @@ fn analyzeBodyInner(...@@ -1382,10 +1389,10 @@ fn analyzeBodyInner(
1382 const extended = datas[@intFromEnum(inst)].extended;1389 const extended = datas[@intFromEnum(inst)].extended;
1383 break :ext switch (extended.opcode) {1390 break :ext switch (extended.opcode) {
1384 // zig fmt: off1391 // zig fmt: off
1385 .struct_decl => try sema.zirStructDecl( block, extended, inst),1392 .struct_decl => try sema.zirStructDecl( block, inst),
1386 .enum_decl => try sema.zirEnumDecl( block, extended, inst),1393 .enum_decl => try sema.zirEnumDecl( block, inst),
1387 .union_decl => try sema.zirUnionDecl( block, extended, inst),1394 .union_decl => try sema.zirUnionDecl( block, inst),
1388 .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst),1395 .opaque_decl => try sema.zirOpaqueDecl( block, inst),
1389 .tuple_decl => try sema.zirTupleDecl( block, extended),1396 .tuple_decl => try sema.zirTupleDecl( block, extended),
1390 .this => try sema.zirThis( block, extended),1397 .this => try sema.zirThis( block, extended),
1391 .ret_addr => try sema.zirRetAddr( block, extended),1398 .ret_addr => try sema.zirRetAddr( block, extended),
...@@ -1869,7 +1876,7 @@ fn analyzeBodyInner(...@@ -1869,7 +1876,7 @@ fn analyzeBodyInner(
18691876
1870 const break_data = opt_break_data orelse break;1877 const break_data = opt_break_data orelse break;
1871 if (inst == break_data.block_inst) {1878 if (inst == break_data.block_inst) {
1872 break :blk try sema.resolveInst(break_data.operand);1879 break :blk sema.resolveInst(break_data.operand);
1873 } else {1880 } else {
1874 // `comptime_break_inst` preserved from `analyzeBodyInner` above.1881 // `comptime_break_inst` preserved from `analyzeBodyInner` above.
1875 return error.ComptimeBreak;1882 return error.ComptimeBreak;
...@@ -1890,7 +1897,7 @@ fn analyzeBodyInner(...@@ -1890,7 +1897,7 @@ fn analyzeBodyInner(
1890 extra.end + then_body.len,1897 extra.end + then_body.len,
1891 extra.data.else_body_len,1898 extra.data.else_body_len,
1892 );1899 );
1893 const uncasted_cond = try sema.resolveInst(extra.data.condition);1900 const uncasted_cond = sema.resolveInst(extra.data.condition);
1894 const cond = try sema.coerce(block, .bool, uncasted_cond, cond_src);1901 const cond = try sema.coerce(block, .bool, uncasted_cond, cond_src);
1895 const cond_val = try sema.resolveConstDefinedValue(1902 const cond_val = try sema.resolveConstDefinedValue(
1896 block,1903 block,
...@@ -1916,7 +1923,7 @@ fn analyzeBodyInner(...@@ -1916,7 +1923,7 @@ fn analyzeBodyInner(
1916 const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node });1923 const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node });
1917 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);1924 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
1918 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);1925 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);
1920 const err_union_ty = sema.typeOf(err_union);1927 const err_union_ty = sema.typeOf(err_union);
1921 if (err_union_ty.zigTypeTag(zcu) != .error_union) {1928 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
1922 return sema.failWithOwnedErrorMsg(block, msg: {1929 return sema.failWithOwnedErrorMsg(block, msg: {
...@@ -1942,7 +1949,7 @@ fn analyzeBodyInner(...@@ -1942,7 +1949,7 @@ fn analyzeBodyInner(
1942 const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node });1949 const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node });
1943 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);1950 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
1944 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);1951 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);
1946 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);1953 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);
1947 const is_non_err_val = (try sema.resolveIsNonErrVal(block, operand_src, err_union)).?;1954 const is_non_err_val = (try sema.resolveIsNonErrVal(block, operand_src, err_union)).?;
1948 if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, operand_src, null);1955 if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, operand_src, null);
...@@ -1971,7 +1978,7 @@ fn analyzeBodyInner(...@@ -1971,7 +1978,7 @@ fn analyzeBodyInner(
1971 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code;1978 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code;
1972 const extra = sema.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data;1979 const extra = sema.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data;
1973 const defer_body = sema.code.bodySlice(extra.index, extra.len);1980 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);
1975 try map.ensureSpaceForInstructions(sema.gpa, defer_body);1982 try map.ensureSpaceForInstructions(sema.gpa, defer_body);
1976 map.putAssumeCapacity(extra.remapped_err_code, err_code);1983 map.putAssumeCapacity(extra.remapped_err_code, err_code);
1977 if (sema.analyzeBodyInner(block, defer_body)) {1984 if (sema.analyzeBodyInner(block, defer_body)) {
...@@ -1987,18 +1994,35 @@ fn analyzeBodyInner(...@@ -1987,18 +1994,35 @@ fn analyzeBodyInner(
1987 break :blk .void_value;1994 break :blk .void_value;
1988 },1995 },
1989 };1996 };
1990 if (sema.isNoReturn(air_inst)) {1997
1991 // We're going to assume that the body itself is noreturn, so let's ensure that now1998 const is_inferred_alloc = if (air_ref.toIndex()) |air_inst| switch (sema.air_instructions.items(.tag)[@intFromEnum(air_inst)]) {
1992 assert(block.instructions.items.len > 0);1999 .inferred_alloc, .inferred_alloc_comptime => true,
1993 assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef()));2000 else => false,
1994 break;2001 } else false;
1995 }2002 // We must resolve the layout of a type before creating a value of that type. Therefore,
1996 map.putAssumeCapacity(inst, air_inst);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);
1997 i += 1;2021 i += 1;
1998 }2022 }
1999}2023}
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 {
2002 if (zir_ref == .none) {2026 if (zir_ref == .none) {
2003 return .none;2027 return .none;
2004 } else {2028 } else {
...@@ -2006,7 +2030,7 @@ pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {...@@ -2006,7 +2030,7 @@ pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
2006 }2030 }
2007}2031}
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 {
2010 assert(zir_ref != .none);2034 assert(zir_ref != .none);
2011 if (zir_ref.toIndex()) |i| {2035 if (zir_ref.toIndex()) |i| {
2012 return sema.inst_map.get(i).?;2036 return sema.inst_map.get(i).?;
...@@ -2023,7 +2047,7 @@ fn resolveConstBool(...@@ -2023,7 +2047,7 @@ fn resolveConstBool(
2023 zir_ref: Zir.Inst.Ref,2047 zir_ref: Zir.Inst.Ref,
2024 reason: ComptimeReason,2048 reason: ComptimeReason,
2025) !bool {2049) !bool {
2026 const air_inst = try sema.resolveInst(zir_ref);2050 const air_inst = sema.resolveInst(zir_ref);
2027 const wanted_type: Type = .bool;2051 const wanted_type: Type = .bool;
2028 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);2052 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
2029 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);2053 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
...@@ -2039,7 +2063,7 @@ fn resolveConstString(...@@ -2039,7 +2063,7 @@ fn resolveConstString(
2039 /// being comptime-resolved is that the block is being comptime-evaluated.2063 /// being comptime-resolved is that the block is being comptime-evaluated.
2040 reason: ?ComptimeReason,2064 reason: ?ComptimeReason,
2041) ![]u8 {2065) ![]u8 {
2042 const air_inst = try sema.resolveInst(zir_ref);2066 const air_inst = sema.resolveInst(zir_ref);
2043 return sema.toConstString(block, src, air_inst, reason);2067 return sema.toConstString(block, src, air_inst, reason);
2044}2068}
20452069
...@@ -2066,7 +2090,7 @@ pub fn resolveConstStringIntern(...@@ -2066,7 +2090,7 @@ pub fn resolveConstStringIntern(
2066 zir_ref: Zir.Inst.Ref,2090 zir_ref: Zir.Inst.Ref,
2067 reason: ComptimeReason,2091 reason: ComptimeReason,
2068) !InternPool.NullTerminatedString {2092) !InternPool.NullTerminatedString {
2069 const air_inst = try sema.resolveInst(zir_ref);2093 const air_inst = sema.resolveInst(zir_ref);
2070 const wanted_type: Type = .slice_const_u8;2094 const wanted_type: Type = .slice_const_u8;
2071 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);2095 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
2072 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);2096 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
...@@ -2074,8 +2098,8 @@ pub fn resolveConstStringIntern(...@@ -2074,8 +2098,8 @@ pub fn resolveConstStringIntern(
2074}2098}
20752099
2076fn resolveTypeOrPoison(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !?Type {2100fn resolveTypeOrPoison(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !?Type {
2077 const air_inst = try sema.resolveInst(zir_ref);2101 const air_inst = sema.resolveInst(zir_ref);
2078 const ty = try sema.analyzeAsType(block, src, air_inst);2102 const ty = try sema.analyzeAsType(block, src, .type, air_inst);
2079 if (ty.isGenericPoison()) return null;2103 if (ty.isGenericPoison()) return null;
2080 return ty;2104 return ty;
2081}2105}
...@@ -2168,7 +2192,7 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi...@@ -2168,7 +2192,7 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi
2168 // There are two cases here: the pointer type may already have been2192 // There are two cases here: the pointer type may already have been
2169 // generic poison, or it may have been an anyopaque pointer.2193 // generic poison, or it may have been an anyopaque pointer.
2170 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;2194 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);
2172 const operand_val = operand_ref.toInterned() orelse return .unknown;2196 const operand_val = operand_ref.toInterned() orelse return .unknown;
2173 if (operand_val == .generic_poison_type) {2197 if (operand_val == .generic_poison_type) {
2174 // The pointer was generic poison - keep looking.2198 // The pointer was generic poison - keep looking.
...@@ -2190,15 +2214,16 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi...@@ -2190,15 +2214,16 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi
2190 }2214 }
2191}2215}
21922216
2193fn analyzeAsType(2217pub fn analyzeAsType(
2194 sema: *Sema,2218 sema: *Sema,
2195 block: *Block,2219 block: *Block,
2196 src: LazySrcLoc,2220 src: LazySrcLoc,
2221 reason: std.zig.SimpleComptimeReason,
2197 air_inst: Air.Inst.Ref,2222 air_inst: Air.Inst.Ref,
2198) !Type {2223) !Type {
2199 const wanted_type: Type = .type;2224 const wanted_type: Type = .type;
2200 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);2225 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 });
2202 return val.toType();2227 return val.toType();
2203}2228}
22042229
...@@ -2227,7 +2252,6 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2227,7 +2252,6 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
22272252
2228 // var st: StackTrace = undefined;2253 // var st: StackTrace = undefined;
2229 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);2254 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);
2230 try stack_trace_ty.resolveFields(pt);
2231 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));2255 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));
22322256
2233 // st.instruction_addresses = &addrs;2257 // st.instruction_addresses = &addrs;
...@@ -2247,14 +2271,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2247,14 +2271,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
2247}2271}
22482272
2249/// Return the Value corresponding to a given AIR ref, or `null` if it refers to a runtime value.2273/// 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 {
2251 const zcu = sema.pt.zcu;2275 const zcu = sema.pt.zcu;
2252 assert(inst != .none);2276 assert(inst != .none);
22532277
2254 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {
2255 return opv;
2256 }
2257
2258 if (inst.toInterned()) |ip_index| {2278 if (inst.toInterned()) |ip_index| {
2259 const val: Value = .fromInterned(ip_index);2279 const val: Value = .fromInterned(ip_index);
2260 assert(val.getVariable(zcu) == null);2280 assert(val.getVariable(zcu) == null);
...@@ -2267,12 +2287,21 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {...@@ -2267,12 +2287,21 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2267 .inferred_alloc_comptime => unreachable, // assertion failure2287 .inferred_alloc_comptime => unreachable, // assertion failure
2268 else => {},2288 else => {},
2269 }2289 }
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 };
2270 return null;2299 return null;
2271 }2300 }
2272}2301}
22732302
2274/// Like `resolveValue`, but emits an error if the value is not comptime-known.2303/// Like `resolveValue`, but emits an error if the value is not comptime-known.
2275fn resolveConstValue(2304pub fn resolveConstValue(
2276 sema: *Sema,2305 sema: *Sema,
2277 block: *Block,2306 block: *Block,
2278 src: LazySrcLoc,2307 src: LazySrcLoc,
...@@ -2281,7 +2310,8 @@ fn resolveConstValue(...@@ -2281,7 +2310,8 @@ fn resolveConstValue(
2281 /// being comptime-resolved is that the block is being comptime-evaluated.2310 /// being comptime-resolved is that the block is being comptime-evaluated.
2282 reason: ?ComptimeReason,2311 reason: ?ComptimeReason,
2283) CompileError!Value {2312) CompileError!Value {
2284 return try sema.resolveValue(inst) orelse {2313 assert(reason != null or block.isComptime());
2314 return sema.resolveValue(inst) orelse {
2285 return sema.failWithNeededComptime(block, src, reason);2315 return sema.failWithNeededComptime(block, src, reason);
2286 };2316 };
2287}2317}
...@@ -2295,13 +2325,13 @@ fn resolveDefinedValue(...@@ -2295,13 +2325,13 @@ fn resolveDefinedValue(
2295) CompileError!?Value {2325) CompileError!?Value {
2296 const pt = sema.pt;2326 const pt = sema.pt;
2297 const zcu = pt.zcu;2327 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;
2299 if (val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);2329 if (val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);
2300 return val;2330 return val;
2301}2331}
23022332
2303/// Like `resolveValue`, but emits an error if the value is not comptime-known or is undefined.2333/// Like `resolveValue`, but emits an error if the value is not comptime-known or is undefined.
2304fn resolveConstDefinedValue(2334pub fn resolveConstDefinedValue(
2305 sema: *Sema,2335 sema: *Sema,
2306 block: *Block,2336 block: *Block,
2307 src: LazySrcLoc,2337 src: LazySrcLoc,
...@@ -2315,11 +2345,6 @@ fn resolveConstDefinedValue(...@@ -2315,11 +2345,6 @@ fn resolveConstDefinedValue(
2315 return val;2345 return val;
2316}2346}
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
2323/// Value Tag may be `undef` or `variable`.2348/// Value Tag may be `undef` or `variable`.
2324pub fn resolveFinalDeclValue(2349pub fn resolveFinalDeclValue(
2325 sema: *Sema,2350 sema: *Sema,
...@@ -2439,13 +2464,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non...@@ -2439,13 +2464,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non
24392464
2440fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {2465fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
2441 const pt = sema.pt;2466 const pt = sema.pt;
2467 const zcu = pt.zcu;
2442 const msg = msg: {2468 const msg = msg: {
2443 const msg = try sema.errMsg(src, "type '{f}' does not support array initialization syntax", .{2469 const msg = try sema.errMsg(src, "type '{f}' does not support array initialization syntax", .{
2444 ty.fmt(pt),2470 ty.fmt(pt),
2445 });2471 });
2446 errdefer msg.destroy(sema.gpa);2472 errdefer msg.destroy(sema.gpa);
2447 if (ty.isSlice(pt.zcu)) {2473 if (ty.isSlice(zcu)) {
2448 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{f}'", .{ty.elemType2(pt.zcu).fmt(pt)});2474 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{f}'", .{ty.childType(zcu).fmt(pt)});
2449 }2475 }
2450 break :msg msg;2476 break :msg msg;
2451 };2477 };
...@@ -2644,7 +2670,7 @@ pub fn fail(...@@ -2644,7 +2670,7 @@ pub fn fail(
2644 src: LazySrcLoc,2670 src: LazySrcLoc,
2645 comptime format: []const u8,2671 comptime format: []const u8,
2646 args: anytype,2672 args: anytype,
2647) CompileError {2673) SemaError {
2648 const err_msg = try sema.errMsg(src, format, args);2674 const err_msg = try sema.errMsg(src, format, args);
2649 inline for (args) |arg| {2675 inline for (args) |arg| {
2650 if (@TypeOf(arg) == Type.Formatter) {2676 if (@TypeOf(arg) == Type.Formatter) {
...@@ -2772,7 +2798,7 @@ fn resolveAlign(...@@ -2772,7 +2798,7 @@ fn resolveAlign(
2772 src: LazySrcLoc,2798 src: LazySrcLoc,
2773 zir_ref: Zir.Inst.Ref,2799 zir_ref: Zir.Inst.Ref,
2774) !Alignment {2800) !Alignment {
2775 const air_ref = try sema.resolveInst(zir_ref);2801 const air_ref = sema.resolveInst(zir_ref);
2776 return sema.analyzeAsAlign(block, src, air_ref);2802 return sema.analyzeAsAlign(block, src, air_ref);
2777}2803}
27782804
...@@ -2784,7 +2810,7 @@ fn resolveInt(...@@ -2784,7 +2810,7 @@ fn resolveInt(
2784 dest_ty: Type,2810 dest_ty: Type,
2785 reason: ComptimeReason,2811 reason: ComptimeReason,
2786) !u64 {2812) !u64 {
2787 const air_ref = try sema.resolveInst(zir_ref);2813 const air_ref = sema.resolveInst(zir_ref);
2788 return sema.analyzeAsInt(block, src, air_ref, dest_ty, reason);2814 return sema.analyzeAsInt(block, src, air_ref, dest_ty, reason);
2789}2815}
27902816
...@@ -2798,27 +2824,26 @@ fn analyzeAsInt(...@@ -2798,27 +2824,26 @@ fn analyzeAsInt(
2798) !u64 {2824) !u64 {
2799 const coerced = try sema.coerce(block, dest_ty, air_ref, src);2825 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
2800 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);2826 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
2801 return try val.toUnsignedIntSema(sema.pt);2827 return val.toUnsignedInt(sema.pt.zcu);
2802}2828}
28032829
2804fn analyzeValueAsCallconv(2830fn analyzeValueAsCallconv(
2805 sema: *Sema,2831 sema: *Sema,
2806 block: *Block,2832 block: *Block,
2807 src: LazySrcLoc,2833 src: LazySrcLoc,
2808 unresolved_val: Value,2834 val: Value,
2809) !std.builtin.CallingConvention {2835) !std.builtin.CallingConvention {
2810 return interpretBuiltinType(sema, block, src, unresolved_val, std.builtin.CallingConvention);2836 return interpretBuiltinType(sema, block, src, val, std.builtin.CallingConvention);
2811}2837}
28122838
2813fn interpretBuiltinType(2839fn interpretBuiltinType(
2814 sema: *Sema,2840 sema: *Sema,
2815 block: *Block,2841 block: *Block,
2816 src: LazySrcLoc,2842 src: LazySrcLoc,
2817 unresolved_val: Value,2843 val: Value,
2818 comptime T: type,2844 comptime T: type,
2819) !T {2845) !T {
2820 const resolved_val = try sema.resolveLazyValue(unresolved_val);2846 return val.interpret(T, sema.pt) catch |err| switch (err) {
2821 return resolved_val.interpret(T, sema.pt) catch |err| switch (err) {
2822 error.OutOfMemory => |e| return e,2847 error.OutOfMemory => |e| return e,
2823 error.UndefinedValue => return sema.failWithUseOfUndef(block, src, null),2848 error.UndefinedValue => return sema.failWithUseOfUndef(block, src, null),
2824 error.TypeMismatch => @panic("std.builtin is corrupt"),2849 error.TypeMismatch => @panic("std.builtin is corrupt"),
...@@ -2864,7 +2889,7 @@ fn zirTupleDecl(...@@ -2864,7 +2889,7 @@ fn zirTupleDecl(
2864 field_ty.* = field_type.toIntern();2889 field_ty.* = field_type.toIntern();
2865 field_init.* = init: {2890 field_init.* = init: {
2866 if (zir_field_init != .none) {2891 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);
2868 const coerced_field_init = try sema.coerce(block, field_type, uncoerced_field_init, init_src);2893 const coerced_field_init = try sema.coerce(block, field_type, uncoerced_field_init, init_src);
2869 const field_init_val = try sema.resolveConstDefinedValue(block, init_src, coerced_field_init, .{ .simple = .tuple_field_default_value });2894 const field_init_val = try sema.resolveConstDefinedValue(block, init_src, coerced_field_init, .{ .simple = .tuple_field_default_value });
2870 if (field_init_val.canMutateComptimeVarState(zcu)) {2895 if (field_init_val.canMutateComptimeVarState(zcu)) {
...@@ -2913,7 +2938,13 @@ fn validateTupleFieldType(...@@ -2913,7 +2938,13 @@ fn validateTupleFieldType(
29132938
2914/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,2939/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
2915/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.2940/// 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 {
2917 const pt = sema.pt;2948 const pt = sema.pt;
2918 const zcu = pt.zcu;2949 const zcu = pt.zcu;
2919 const comp = zcu.comp;2950 const comp = zcu.comp;
...@@ -2924,41 +2955,38 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2924,41 +2955,38 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2924 const parent_ty: Type = .fromInterned(zcu.namespacePtr(block.namespace).owner_type);2955 const parent_ty: Type = .fromInterned(zcu.namespacePtr(block.namespace).owner_type);
2925 const parent_captures: InternPool.CaptureValue.Slice = parent_ty.getCaptures(zcu);2956 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| {2960 for (zir_captures, zir_capture_names, captures) |zir_capture, zir_name, *capture| {
2930 const zir_capture: Zir.Inst.Capture = @bitCast(raw);
2931 const zir_name: Zir.NullTerminatedString = @enumFromInt(raw_name);
2932 const zir_name_slice = sema.code.nullTerminatedString(zir_name);2961 const zir_name_slice = sema.code.nullTerminatedString(zir_name);
2933 capture.* = switch (zir_capture.unwrap()) {2962 capture.* = switch (zir_capture.unwrap()) {
2934 .nested => |parent_idx| parent_captures.get(ip)[parent_idx],2963 .nested => |parent_idx| parent_captures.get(ip)[parent_idx],
2935 .instruction_load => |ptr_inst| InternPool.CaptureValue.wrap(capture: {2964 .instruction_load => |ptr_inst| capture: {
2936 const ptr_ref = try sema.resolveInst(ptr_inst.toRef());2965 const ptr_ref = sema.resolveInst(ptr_inst.toRef());
2937 const ptr_val = try sema.resolveValue(ptr_ref) orelse {2966 const ptr_val = sema.resolveValue(ptr_ref) orelse {
2938 break :capture .{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() };2967 break :capture .wrap(.{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() });
2939 };2968 };
2940 // TODO: better source location2969 // TODO: better source location
2941 const unresolved_loaded_val = try sema.pointerDeref(block, type_src, ptr_val, sema.typeOf(ptr_ref)) orelse {2970 const 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() };2971 break :capture .wrap(.{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() });
2943 };2972 };
2944 const loaded_val = try sema.resolveLazyValue(unresolved_loaded_val);
2945 if (loaded_val.canMutateComptimeVarState(zcu)) {2973 if (loaded_val.canMutateComptimeVarState(zcu)) {
2946 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_name_slice, .no_embedded_nulls);2974 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_name_slice, .no_embedded_nulls);
2947 return sema.failWithContainsReferenceToComptimeVar(block, type_src, field_name, "captured value", loaded_val);2975 return sema.failWithContainsReferenceToComptimeVar(block, type_src, field_name, "captured value", loaded_val);
2948 }2976 }
2949 break :capture .{ .@"comptime" = loaded_val.toIntern() };2977 break :capture .wrap(.{ .@"comptime" = loaded_val.toIntern() });
2950 }),2978 },
2951 .instruction => |inst| InternPool.CaptureValue.wrap(capture: {2979 .instruction => |inst| capture: {
2952 const air_ref = try sema.resolveInst(inst.toRef());2980 const air_ref = sema.resolveInst(inst.toRef());
2953 if (try sema.resolveValueResolveLazy(air_ref)) |val| {2981 if (sema.resolveValue(air_ref)) |val| {
2954 if (val.canMutateComptimeVarState(zcu)) {2982 if (val.canMutateComptimeVarState(zcu)) {
2955 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_name_slice, .no_embedded_nulls);2983 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_name_slice, .no_embedded_nulls);
2956 return sema.failWithContainsReferenceToComptimeVar(block, type_src, field_name, "captured value", val);2984 return sema.failWithContainsReferenceToComptimeVar(block, type_src, field_name, "captured value", val);
2957 }2985 }
2958 break :capture .{ .@"comptime" = val.toIntern() };2986 break :capture .wrap(.{ .@"comptime" = val.toIntern() });
2959 }2987 }
2960 break :capture .{ .runtime = sema.typeOf(air_ref).toIntern() };2988 break :capture .wrap(.{ .runtime = sema.typeOf(air_ref).toIntern() });
2961 }),2989 },
2962 .decl_val => |str| capture: {2990 .decl_val => |str| capture: {
2963 const decl_name = try ip.getOrPutString(2991 const decl_name = try ip.getOrPutString(
2964 gpa,2992 gpa,
...@@ -2968,7 +2996,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2968,7 +2996,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2968 .no_embedded_nulls,2996 .no_embedded_nulls,
2969 );2997 );
2970 const nav = try sema.lookupIdentifier(block, decl_name);2998 const nav = try sema.lookupIdentifier(block, decl_name);
2971 break :capture InternPool.CaptureValue.wrap(.{ .nav_val = nav });2999 break :capture .wrap(.{ .nav_val = nav });
2972 },3000 },
2973 .decl_ref => |str| capture: {3001 .decl_ref => |str| capture: {
2974 const decl_name = try ip.getOrPutString(3002 const decl_name = try ip.getOrPutString(
...@@ -2987,952 +3015,335 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2987,952 +3015,335 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2987 return captures;3015 return captures;
2988}3016}
29893017
2990fn zirStructDecl(3018fn zirErrorSetDecl(
2991 sema: *Sema,3019 sema: *Sema,
2992 block: *Block,
2993 extended: Zir.Inst.Extended.InstData,
2994 inst: Zir.Inst.Index,3020 inst: Zir.Inst.Index,
2995) CompileError!Air.Inst.Ref {3021) CompileError!Air.Inst.Ref {
3022 const tracy = trace(@src());
3023 defer tracy.end();
3024
2996 const pt = sema.pt;3025 const pt = sema.pt;
2997 const zcu = pt.zcu;3026 const zcu = pt.zcu;
2998 const comp = zcu.comp;3027 const comp = zcu.comp;
2999 const gpa = comp.gpa;3028 const gpa = comp.gpa;
3000 const io = comp.io;3029 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);3031 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
3007 const src: LazySrcLoc = .{3032 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
3008 .base_node_inst = tracked_inst,
3009 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
3010 };
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: {3037 var extra_index: u32 = @intCast(extra.end);
3015 const captures_len = sema.code.extra[extra_index];3038 const extra_index_end = extra_index + extra.data.fields_len;
3016 extra_index += 1;3039 while (extra_index < extra_index_end) : (extra_index += 1) {
3017 break :blk captures_len;3040 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3018 } else 0;3041 const name = sema.code.nullTerminatedString(name_index);
3019 const fields_len = if (small.has_fields_len) blk: {3042 const name_ip = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
3020 const fields_len = sema.code.extra[extra_index];3043 _ = try pt.getErrorValue(name_ip);
3021 extra_index += 1;3044 const result = names.getOrPutAssumeCapacity(name_ip);
3022 break :blk fields_len;3045 assert(!result.found_existing); // verified in AstGen
3023 } else 0;3046 }
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;
30293047
3030 const captures = try sema.getCaptures(block, src, extra_index, captures_len);3048 return Air.internedToRef((try pt.errorSetFromUnsortedNames(names.keys())).toIntern());
3031 extra_index += captures_len * 2;3049}
30323050
3033 if (small.has_backing_int) {3051fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3034 const backing_int_body_len = sema.code.extra[extra_index];3052 const tracy = trace(@src());
3035 extra_index += 1; // backing_int_body_len3053 defer tracy.end();
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);
30603054
3061 // Make sure we update the namespace if the declaration is re-analyzed, to pick3055 const pt = sema.pt;
3062 // up on e.g. changed comptime decls.3056 const zcu = pt.zcu;
3063 try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu));
30643057
3065 try sema.declareDependency(.{ .interned = new_ty });3058 const src = block.nodeOffset(sema.code.instructions.items(.data)[@intFromEnum(inst)].node);
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);
30723059
3073 const type_name = try sema.createTypeName(3060 if (block.isComptime() or sema.fn_ret_ty.comptimeOnly(zcu)) {
3074 block,3061 return sema.analyzeComptimeAlloc(block, src, sema.fn_ret_ty, .none);
3075 small.name_strategy,3062 }
3076 "struct",
3077 inst,
3078 wip_ty.index,
3079 );
3080 wip_ty.setName(ip, type_name.name, type_name.nav);
30813063
3082 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{3064 const target = zcu.getTarget();
3083 .parent = block.namespace.toOptional(),3065 const ptr_type = try pt.ptrType(.{
3084 .owner_type = wip_ty.index,3066 .child = sema.fn_ret_ty.toIntern(),
3085 .file_scope = block.getFileScopeIndex(zcu),3067 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3086 .generation = zcu.generation,
3087 });3068 });
3088 errdefer pt.destroyNamespace(new_namespace_index);
30893069
3090 if (pt.zcu.comp.config.incremental) {3070 if (block.inlining != null) {
3091 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });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);
3092 }3075 }
30933076
3094 const decls = sema.code.bodySlice(extra_index, decls_len);3077 return block.addTy(.ret_ptr, ptr_type);
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));
3109}3078}
31103079
3111pub fn createTypeName(3080fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3112 sema: *Sema,3081 const tracy = trace(@src());
3113 block: *Block,3082 defer tracy.end();
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);
31393083
3140 var aw: std.Io.Writer.Allocating = .init(gpa);3084 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
3141 defer aw.deinit();3085 const operand = sema.resolveInst(inst_data.operand);
3142 const w = &aw.writer;3086 return sema.analyzeRef(block, block.tokenOffset(inst_data.src_tok), operand, .none);
3143 w.print("{f}(", .{block.type_name_ctx.fmt(ip)}) catch return error.OutOfMemory;3087}
31443088
3145 var arg_i: usize = 0;3089fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3146 for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {3090 const tracy = trace(@src());
3147 .param, .param_comptime, .param_anytype, .param_anytype_comptime => {3091 defer tracy.end();
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
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, which3097 return sema.ensureResultUsed(block, sema.typeOf(operand), src);
3159 // in turn helps to avoid unreasonably long symbol names for namespaced3098}
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;
31683099
3169 arg_i += 1;3100fn ensureResultUsed(
3170 continue;3101 sema: *Sema,
3171 },3102 block: *Block,
3172 else => continue,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;
3173 };3117 };
31743118 return sema.failWithOwnedErrorMsg(block, msg);
3175 w.writeByte(')') catch return error.OutOfMemory;3119 },
3176 return .{3120 else => {
3177 .name = try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls),3121 const msg = msg: {
3178 .nav = .none,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;
3179 };3127 };
3128 return sema.failWithOwnedErrorMsg(block, msg);
3180 },3129 },
3181 .dbg_var => {3130 }
3182 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.3131}
3183 const ref = inst.?.toRef();3132
3184 const zir_tags = sema.code.instructions.items(.tag);3133fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3185 const zir_data = sema.code.instructions.items(.data);3134 const tracy = trace(@src());
3186 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {3135 defer tracy.end();
3187 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {3136
3188 return .{3137 const pt = sema.pt;
3189 .name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{3138 const zcu = pt.zcu;
3190 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),3139 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3191 }, .no_embedded_nulls),3140 const operand = sema.resolveInst(inst_data.operand);
3192 .nav = .none,3141 const src = block.nodeOffset(inst_data.src_node);
3193 };3142 const operand_ty = sema.typeOf(operand);
3194 },3143 switch (operand_ty.zigTypeTag(zcu)) {
3195 else => {},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;
3196 };3151 };
3197 // fall through to anon strat3152 return sema.failWithOwnedErrorMsg(block, msg);
3198 },3153 },
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);
3199 }3182 }
3183}
32003184
3201 // anon strat handling3185fn 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 has3189 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3204 // to survive incremental updates, where it may have been shifted down3190 const src = block.nodeOffset(inst_data.src_node);
3205 // or up to a different line, but unchanged, and thus not unnecessarily3191 const object = sema.resolveInst(inst_data.operand);
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.
32103192
3211 return .{3193 return indexablePtrLen(sema, block, src, object);
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 };
3217}3194}
32183195
3219fn zirEnumDecl(3196fn indexablePtrLen(
3220 sema: *Sema,3197 sema: *Sema,
3221 block: *Block,3198 block: *Block,
3222 extended: Zir.Inst.Extended.InstData,3199 src: LazySrcLoc,
3223 inst: Zir.Inst.Index,3200 object: Air.Inst.Ref,
3224) CompileError!Air.Inst.Ref {3201) CompileError!Air.Inst.Ref {
3225 const tracy = trace(@src());
3226 defer tracy.end();
3227
3228 const pt = sema.pt;3202 const pt = sema.pt;
3229 const zcu = pt.zcu;3203 const zcu = pt.zcu;
3230 const comp = zcu.comp;3204 const comp = zcu.comp;
3231 const gpa = comp.gpa;3205 const gpa = comp.gpa;
3232 const io = comp.io;3206 const io = comp.io;
3233 const ip = &zcu.intern_pool;3207 const object_ty = sema.typeOf(object);
32343208 const is_pointer_to = object_ty.isSinglePointer(zcu);
3235 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);3209 const indexable_ty = if (is_pointer_to) object_ty.childType(zcu) else object_ty;
3236 const extra = sema.code.extraData(Zir.Inst.EnumDecl, extended.operand);3210 try sema.checkIndexable(block, src, indexable_ty);
3237 var extra_index: usize = extra.end;3211 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls);
32383212 return sema.fieldVal(block, src, object, field_name, src);
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);
3389}3213}
33903214
3391fn zirUnionDecl(3215fn indexablePtrLenOrNone(
3392 sema: *Sema,3216 sema: *Sema,
3393 block: *Block,3217 block: *Block,
3394 extended: Zir.Inst.Extended.InstData,3218 src: LazySrcLoc,
3395 inst: Zir.Inst.Index,3219 operand: Air.Inst.Ref,
3396) CompileError!Air.Inst.Ref {3220) CompileError!Air.Inst.Ref {
3397 const tracy = trace(@src());
3398 defer tracy.end();
3399
3400 const pt = sema.pt;3221 const pt = sema.pt;
3401 const zcu = pt.zcu;3222 const zcu = pt.zcu;
3402 const comp = zcu.comp;3223 const comp = zcu.comp;
3403 const gpa = comp.gpa;3224 const gpa = comp.gpa;
3404 const io = comp.io;3225 const io = comp.io;
3405 const ip = &zcu.intern_pool;3226 const operand_ty = sema.typeOf(operand);
34063227 try checkMemOperand(sema, block, src, operand_ty);
3407 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);3228 switch (operand_ty.ptrSize(zcu)) {
3408 const extra = sema.code.extraData(Zir.Inst.UnionDecl, extended.operand);3229 .many, .c => return .none,
3409 var extra_index: usize = extra.end;3230 .one, .slice => {},
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 });
3510 }3231 }
3511 try sema.declareDependency(.{ .interned = wip_ty.index });3232 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls);
3512 try sema.addTypeReferenceEntry(src, wip_ty.index);3233 return sema.fieldVal(block, src, operand, field_name, src);
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));
3515}3234}
35163235
3517fn zirOpaqueDecl(3236fn zirAllocExtended(
3518 sema: *Sema,3237 sema: *Sema,
3519 block: *Block,3238 block: *Block,
3520 extended: Zir.Inst.Extended.InstData,3239 extended: Zir.Inst.Extended.InstData,
3521 inst: Zir.Inst.Index,
3522) CompileError!Air.Inst.Ref {3240) CompileError!Air.Inst.Ref {
3523 const tracy = trace(@src());
3524 defer tracy.end();
3525
3526 const pt = sema.pt;3241 const pt = sema.pt;
3527 const zcu = pt.zcu;3242 const zcu = pt.zcu;
3528 const comp = zcu.comp;3243 const gpa = sema.gpa;
3529 const gpa = comp.gpa;3244 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
3530 const io = comp.io;3245 const var_src = block.nodeOffset(extra.data.src_node);
3531 const ip = &zcu.intern_pool;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);
3535 var extra_index: usize = extra.end;3250 var extra_index: usize = extra.end;
35363251
3537 const tracked_inst = try block.trackZir(inst);3252 const var_ty: Type = if (small.has_type) blk: {
3538 const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) };3253 const type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
3539
3540 const captures_len = if (small.has_captures_len) blk: {
3541 const captures_len = sema.code.extra[extra_index];
3542 extra_index += 1;3254 extra_index += 1;
3543 break :blk captures_len;3255 break :blk try sema.resolveType(block, ty_src, type_ref);
3544 } else 0;3256 } else undefined;
35453257
3546 const decls_len = if (small.has_decls_len) blk: {3258 const alignment = if (small.has_align) blk: {
3547 const decls_len = sema.code.extra[extra_index];3259 const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
3548 extra_index += 1;3260 extra_index += 1;
3549 break :blk decls_len;3261 break :blk try sema.resolveAlign(block, align_src, align_ref);
3550 } else 0;3262 } else .none;
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));
35643263
3565 try sema.declareDependency(.{ .interned = ty });3264 if (small.has_type) {
3566 try sema.addTypeReferenceEntry(src, ty);3265 try sema.ensureLayoutResolved(var_ty, var_src, if (small.is_const) .constant else .variable);
3567 return Air.internedToRef(ty);3266 if (block.isComptime() or small.is_comptime or var_ty.comptimeOnly(zcu)) {
3568 },3267 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);
3569 .wip => |wip| wip,3268 }
3570 };3269 if (!small.is_const) {
3571 errdefer wip_ty.cancel(ip, pt.tid);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(3293 if (block.isComptime() or small.is_comptime) {
3574 block,3294 const iac_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
3575 small.name_strategy,3295 try sema.air_instructions.append(gpa, .{
3576 "opaque",3296 .tag = .inferred_alloc_comptime,
3577 inst,3297 .data = .{ .inferred_alloc_comptime = .{
3578 wip_ty.index,3298 .alignment = alignment,
3579 );3299 .is_const = small.is_const,
3580 wip_ty.setName(ip, type_name.name, type_name.nav);3300 .ptr = undefined,
3301 } },
3302 });
3303 return iac_index.toRef();
3304 }
35813305
3582 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{3306 const result_index = try block.addInstAsIndex(.{
3583 .parent = block.namespace.toOptional(),3307 .tag = .inferred_alloc,
3584 .owner_type = wip_ty.index,3308 .data = .{ .inferred_alloc = .{
3585 .file_scope = block.getFileScopeIndex(zcu),3309 .alignment = alignment,
3586 .generation = zcu.generation,3310 .is_const = small.is_const,
3311 } },
3587 });3312 });
3588 errdefer pt.destroyNamespace(new_namespace_index);3313 try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, .{});
35893314 if (small.is_const) {
3590 const decls = sema.code.bodySlice(extra_index, decls_len);3315 try sema.maybe_comptime_allocs.put(gpa, result_index, .{ .runtime_index = block.runtime_index });
3591 try pt.scanNamespace(new_namespace_index, decls);3316 try sema.base_allocs.put(gpa, result_index, result_index);
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 });
3599 }3317 }
3600 try sema.addTypeReferenceEntry(src, wip_ty.index);3318 return result_index.toRef();
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));
3603}3319}
36043320
3605fn zirErrorSetDecl(3321fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3606 sema: *Sema,
3607 inst: Zir.Inst.Index,
3608) CompileError!Air.Inst.Ref {
3609 const tracy = trace(@src());3322 const tracy = trace(@src());
3610 defer tracy.end();3323 defer tracy.end();
36113324
3612 const pt = sema.pt;3325 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3613 const zcu = pt.zcu;3326 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
3614 const comp = zcu.comp;3327 const var_src = block.nodeOffset(inst_data.src_node);
3615 const gpa = comp.gpa;3328 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3616 const io = comp.io;3329 try sema.ensureLayoutResolved(var_ty, var_src, .variable);
36173330 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
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());
3636}3331}
36373332
3638fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3333fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3639 const tracy = trace(@src());
3640 defer tracy.end();
3641
3642 const pt = sema.pt;3334 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);3342 // If the alloc was created in a comptime scope, we already created a comptime alloc for it.
36453343 // However, if the final constructed value does not reference comptime-mutable memory, we wish
3646 if (block.isComptime() or try sema.fn_ret_ty.comptimeOnlySema(pt)) {3344 // to promote it to an anon decl.
3647 try sema.fn_ret_ty.resolveFields(pt);3345 already_ct: {
3648 return sema.analyzeComptimeAlloc(block, src, sema.fn_ret_ty, .none);3346 const ptr_val = sema.resolveValue(alloc) orelse break :already_ct;
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;
39363347
3937 // If this was a comptime inferred alloc, then `storeToInferredAllocComptime`3348 // If this was a comptime inferred alloc, then `storeToInferredAllocComptime`
3938 // might have already done our job and created an anon decl ref.3349 // 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...@@ -3978,7 +3389,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3978 return sema.makePtrConst(block, Air.internedToRef(ptr_val));3389 return sema.makePtrConst(block, Air.internedToRef(ptr_val));
3979 }3390 }
39803391
3981 if (try elem_ty.comptimeOnlySema(pt)) {3392 if (elem_ty.comptimeOnly(zcu)) {
3982 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.3393 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.
3983 // TODO: source location of runtime control flow3394 // TODO: source location of runtime control flow
3984 const init_src = block.src(.{ .node_offset_var_decl_init = inst_data.src_node });3395 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,...@@ -4001,20 +3412,23 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4001 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);3412 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);
4002 const ptr_info = alloc_ty.ptrInfo(zcu);3413 const ptr_info = alloc_ty.ptrInfo(zcu);
4003 const elem_ty: Type = .fromInterned(ptr_info.child);3414 const elem_ty: Type = .fromInterned(ptr_info.child);
3415 elem_ty.assertHasLayout(zcu);
40043416
4005 const alloc_inst = alloc.toIndex() orelse return null;3417 const alloc_inst = alloc.toIndex() orelse return null;
4006 const comptime_info = sema.maybe_comptime_allocs.fetchRemove(alloc_inst) orelse return null;3418 const comptime_info = sema.maybe_comptime_allocs.fetchRemove(alloc_inst) orelse return null;
4007 const stores = comptime_info.value.stores.items(.inst);3419 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
4009 // Since the entry existed in `maybe_comptime_allocs`, the allocation is comptime-known.3429 // Since the entry existed in `maybe_comptime_allocs`, the allocation is comptime-known.
4010 // We will resolve and return its value.3430 // 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
4018 // In general, we want to create a comptime alloc of the correct type and3432 // In general, we want to create a comptime alloc of the correct type and
4019 // apply the stores to that alloc in order. However, before going to all3433 // apply the stores to that alloc in order. However, before going to all
4020 // that effort, let's optimize for the common case of a single store.3434 // 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,...@@ -4115,10 +3529,10 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4115 Air.Bin,3529 Air.Bin,
4116 tmp_air.instructions.items(.data)[@intFromEnum(air_ptr)].ty_pl.payload,3530 tmp_air.instructions.items(.data)[@intFromEnum(air_ptr)].ty_pl.payload,
4117 ).data;3531 ).data;
4118 const idx_val = (try sema.resolveValue(data.rhs)).?;3532 const idx_val = sema.resolveValue(data.rhs).?;
4119 break :blk .{3533 break :blk .{
4120 data.lhs,3534 data.lhs,
4121 .{ .elem = try idx_val.toUnsignedIntSema(pt) },3535 .{ .elem = idx_val.toUnsignedInt(zcu) },
4122 };3536 };
4123 },3537 },
4124 .bitcast => .{3538 .bitcast => .{
...@@ -4150,7 +3564,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -4150,7 +3564,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4150 // If the payload is OPV, we must use that value instead of undef.3564 // If the payload is OPV, we must use that value instead of undef.
4151 const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3565 const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
4152 const payload_ty = opt_ty.optionalChild(zcu);3566 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);
4154 const opt_val = try pt.intern(.{ .opt = .{3568 const opt_val = try pt.intern(.{ .opt = .{
4155 .ty = opt_ty.toIntern(),3569 .ty = opt_ty.toIntern(),
4156 .val = payload_val.toIntern(),3570 .val = payload_val.toIntern(),
...@@ -4163,7 +3577,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -4163,7 +3577,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4163 // If the payload is OPV, we must use that value instead of undef.3577 // If the payload is OPV, we must use that value instead of undef.
4164 const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3578 const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
4165 const payload_ty = eu_ty.errorUnionPayload(zcu);3579 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);
4167 const eu_val = try pt.intern(.{ .error_union = .{3581 const eu_val = try pt.intern(.{ .error_union = .{
4168 .ty = eu_ty.toIntern(),3582 .ty = eu_ty.toIntern(),
4169 .val = .{ .payload = payload_val.toIntern() },3583 .val = .{ .payload = payload_val.toIntern() },
...@@ -4173,18 +3587,31 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -4173,18 +3587,31 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4173 },3587 },
4174 .field => |idx| ptr: {3588 .field => |idx| ptr: {
4175 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3589 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) {
4177 // As this is a union field, we must store to the pointer now to set the tag.3591 // As this is a union field, we must store to the pointer now to set the tag.
4178 // The payload value will be stored later, so undef is a sufficent payload for now.3592 // The payload value will be stored later, so undef is a sufficent payload for now.
4179 const payload_ty: Type = .fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]);3593 const payload_ty: Type = .fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]);
4180 const payload_val = try pt.undefValue(payload_ty);3594 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);
4182 const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val);3596 const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val);
4183 try sema.storePtrVal(block, .unneeded, .fromInterned(decl_parent_ptr), store_val, maybe_union_ty);3597 try sema.storePtrVal(block, .unneeded, .fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
4184 }3598 };
4185 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, pt)).toIntern();3599 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, pt)).toIntern();
4186 },3600 },
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 },
4188 };3615 };
4189 try ptr_mapping.put(air_ptr, new_ptr);3616 try ptr_mapping.put(air_ptr, new_ptr);
4190 }3617 }
...@@ -4207,14 +3634,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -4207,14 +3634,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4207 const tag_val: Value = .fromInterned(store_inst.data.bin_op.rhs.toInterned().?);3634 const tag_val: Value = .fromInterned(store_inst.data.bin_op.rhs.toInterned().?);
4208 const union_ty = union_ptr_val.typeOf(zcu).childType(zcu);3635 const union_ty = union_ptr_val.typeOf(zcu).childType(zcu);
4209 const field_ty = union_ty.unionFieldType(tag_val, zcu).?;3636 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| {
4211 const new_union_val = try pt.unionValue(union_ty, tag_val, payload_val);3638 const new_union_val = try pt.unionValue(union_ty, tag_val, payload_val);
4212 try sema.storePtrVal(block, .unneeded, union_ptr_val, new_union_val, union_ty);3639 try sema.storePtrVal(block, .unneeded, union_ptr_val, new_union_val, union_ty);
4213 }3640 }
4214 },3641 },
4215 .store, .store_safe => {3642 .store, .store_safe => {
4216 const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?;3643 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).?;
4218 const new_ptr = ptr_mapping.get(air_ptr_inst).?;3645 const new_ptr = ptr_mapping.get(air_ptr_inst).?;
4219 try sema.storePtrVal(block, .unneeded, .fromInterned(new_ptr), store_val, store_val.typeOf(zcu));3646 try sema.storePtrVal(block, .unneeded, .fromInterned(new_ptr), store_val, store_val.typeOf(zcu));
4220 },3647 },
...@@ -4289,7 +3716,7 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4289,7 +3716,7 @@ fn finishResolveComptimeKnownAllocPtr(
4289fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {3716fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
4290 var ptr_info = ptr_ty.ptrInfo(sema.pt.zcu);3717 var ptr_info = ptr_ty.ptrInfo(sema.pt.zcu);
4291 ptr_info.flags.is_const = true;3718 ptr_info.flags.is_const = true;
4292 return sema.pt.ptrTypeSema(ptr_info);3719 return sema.pt.ptrType(ptr_info);
4293}3720}
42943721
4295fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {3722fn 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...@@ -4297,7 +3724,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
4297 const const_ptr_ty = try sema.makePtrTyConst(alloc_ty);3724 const const_ptr_ty = try sema.makePtrTyConst(alloc_ty);
42983725
4299 // Detect if a comptime value simply needs to have its type changed.3726 // 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| {
4301 return Air.internedToRef((try sema.pt.getCoerced(val, const_ptr_ty)).toIntern());3728 return Air.internedToRef((try sema.pt.getCoerced(val, const_ptr_ty)).toIntern());
4302 }3729 }
43033730
...@@ -4326,21 +3753,23 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -4326,21 +3753,23 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
4326 defer tracy.end();3753 defer tracy.end();
43273754
4328 const pt = sema.pt;3755 const pt = sema.pt;
3756 const zcu = pt.zcu;
43293757
4330 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3758 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4331 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });3759 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
4332 const var_src = block.nodeOffset(inst_data.src_node);3760 const var_src = block.nodeOffset(inst_data.src_node);
43333761
4334 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3762 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)) {
4336 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);3765 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
4337 }3766 }
4338 if (sema.func_is_naked and try var_ty.hasRuntimeBitsSema(pt)) {3767 if (sema.func_is_naked and var_ty.hasRuntimeBits(zcu)) {
4339 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });3768 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
4340 return sema.fail(block, mut_src, "local variable in naked function", .{});3769 return sema.fail(block, mut_src, "local variable in naked function", .{});
4341 }3770 }
4342 const target = pt.zcu.getTarget();3771 const target = zcu.getTarget();
4343 const ptr_type = try pt.ptrTypeSema(.{3772 const ptr_type = try pt.ptrType(.{
4344 .child = var_ty.toIntern(),3773 .child = var_ty.toIntern(),
4345 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },3774 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4346 });3775 });
...@@ -4356,21 +3785,24 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -4356,21 +3785,24 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
4356 defer tracy.end();3785 defer tracy.end();
43573786
4358 const pt = sema.pt;3787 const pt = sema.pt;
3788 const zcu = pt.zcu;
43593789
4360 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3790 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4361 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });3791 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
4362 const var_src = block.nodeOffset(inst_data.src_node);3792 const var_src = block.nodeOffset(inst_data.src_node);
3793
4363 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3794 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3795 try sema.ensureLayoutResolved(var_ty, var_src, .variable);
4364 if (block.isComptime()) {3796 if (block.isComptime()) {
4365 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);3797 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
4366 }3798 }
4367 if (sema.func_is_naked and try var_ty.hasRuntimeBitsSema(pt)) {3799 if (sema.func_is_naked and var_ty.hasRuntimeBits(zcu)) {
4368 const store_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });3800 const store_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
4369 return sema.fail(block, store_src, "local variable in naked function", .{});3801 return sema.fail(block, store_src, "local variable in naked function", .{});
4370 }3802 }
4371 try sema.validateVarType(block, ty_src, var_ty, false);3803 try sema.validateVarType(block, ty_src, var_ty, false);
4372 const target = pt.zcu.getTarget();3804 const target = zcu.getTarget();
4373 const ptr_type = try pt.ptrTypeSema(.{3805 const ptr_type = try pt.ptrType(.{
4374 .child = var_ty.toIntern(),3806 .child = var_ty.toIntern(),
4375 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },3807 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4376 });3808 });
...@@ -4424,14 +3856,15 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4424,14 +3856,15 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4424 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3856 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4425 const src = block.nodeOffset(inst_data.src_node);3857 const src = block.nodeOffset(inst_data.src_node);
4426 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });3858 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);
4428 const ptr_inst = ptr.toIndex().?;3860 const ptr_inst = ptr.toIndex().?;
4429 const target = zcu.getTarget();3861 const target = zcu.getTarget();
44303862
4431 switch (sema.air_instructions.items(.tag)[@intFromEnum(ptr_inst)]) {3863 switch (sema.air_instructions.items(.tag)[@intFromEnum(ptr_inst)]) {
4432 .inferred_alloc_comptime => {3864 .inferred_alloc_comptime => {
4433 // The work was already done for us by `Sema.storeToInferredAllocComptime`.3865 // The work was already done for us by `Sema.storeToInferredAllocComptime`. Also, since
4434 // All we need to do is return the pointer.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.
4435 const iac = sema.air_instructions.items(.data)[@intFromEnum(ptr_inst)].inferred_alloc_comptime;3868 const iac = sema.air_instructions.items(.data)[@intFromEnum(ptr_inst)].inferred_alloc_comptime;
4436 const resolved_ptr = iac.ptr;3869 const resolved_ptr = iac.ptr;
44373870
...@@ -4450,7 +3883,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4450,7 +3883,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4450 };3883 };
4451 if (zcu.intern_pool.isFuncBody(val)) {3884 if (zcu.intern_pool.isFuncBody(val)) {
4452 const ty: Type = .fromInterned(zcu.intern_pool.typeOf(val));3885 const ty: Type = .fromInterned(zcu.intern_pool.typeOf(val));
4453 if (try ty.fnHasRuntimeBitsSema(pt)) {3886 if (ty.fnHasRuntimeBits(zcu)) {
4454 const orig_fn_index = zcu.intern_pool.unwrapCoercedFunc(val);3887 const orig_fn_index = zcu.intern_pool.unwrapCoercedFunc(val);
4455 try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_fn_index }));3888 try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_fn_index }));
4456 try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index);3889 try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index);
...@@ -4469,8 +3902,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4469,8 +3902,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4469 peer_val.* = bin_op.rhs;3902 peer_val.* = bin_op.rhs;
4470 }3903 }
4471 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);3904 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(.{
4474 .child = final_elem_ty.toIntern(),3909 .child = final_elem_ty.toIntern(),
4475 .flags = .{3910 .flags = .{
4476 .alignment = ia1.alignment,3911 .alignment = ia1.alignment,
...@@ -4484,21 +3919,16 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4484,21 +3919,16 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4484 const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty);3919 const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty);
4485 const new_const_ptr = try pt.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty);3920 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
4492 return Air.internedToRef(new_const_ptr.toIntern());3922 return Air.internedToRef(new_const_ptr.toIntern());
4493 }3923 }
44943924
4495 if (try final_elem_ty.comptimeOnlySema(pt)) {3925 if (final_elem_ty.comptimeOnly(zcu)) {
4496 // The alloc wasn't comptime-known per the above logic, so the3926 // The alloc wasn't comptime-known per the above logic, so the
4497 // type cannot be comptime-only.3927 // type cannot be comptime-only.
4498 // TODO: source location of runtime control flow3928 // TODO: source location of runtime control flow
4499 return sema.fail(block, src, "value with comptime-only type '{f}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});3929 return sema.fail(block, src, "value with comptime-only type '{f}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});
4500 }3930 }
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)) {
4502 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });3932 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
4503 return sema.fail(block, mut_src, "local variable in naked function", .{});3933 return sema.fail(block, mut_src, "local variable in naked function", .{});
4504 }3934 }
...@@ -4591,7 +4021,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4591,7 +4021,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
45914021
4592 const arg_len_uncoerced = if (zir_arg_pair[1] == .none) l: {4022 const arg_len_uncoerced = if (zir_arg_pair[1] == .none) l: {
4593 // This argument is an indexable.4023 // This argument is an indexable.
4594 const object = try sema.resolveInst(zir_arg_pair[0]);4024 const object = sema.resolveInst(zir_arg_pair[0]);
4595 const object_ty = sema.typeOf(object);4025 const object_ty = sema.typeOf(object);
4596 if (!object_ty.isIndexable(zcu)) {4026 if (!object_ty.isIndexable(zcu)) {
4597 // Instead of using checkIndexable we customize this error.4027 // Instead of using checkIndexable we customize this error.
...@@ -4612,8 +4042,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4612,8 +4042,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4612 break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls), arg_src);4042 break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls), arg_src);
4613 } else l: {4043 } else l: {
4614 // This argument is a range.4044 // This argument is a range.
4615 const range_start = try sema.resolveInst(zir_arg_pair[0]);4045 const range_start = sema.resolveInst(zir_arg_pair[0]);
4616 const range_end = try sema.resolveInst(zir_arg_pair[1]);4046 const range_end = sema.resolveInst(zir_arg_pair[1]);
4617 if (try sema.resolveDefinedValue(block, arg_src, range_start)) |start| {4047 if (try sema.resolveDefinedValue(block, arg_src, range_start)) |start| {
4618 if (try sema.valuesEqual(start, .zero_usize, .usize)) break :l range_end;4048 if (try sema.valuesEqual(start, .zero_usize, .usize)) break :l range_end;
4619 }4049 }
...@@ -4663,7 +4093,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4663,7 +4093,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4663 const i: u32 = @intCast(i_usize);4093 const i: u32 = @intCast(i_usize);
4664 if (zir_arg_pair[0] == .none) continue;4094 if (zir_arg_pair[0] == .none) continue;
4665 if (zir_arg_pair[1] != .none) continue;4095 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]);
4667 const object_ty = sema.typeOf(object);4097 const object_ty = sema.typeOf(object);
4668 const arg_src = block.src(.{ .for_input = .{4098 const arg_src = block.src(.{ .for_input = .{
4669 .for_node_offset = inst_data.src_node,4099 .for_node_offset = inst_data.src_node,
...@@ -4701,9 +4131,11 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4701,9 +4131,11 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4701/// or error union pointed to, initializing these pointers along the way.4131/// or error union pointed to, initializing these pointers along the way.
4702/// Given a `*E!?T`, returns a (valid) `*T`.4132/// Given a `*E!?T`, returns a (valid) `*T`.
4703/// May invalidate already-stored payload data.4133/// May invalidate already-stored payload data.
4134/// Asserts that the layout of the pointer child type is already resolved.
4704fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {4135fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {
4705 const pt = sema.pt;4136 const pt = sema.pt;
4706 const zcu = pt.zcu;4137 const zcu = pt.zcu;
4138 sema.typeOf(ptr).childType(zcu).assertHasLayout(zcu);
4707 var base_ptr = ptr;4139 var base_ptr = ptr;
4708 while (true) switch (sema.typeOf(base_ptr).childType(zcu).zigTypeTag(zcu)) {4140 while (true) switch (sema.typeOf(base_ptr).childType(zcu).zigTypeTag(zcu)) {
4709 .error_union => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),4141 .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...@@ -4716,8 +4148,10 @@ fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcL
47164148
4717fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4149fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4718 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4150 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4719 const ptr = try sema.resolveInst(un_node.operand);4151 const ptr = sema.resolveInst(un_node.operand);
4720 return sema.optEuBasePtrInit(block, ptr, block.nodeOffset(un_node.src_node));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);
4721}4155}
47224156
4723fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4157fn 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...@@ -4726,7 +4160,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
4726 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4160 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4727 const src = block.nodeOffset(pl_node.src_node);4161 const src = block.nodeOffset(pl_node.src_node);
4728 const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;4162 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);
4730 const maybe_wrapped_ptr_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, extra.lhs) orelse return uncoerced_val;4164 const maybe_wrapped_ptr_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, extra.lhs) orelse return uncoerced_val;
4731 const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(zcu);4165 const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(zcu);
4732 assert(ptr_ty.zigTypeTag(zcu) == .pointer); // validated by a previous instruction4166 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...@@ -4812,7 +4246,7 @@ fn zirTryOperandTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: boo
4812 if (is_ref) {4246 if (is_ref) {
4813 var ptr_info = operand_ty.ptrInfo(zcu);4247 var ptr_info = operand_ty.ptrInfo(zcu);
4814 ptr_info.child = eu_ty.toIntern();4248 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);
4816 return Air.internedToRef(eu_ptr_ty.toIntern());4250 return Air.internedToRef(eu_ptr_ty.toIntern());
4817 } else {4251 } else {
4818 return Air.internedToRef(eu_ty.toIntern());4252 return Air.internedToRef(eu_ty.toIntern());
...@@ -4842,7 +4276,7 @@ fn zirValidateConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4842,7 +4276,7 @@ fn zirValidateConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
48424276
4843 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4277 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4844 const src = block.nodeOffset(un_node.src_node);4278 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);
4846 if (!try sema.isComptimeKnown(init_ref)) {4280 if (!try sema.isComptimeKnown(init_ref)) {
4847 return sema.failWithNeededComptime(block, src, null);4281 return sema.failWithNeededComptime(block, src, null);
4848 }4282 }
...@@ -4935,7 +4369,6 @@ fn validateArrayInitTy(...@@ -4935,7 +4369,6 @@ fn validateArrayInitTy(
4935 return;4369 return;
4936 },4370 },
4937 .@"struct" => if (ty.isTuple(zcu)) {4371 .@"struct" => if (ty.isTuple(zcu)) {
4938 try ty.resolveFields(pt);
4939 const array_len = ty.arrayLen(zcu);4372 const array_len = ty.arrayLen(zcu);
4940 if (init_count > array_len) {4373 if (init_count > array_len) {
4941 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{4374 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
...@@ -4986,7 +4419,7 @@ fn zirValidatePtrStructInit(...@@ -4986,7 +4419,7 @@ fn zirValidatePtrStructInit(
4986 const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len);4419 const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len);
4987 const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node;4420 const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node;
4988 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;4421 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);
4990 const agg_ty = sema.typeOf(object_ptr).childType(zcu).optEuBaseType(zcu);4423 const agg_ty = sema.typeOf(object_ptr).childType(zcu).optEuBaseType(zcu);
4991 switch (agg_ty.zigTypeTag(zcu)) {4424 switch (agg_ty.zigTypeTag(zcu)) {
4992 .@"struct" => return sema.validateStructInit(4425 .@"struct" => return sema.validateStructInit(
...@@ -5097,12 +4530,16 @@ fn validateStructInit(...@@ -5097,12 +4530,16 @@ fn validateStructInit(
5097 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);4530 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
50984531
5099 for (found_fields, 0..) |explicit, i_usize| {4532 for (found_fields, 0..) |explicit, i_usize| {
5100 if (explicit) continue;
5101 const i: u32 = @intCast(i_usize);4533 const i: u32 = @intCast(i_usize);
51024534
5103 try struct_ty.resolveStructFieldInits(pt);4535 if (explicit) continue;
5104 const default_val = struct_ty.structFieldDefaultValue(i, zcu);4536 if (struct_ty.structFieldIsComptime(i, zcu)) continue;
5105 if (default_val.toIntern() == .unreachable_value) {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 {
5106 const field_name = struct_ty.structFieldName(i, zcu).unwrap() orelse {4543 const field_name = struct_ty.structFieldName(i, zcu).unwrap() orelse {
5107 const template = "missing tuple field with index {d}";4544 const template = "missing tuple field with index {d}";
5108 if (root_msg) |msg| {4545 if (root_msg) |msg| {
...@@ -5120,13 +4557,10 @@ fn validateStructInit(...@@ -5120,13 +4557,10 @@ fn validateStructInit(
5120 root_msg = try sema.errMsg(init_src, template, args);4557 root_msg = try sema.errMsg(init_src, template, args);
5121 }4558 }
5122 continue;4559 continue;
5123 }4560 };
51244561
5125 const field_src = init_src; // TODO better source location4562 const field_src = init_src; // TODO better source location
5126 const default_field_ptr = if (struct_ty.isTuple(zcu))4563 const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), struct_ty);
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);
5130 try sema.checkKnownAllocPtr(block, struct_ptr, default_field_ptr);4564 try sema.checkKnownAllocPtr(block, struct_ptr, default_field_ptr);
5131 try sema.storePtr2(block, init_src, default_field_ptr, init_src, .fromValue(default_val), field_src, .store);4565 try sema.storePtr2(block, init_src, default_field_ptr, init_src, .fromValue(default_val), field_src, .store);
5132 }4566 }
...@@ -5151,7 +4585,7 @@ fn zirValidatePtrArrayInit(...@@ -5151,7 +4585,7 @@ fn zirValidatePtrArrayInit(
5151 const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len);4585 const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len);
5152 const first_elem_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node;4586 const first_elem_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node;
5153 const elem_ptr_extra = sema.code.extraData(Zir.Inst.ElemPtrImm, first_elem_ptr_data.payload_index).data;4587 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);
5155 const array_ty = sema.typeOf(array_ptr).childType(zcu).optEuBaseType(zcu);4589 const array_ty = sema.typeOf(array_ptr).childType(zcu).optEuBaseType(zcu);
5156 const array_len = array_ty.arrayLen(zcu);4590 const array_len = array_ty.arrayLen(zcu);
51574591
...@@ -5166,11 +4600,9 @@ fn zirValidatePtrArrayInit(...@@ -5166,11 +4600,9 @@ fn zirValidatePtrArrayInit(
5166 var root_msg: ?*Zcu.ErrorMsg = null;4600 var root_msg: ?*Zcu.ErrorMsg = null;
5167 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);4601 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
51684602
5169 try array_ty.resolveStructFieldInits(pt);
5170 var i = instrs.len;4603 var i = instrs.len;
5171 while (i < array_len) : (i += 1) {4604 while (i < array_len) : (i += 1) {
5172 const default_val = array_ty.structFieldDefaultValue(i, zcu).toIntern();4605 if (array_ty.structFieldDefaultValue(i, zcu) == null) {
5173 if (default_val == .unreachable_value) {
5174 const template = "missing tuple field with index {d}";4606 const template = "missing tuple field with index {d}";
5175 if (root_msg) |msg| {4607 if (root_msg) |msg| {
5176 try sema.errNote(init_src, msg, template, .{i});4608 try sema.errNote(init_src, msg, template, .{i});
...@@ -5213,7 +4645,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5213,7 +4645,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5213 const zcu = pt.zcu;4645 const zcu = pt.zcu;
5214 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4646 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
5215 const src = block.nodeOffset(inst_data.src_node);4647 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);
5217 const operand_ty = sema.typeOf(operand);4649 const operand_ty = sema.typeOf(operand);
52184650
5219 if (operand_ty.zigTypeTag(zcu) != .pointer) {4651 if (operand_ty.zigTypeTag(zcu) != .pointer) {
...@@ -5224,40 +4656,14 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5224,40 +4656,14 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5224 .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{operand_ty.fmt(pt)}),4656 .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{operand_ty.fmt(pt)}),
5225 }4657 }
52264658
5227 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(zcu))) != null) {4659 if (sema.resolveValue(operand)) |val| {
5228 // No need to validate the actual pointer value, we don't need it!4660 // Error for deref of undef pointer, unless the pointee is OPV in which case it's legal.
5229 return;4661 if (val.isUndef(zcu) and operand_ty.childType(zcu).classify(zcu) != .one_possible_value) {
5230 }
5231
5232 const elem_ty = operand_ty.elemType2(zcu);
5233 if (try sema.resolveValue(operand)) |val| {
5234 if (val.isUndef(zcu)) {
5235 return sema.fail(block, src, "cannot dereference undefined value", .{});4662 return sema.fail(block, src, "cannot dereference undefined value", .{});
5236 }4663 }
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);
5250 }4664 }
5251}4665}
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
5261fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4667fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5262 const pt = sema.pt;4668 const pt = sema.pt;
5263 const zcu = pt.zcu;4669 const zcu = pt.zcu;
...@@ -5265,17 +4671,17 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -5265,17 +4671,17 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
5265 const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;4671 const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
5266 const src = block.nodeOffset(inst_data.src_node);4672 const src = block.nodeOffset(inst_data.src_node);
5267 const destructure_src = block.nodeOffset(extra.destructure_node);4673 const destructure_src = block.nodeOffset(extra.destructure_node);
5268 const operand = try sema.resolveInst(extra.operand);4674 const operand = sema.resolveInst(extra.operand);
5269 const operand_ty = sema.typeOf(operand);4675 const operand_ty = sema.typeOf(operand);
52704676
5271 if (!typeIsDestructurable(operand_ty, zcu)) {4677 if (!operand_ty.destructurable(zcu)) {
5272 return sema.failWithOwnedErrorMsg(block, msg: {4678 return sema.failWithOwnedErrorMsg(block, msg: {
5273 const msg = try sema.errMsg(src, "type '{f}' cannot be destructured", .{operand_ty.fmt(pt)});4679 const msg = try sema.errMsg(src, "type '{f}' cannot be destructured", .{operand_ty.fmt(pt)});
5274 errdefer msg.destroy(sema.gpa);4680 errdefer msg.destroy(sema.gpa);
5275 try sema.errNote(destructure_src, msg, "result destructured here", .{});4681 try sema.errNote(destructure_src, msg, "result destructured here", .{});
5276 if (operand_ty.zigTypeTag(pt.zcu) == .error_union) {4682 if (operand_ty.zigTypeTag(pt.zcu) == .error_union) {
5277 const base_op_ty = operand_ty.errorUnionPayload(zcu);4683 const base_op_ty = operand_ty.errorUnionPayload(zcu);
5278 if (typeIsDestructurable(base_op_ty, zcu))4684 if (base_op_ty.destructurable(zcu))
5279 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});4685 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
5280 }4686 }
5281 break :msg msg;4687 break :msg msg;
...@@ -5373,7 +4779,7 @@ fn failWithBadUnionFieldAccess(...@@ -5373,7 +4779,7 @@ fn failWithBadUnionFieldAccess(
5373 return sema.failWithOwnedErrorMsg(block, msg);4779 return sema.failWithOwnedErrorMsg(block, msg);
5374}4780}
53754781
5376fn addDeclaredHereNote(sema: *Sema, parent: *Zcu.ErrorMsg, decl_ty: Type) !void {4782pub fn addDeclaredHereNote(sema: *Sema, parent: *Zcu.ErrorMsg, decl_ty: Type) !void {
5377 const zcu = sema.pt.zcu;4783 const zcu = sema.pt.zcu;
5378 const src_loc = decl_ty.srcLocOrNull(zcu) orelse return;4784 const src_loc = decl_ty.srcLocOrNull(zcu) orelse return;
5379 const category = switch (decl_ty.zigTypeTag(zcu)) {4785 const category = switch (decl_ty.zigTypeTag(zcu)) {
...@@ -5393,8 +4799,8 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi...@@ -5393,8 +4799,8 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
5393 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4799 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5394 const src = block.nodeOffset(pl_node.src_node);4800 const src = block.nodeOffset(pl_node.src_node);
5395 const bin = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;4801 const bin = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
5396 const ptr = try sema.resolveInst(bin.lhs);4802 const ptr = sema.resolveInst(bin.lhs);
5397 const operand = try sema.resolveInst(bin.rhs);4803 const operand = sema.resolveInst(bin.rhs);
5398 const ptr_inst = ptr.toIndex().?;4804 const ptr_inst = ptr.toIndex().?;
5399 const air_datas = sema.air_instructions.items(.data);4805 const air_datas = sema.air_instructions.items(.data);
54004806
...@@ -5440,17 +4846,19 @@ fn storeToInferredAllocComptime(...@@ -5440,17 +4846,19 @@ fn storeToInferredAllocComptime(
5440 const operand_ty = sema.typeOf(operand);4846 const operand_ty = sema.typeOf(operand);
5441 // There will be only one store_to_inferred_ptr because we are running at comptime.4847 // There will be only one store_to_inferred_ptr because we are running at comptime.
5442 // The alloc will turn into a Decl or a ComptimeAlloc.4848 // 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 {
5444 return sema.failWithNeededComptime(block, src, .{ .simple = .stored_to_comptime_var });4850 return sema.failWithNeededComptime(block, src, .{ .simple = .stored_to_comptime_var });
5445 };4851 };
5446 const alloc_ty = try pt.ptrTypeSema(.{4852 const alloc_ty = try pt.ptrType(.{
5447 .child = operand_ty.toIntern(),4853 .child = operand_ty.toIntern(),
5448 .flags = .{4854 .flags = .{
5449 .alignment = iac.alignment,4855 .alignment = iac.alignment,
5450 .is_const = iac.is_const,4856 .is_const = iac.is_const,
5451 },4857 },
5452 });4858 });
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 {
5454 iac.ptr = try pt.intern(.{ .ptr = .{4862 iac.ptr = try pt.intern(.{ .ptr = .{
5455 .ty = alloc_ty.toIntern(),4863 .ty = alloc_ty.toIntern(),
5456 .base_addr = .{ .uav = .{4864 .base_addr = .{ .uav = .{
...@@ -5487,8 +4895,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v...@@ -5487,8 +4895,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
5487 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;4895 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;
5488 const src = block.nodeOffset(inst_data.src_node);4896 const src = block.nodeOffset(inst_data.src_node);
5489 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;4897 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5490 const ptr = try sema.resolveInst(extra.lhs);4898 const ptr = sema.resolveInst(extra.lhs);
5491 const operand = try sema.resolveInst(extra.rhs);4899 const operand = sema.resolveInst(extra.rhs);
54924900
5493 const is_ret = if (extra.lhs.toIndex()) |ptr_index|4901 const is_ret = if (extra.lhs.toIndex()) |ptr_index|
5494 zir_tags[@intFromEnum(ptr_index)] == .ret_ptr4902 zir_tags[@intFromEnum(ptr_index)] == .ret_ptr
...@@ -5535,11 +4943,11 @@ pub fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!...@@ -5535,11 +4943,11 @@ pub fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!
5535 .ty = array_ty.toIntern(),4943 .ty = array_ty.toIntern(),
5536 .storage = .{ .bytes = string },4944 .storage = .{ .bytes = string },
5537 } });4945 } });
5538 return sema.uavRef(val);4946 return sema.uavRef(.fromInterned(val));
5539}4947}
55404948
5541fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {4949fn uavRef(sema: *Sema, val: Value) CompileError!Air.Inst.Ref {
5542 return Air.internedToRef(try sema.pt.refValue(val));4950 return .fromValue(try sema.pt.uavValue(val));
5543}4951}
55444952
5545fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4953fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -5622,9 +5030,9 @@ fn zirCompileLog(...@@ -5622,9 +5030,9 @@ fn zirCompileLog(
5622 for (args, 0..) |arg_ref, i| {5030 for (args, 0..) |arg_ref, i| {
5623 if (i != 0) writer.writeAll(", ") catch return error.OutOfMemory;5031 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);
5626 const arg_ty = sema.typeOf(arg);5034 const arg_ty = sema.typeOf(arg);
5627 if (try sema.resolveValueResolveLazy(arg)) |val| {5035 if (sema.resolveValue(arg)) |val| {
5628 writer.print("@as({f}, {f})", .{5036 writer.print("@as({f}, {f})", .{
5629 arg_ty.fmt(pt), val.fmtValueSema(pt, sema),5037 arg_ty.fmt(pt), val.fmtValueSema(pt, sema),
5630 }) catch return error.OutOfMemory;5038 }) catch return error.OutOfMemory;
...@@ -5672,7 +5080,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -5672,7 +5080,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
56725080
5673 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;5081 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
5674 const src = block.nodeOffset(inst_data.src_node);5082 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
5677 const arg_src = block.builtinCallArgSrc(inst_data.src_node, 0);5085 const arg_src = block.builtinCallArgSrc(inst_data.src_node, 0);
5678 const coerced_msg = try sema.coerce(block, .slice_const_u8, msg_inst, arg_src);5086 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...@@ -5752,9 +5160,9 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5752 var label: Block.Label = .{5160 var label: Block.Label = .{
5753 .zir_block = inst,5161 .zir_block = inst,
5754 .merges = .{5162 .merges = .{
5755 .src_locs = .{},5163 .src_locs = .empty,
5756 .results = .{},5164 .results = .empty,
5757 .br_list = .{},5165 .br_list = .empty,
5758 .block_inst = block_inst,5166 .block_inst = block_inst,
5759 },5167 },
5760 };5168 };
...@@ -5826,7 +5234,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5826,7 +5234,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5826 .parent = parent_block,5234 .parent = parent_block,
5827 .sema = sema,5235 .sema = sema,
5828 .namespace = parent_block.namespace,5236 .namespace = parent_block.namespace,
5829 .instructions = .{},5237 .instructions = .empty,
5830 .inlining = parent_block.inlining,5238 .inlining = parent_block.inlining,
5831 .comptime_reason = .{ .reason = .{5239 .comptime_reason = .{ .reason = .{
5832 .src = src,5240 .src = src,
...@@ -5927,11 +5335,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5927,11 +5335,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5927 pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err|5335 pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err|
5928 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});5336 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
59295337
5930 try pt.ensureFileAnalyzed(new_file_index);5338 try pt.ensureFilePopulated(new_file_index);
5931 const ty = zcu.fileRootType(new_file_index);5339 const ty: Type = .fromInterned(zcu.fileRootType(new_file_index));
5932 try sema.declareDependency(.{ .interned = ty });
5933 try sema.addTypeReferenceEntry(src, ty);5340 try sema.addTypeReferenceEntry(src, ty);
5934 return Air.internedToRef(ty);5341 return .fromType(ty);
5935}5342}
59365343
5937fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5344fn 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...@@ -5962,9 +5369,9 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5962 var label: Block.Label = .{5369 var label: Block.Label = .{
5963 .zir_block = inst,5370 .zir_block = inst,
5964 .merges = .{5371 .merges = .{
5965 .src_locs = .{},5372 .src_locs = .empty,
5966 .results = .{},5373 .results = .empty,
5967 .br_list = .{},5374 .br_list = .empty,
5968 .block_inst = block_inst,5375 .block_inst = block_inst,
5969 },5376 },
5970 };5377 };
...@@ -5973,7 +5380,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5973,7 +5380,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5973 .parent = parent_block,5380 .parent = parent_block,
5974 .sema = sema,5381 .sema = sema,
5975 .namespace = parent_block.namespace,5382 .namespace = parent_block.namespace,
5976 .instructions = .{},5383 .instructions = .empty,
5977 .label = &label,5384 .label = &label,
5978 .inlining = parent_block.inlining,5385 .inlining = parent_block.inlining,
5979 .comptime_reason = parent_block.comptime_reason,5386 .comptime_reason = parent_block.comptime_reason,
...@@ -6043,7 +5450,7 @@ fn resolveBlockBody(...@@ -6043,7 +5450,7 @@ fn resolveBlockBody(
6043 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";5450 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";
6044 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;5451 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
6045 if (extra.block_inst == body_inst) {5452 if (extra.block_inst == body_inst) {
6046 return try sema.resolveInst(break_data.operand);5453 return sema.resolveInst(break_data.operand);
6047 } else {5454 } else {
6048 return error.ComptimeBreak;5455 return error.ComptimeBreak;
6049 }5456 }
...@@ -6134,7 +5541,7 @@ fn resolveAnalyzedBlock(...@@ -6134,7 +5541,7 @@ fn resolveAnalyzedBlock(
6134 // Okay, we need a runtime block. If the value is comptime-known, the5541 // Okay, we need a runtime block. If the value is comptime-known, the
6135 // block should just return void, and we return the merge result5542 // block should just return void, and we return the merge result
6136 // directly. Otherwise, we can defer to the logic below.5543 // 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| {
6138 // Create a block containing all instruction from the body.5545 // Create a block containing all instruction from the body.
6139 try parent_block.instructions.append(gpa, merges.block_inst);5546 try parent_block.instructions.append(gpa, merges.block_inst);
6140 switch (block_tag) {5547 switch (block_tag) {
...@@ -6177,10 +5584,11 @@ fn resolveAnalyzedBlock(...@@ -6177,10 +5584,11 @@ fn resolveAnalyzedBlock(
6177 // to emit a jump instruction to after the block when it encounters the break.5584 // to emit a jump instruction to after the block when it encounters the break.
6178 try parent_block.instructions.append(gpa, merges.block_inst);5585 try parent_block.instructions.append(gpa, merges.block_inst);
6179 const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items });5586 const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items });
5587 resolved_ty.assertHasLayout(zcu);
6180 // TODO add note "missing else causes void value"5588 // TODO add note "missing else causes void value"
61815589
6182 const type_src = src; // TODO: better source location5590 const type_src = src; // TODO: better source location
6183 if (try resolved_ty.comptimeOnlySema(pt)) {5591 if (resolved_ty.comptimeOnly(zcu)) {
6184 const msg = msg: {5592 const msg = msg: {
6185 const msg = try sema.errMsg(type_src, "value with comptime-only type '{f}' depends on runtime control flow", .{resolved_ty.fmt(pt)});5593 const msg = try sema.errMsg(type_src, "value with comptime-only type '{f}' depends on runtime control flow", .{resolved_ty.fmt(pt)});
6186 errdefer msg.destroy(sema.gpa);5594 errdefer msg.destroy(sema.gpa);
...@@ -6274,10 +5682,7 @@ fn resolveAnalyzedBlock(...@@ -6274,10 +5682,7 @@ fn resolveAnalyzedBlock(
6274 });5682 });
6275 }5683 }
62765684
6277 if (try sema.typeHasOnePossibleValue(resolved_ty)) |block_only_value| {5685 if (try resolved_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
6278 return Air.internedToRef(block_only_value.toIntern());
6279 }
6280
6281 return merges.block_inst.toRef();5686 return merges.block_inst.toRef();
6282}5687}
62835688
...@@ -6295,7 +5700,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -6295,7 +5700,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6295 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);5700 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);
6296 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);5701 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);
6299 const ptr_val = try sema.resolveConstDefinedValue(block, ptr_src, ptr, .{ .simple = .export_target });5704 const ptr_val = try sema.resolveConstDefinedValue(block, ptr_src, ptr, .{ .simple = .export_target });
6300 const ptr_ty = ptr_val.typeOf(zcu);5705 const ptr_ty = ptr_val.typeOf(zcu);
63015706
...@@ -6314,91 +5719,95 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -6314,91 +5719,95 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6314 }5719 }
6315 }5720 }
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
6317 const ptr_info = ip.indexToKey(ptr_val.toIntern()).ptr;5734 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) {
6319 .comptime_alloc, .int, .comptime_field => return sema.fail(block, ptr_src, "export target must be a global variable or a comptime-known constant", .{}),5736 .comptime_alloc, .int, .comptime_field => return sema.fail(block, ptr_src, "export target must be a global variable or a comptime-known constant", .{}),
6320 .eu_payload, .opt_payload, .field, .arr_elem => return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}),5737 .eu_payload, .opt_payload, .field, .arr_elem => return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}),
6321 .uav => |uav| {5738 .uav => |uav| .{ .uav = uav.val },
6322 if (ptr_info.byte_offset != 0) {5739 .nav => |orig_nav| target: {
6323 return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});5740 try sema.ensureNavResolved(block, src, orig_nav, .fully);
6324 }5741 const export_nav = switch (ip.indexToKey(ip.getNav(orig_nav).status.fully_resolved.val)) {
6325 if (zcu.llvm_object != null and options.linkage == .internal) return;5742 .variable => |v| v.owner_nav,
6326 const export_ty = Value.fromInterned(uav.val).typeOf(zcu);5743 .@"extern" => |e| e.owner_nav,
6327 if (!try sema.validateExternType(export_ty, .other)) {5744 .func => |f| f.owner_nav,
6328 return sema.failWithOwnedErrorMsg(block, msg: {5745 else => orig_nav,
6329 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});5746 };
6330 errdefer msg.destroy(sema.gpa);5747 if (ip.getNav(export_nav).getExtern(ip) != null) {
6331 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);5748 return sema.fail(block, src, "export target cannot be extern", .{});
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", .{});
6346 }5749 }
6347 try sema.analyzeExport(block, src, options, nav);5750 try sema.maybeQueueFuncBodyAnalysis(block, src, export_nav);
5751 break :target .{ .nav = export_nav };
6348 },5752 },
5753 };
5754 if (ptr_info.byte_offset != 0) {
5755 return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
6349 }5756 }
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 });
6350}5764}
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(
6353 sema: *Sema,5770 sema: *Sema,
6354 block: *Block,5771 block: *Block,
6355 src: LazySrcLoc,5772 src: LazySrcLoc,
6356 options: Zcu.Export.Options,5773 name: InternPool.NullTerminatedString,
6357 orig_nav_index: InternPool.Nav.Index,
6358) !void {5774) !void {
6359 const gpa = sema.gpa;5775 const gpa = sema.gpa;
6360 const pt = sema.pt;5776 const pt = sema.pt;
6361 const zcu = pt.zcu;5777 const zcu = pt.zcu;
6362 const ip = &zcu.intern_pool;5778 const ip = &zcu.intern_pool;
63635779
6364 if (zcu.llvm_object != null and options.linkage == .internal)5780 const orig_nav = sema.owner.unwrap().nav_val;
6365 return;5781 const export_val: Value = .fromInterned(ip.getNav(orig_nav).status.fully_resolved.val);
63665782 const export_ty = export_val.typeOf(zcu);
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));
63785783
6379 if (!try sema.validateExternType(export_ty, .other)) {5784 if (!export_ty.validateExtern(.other, zcu)) {
6380 return sema.failWithOwnedErrorMsg(block, msg: {5785 return sema.failWithOwnedErrorMsg(block, msg: {
6381 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});5786 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
6382 errdefer msg.destroy(gpa);5787 errdefer msg.destroy(gpa);
6383
6384 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);5788 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
6385
6386 try sema.addDeclaredHereNote(msg, export_ty);5789 try sema.addDeclaredHereNote(msg, export_ty);
6387 break :msg msg;5790 break :msg msg;
6388 });5791 });
6389 }5792 }
63905793
6391 // TODO: some backends might support re-exporting extern decls5794 const export_nav = switch (ip.indexToKey(export_val.toIntern())) {
6392 if (exported_nav.getExtern(ip) != null) {5795 .variable => |v| v.owner_nav,
6393 return sema.fail(block, src, "export target cannot be extern", .{});5796 .@"extern" => |e| e.owner_nav,
6394 }5797 .func => |f| export_nav: {
63955798 assert(export_ty.fnHasRuntimeBits(zcu)); // otherwise `validateExtern` failed above
6396 try sema.maybeQueueFuncBodyAnalysis(block, src, exported_nav_index);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
6398 try sema.exports.append(gpa, .{5807 try sema.exports.append(gpa, .{
6399 .opts = options,5808 .opts = .{ .name = name },
6400 .src = src,5809 .src = src,
6401 .exported = .{ .nav = exported_nav_index },5810 .exported = .{ .nav = export_nav },
6402 .status = .in_progress,5811 .status = .in_progress,
6403 });5812 });
6404}5813}
...@@ -6413,7 +5822,8 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {...@@ -6413,7 +5822,8 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
6413 .@"comptime",5822 .@"comptime",
6414 .nav_val,5823 .nav_val,
6415 .nav_ty,5824 .nav_ty,
6416 .type,5825 .type_layout,
5826 .struct_defaults,
6417 .memoized_state,5827 .memoized_state,
6418 => return, // does nothing outside a function5828 => return, // does nothing outside a function
6419 };5829 };
...@@ -6431,7 +5841,8 @@ fn zirDisableIntrinsics(sema: *Sema) CompileError!void {...@@ -6431,7 +5841,8 @@ fn zirDisableIntrinsics(sema: *Sema) CompileError!void {
6431 .@"comptime",5841 .@"comptime",
6432 .nav_val,5842 .nav_val,
6433 .nav_ty,5843 .nav_ty,
6434 .type,5844 .type_layout,
5845 .struct_defaults,
6435 .memoized_state,5846 .memoized_state,
6436 => return, // does nothing outside a function5847 => return, // does nothing outside a function
6437 };5848 };
...@@ -6457,7 +5868,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6457,7 +5868,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
64575868
6458 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";5869 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
6459 const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;5870 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);
6461 const zir_block = extra.block_inst;5872 const zir_block = extra.block_inst;
64625873
6463 var block = start_block;5874 var block = start_block;
...@@ -6491,7 +5902,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com...@@ -6491,7 +5902,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com
6491 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";5902 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
6492 const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;5903 const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
6493 const operand_src = start_block.nodeOffset(extra.operand_src_node.unwrap().?);5904 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);
6495 const switch_inst = extra.block_inst;5906 const switch_inst = extra.block_inst;
64965907
6497 switch (sema.code.instructions.items(.tag)[@intFromEnum(switch_inst)]) {5908 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...@@ -6500,7 +5911,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com
6500 else => unreachable, // assertion failure5911 else => unreachable, // assertion failure
6501 }5912 }
65025913
6503 const operand_ty = (try sema.resolveInst(switch_inst.toRef())).toType();5914 const operand_ty = (sema.resolveInst(switch_inst.toRef())).toType();
6504 const operand = try sema.coerce(start_block, operand_ty, uncoerced_operand, operand_src);5915 const operand = try sema.coerce(start_block, operand_ty, uncoerced_operand, operand_src);
6505 try sema.validateRuntimeValue(start_block, operand_src, operand);5916 try sema.validateRuntimeValue(start_block, operand_src, operand);
65065917
...@@ -6567,7 +5978,7 @@ fn zirDbgVar(...@@ -6567,7 +5978,7 @@ fn zirDbgVar(
6567 air_tag: Air.Inst.Tag,5978 air_tag: Air.Inst.Tag,
6568) CompileError!void {5979) CompileError!void {
6569 const str_op = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_op;5980 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);
6571 const name = str_op.getStr(sema.code);5982 const name = str_op.getStr(sema.code);
6572 try sema.addDbgVar(block, operand, air_tag, name);5983 try sema.addDbgVar(block, operand, air_tag, name);
6573}5984}
...@@ -6589,9 +6000,9 @@ fn addDbgVar(...@@ -6589,9 +6000,9 @@ fn addDbgVar(
6589 .dbg_var_val, .dbg_arg_inline => operand_ty,6000 .dbg_var_val, .dbg_arg_inline => operand_ty,
6590 else => unreachable,6001 else => unreachable,
6591 };6002 };
6592 if (try val_ty.comptimeOnlySema(pt)) return;6003 if (val_ty.comptimeOnly(zcu)) return;
6593 if (!(try val_ty.hasRuntimeBitsSema(pt))) return;6004 if (!val_ty.hasRuntimeBits(zcu)) return;
6594 if (try sema.resolveValue(operand)) |operand_val| {6005 if (sema.resolveValue(operand)) |operand_val| {
6595 if (operand_val.canMutateComptimeVarState(zcu)) return;6006 if (operand_val.canMutateComptimeVarState(zcu)) return;
6596 }6007 }
65976008
...@@ -6730,7 +6141,7 @@ fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedIns...@@ -6730,7 +6141,7 @@ fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedIns
6730 const pt = sema.pt;6141 const pt = sema.pt;
6731 const zcu = pt.zcu;6142 const zcu = pt.zcu;
6732 const ip = &zcu.intern_pool;6143 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;
6734 if (func_val.isUndef(zcu)) return null;6145 if (func_val.isUndef(zcu)) return null;
6735 const nav = switch (ip.indexToKey(func_val.toIntern())) {6146 const nav = switch (ip.indexToKey(func_val.toIntern())) {
6736 .@"extern" => |e| e.owner_nav,6147 .@"extern" => |e| e.owner_nav,
...@@ -6759,7 +6170,6 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref...@@ -6759,7 +6170,6 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
6759 if (!block.ownerModule().error_tracing) return .none;6170 if (!block.ownerModule().error_tracing) return .none;
67606171
6761 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);6172 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);
6762 try stack_trace_ty.resolveFields(pt);
6763 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);6173 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);
6764 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {6174 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
6765 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),6175 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
...@@ -6803,11 +6213,10 @@ fn popErrorReturnTrace(...@@ -6803,11 +6213,10 @@ fn popErrorReturnTrace(
6803 // the result is comptime-known to be a non-error. Either way, pop unconditionally.6213 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
68046214
6805 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);6215 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
6806 try stack_trace_ty.resolveFields(pt);
6807 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);6216 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
6808 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);6217 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
6809 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);6218 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);
6811 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);6220 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
6812 } else if (is_non_error == null) {6221 } else if (is_non_error == null) {
6813 // The result might be an error. If it is, we leave the error trace alone. If it isn't, we need6222 // 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(...@@ -6829,11 +6238,10 @@ fn popErrorReturnTrace(
68296238
6830 // If non-error, then pop the error return trace by restoring the index.6239 // If non-error, then pop the error return trace by restoring the index.
6831 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);6240 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
6832 try stack_trace_ty.resolveFields(pt);
6833 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);6241 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
6834 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);6242 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
6835 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);6243 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);
6837 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);6245 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
6838 _ = try then_block.addBr(cond_block_inst, .void_value);6246 _ = try then_block.addBr(cond_block_inst, .void_value);
68396247
...@@ -6905,9 +6313,9 @@ fn zirCall(...@@ -6905,9 +6313,9 @@ fn zirCall(
6905 const pop_error_return_trace = extra.data.flags.pop_error_return_trace;6313 const pop_error_return_trace = extra.data.flags.pop_error_return_trace;
69066314
6907 const callee: ResolvedFieldCallee = switch (kind) {6315 const callee: ResolvedFieldCallee = switch (kind) {
6908 .direct => .{ .direct = try sema.resolveInst(extra.data.callee) },6316 .direct => .{ .direct = sema.resolveInst(extra.data.callee) },
6909 .field => blk: {6317 .field => blk: {
6910 const object_ptr = try sema.resolveInst(extra.data.obj_ptr);6318 const object_ptr = sema.resolveInst(extra.data.obj_ptr);
6911 const field_name = try zcu.intern_pool.getOrPutString(6319 const field_name = try zcu.intern_pool.getOrPutString(
6912 gpa,6320 gpa,
6913 io,6321 io,
...@@ -6969,7 +6377,6 @@ fn zirCall(...@@ -6969,7 +6377,6 @@ fn zirCall(
6969 // need to clean-up our own trace if we were passed to a non-error-handling expression.6377 // need to clean-up our own trace if we were passed to a non-error-handling expression.
6970 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {6378 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {
6971 const stack_trace_ty = try sema.getBuiltinType(call_src, .StackTrace);6379 const stack_trace_ty = try sema.getBuiltinType(call_src, .StackTrace);
6972 try stack_trace_ty.resolveFields(pt);
6973 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);6380 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);
6974 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);6381 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
69756382
...@@ -7255,7 +6662,7 @@ const CallArgsInfo = union(enum) {...@@ -7255,7 +6662,7 @@ const CallArgsInfo = union(enum) {
7255 return sema.failWithNeededComptime(block, cai.argSrc(block, arg_index), null);6662 return sema.failWithNeededComptime(block, cai.argSrc(block, arg_index), null);
7256 }6663 }
72576664
7258 if (sema.typeOf(uncoerced_arg).zigTypeTag(zcu) == .noreturn) {6665 if (sema.typeOf(uncoerced_arg).classify(zcu) == .no_possible_value) {
7259 // This terminates resolution of arguments. The caller should6666 // This terminates resolution of arguments. The caller should
7260 // propagate this.6667 // propagate this.
7261 return uncoerced_arg;6668 return uncoerced_arg;
...@@ -7318,6 +6725,21 @@ fn analyzeCall(...@@ -7318,6 +6725,21 @@ fn analyzeCall(
7318 } else func_src;6725 } else func_src;
73196726
7320 const func_ty_info = zcu.typeToFunc(func_ty).?;6727 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
7321 if (!callConvIsCallable(func_ty_info.cc)) {6743 if (!callConvIsCallable(func_ty_info.cc)) {
7322 return sema.failWithOwnedErrorMsg(block, msg: {6744 return sema.failWithOwnedErrorMsg(block, msg: {
7323 const msg = try sema.errMsg(6745 const msg = try sema.errMsg(
...@@ -7334,6 +6756,28 @@ fn analyzeCall(...@@ -7334,6 +6756,28 @@ fn analyzeCall(
7334 });6756 });
7335 }6757 }
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
7337 // We need this value in a few code paths.6781 // We need this value in a few code paths.
7338 const callee_val = try sema.resolveDefinedValue(block, call_src, callee);6782 const callee_val = try sema.resolveDefinedValue(block, call_src, callee);
7339 // If the callee is a comptime-known *non-extern* function, `func_val` is populated.6783 // If the callee is a comptime-known *non-extern* function, `func_val` is populated.
...@@ -7353,7 +6797,7 @@ fn analyzeCall(...@@ -7353,7 +6797,7 @@ fn analyzeCall(
7353 else => unreachable,6797 else => unreachable,
7354 } else .{ null, false };6798 } 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) {
7357 return sema.failWithNeededComptime(block, func_src, .{ .simple = .generic_call_target });6801 return sema.failWithNeededComptime(block, func_src, .{ .simple = .generic_call_target });
7358 }6802 }
73596803
...@@ -7369,19 +6813,18 @@ fn analyzeCall(...@@ -7369,19 +6813,18 @@ fn analyzeCall(
7369 .src = call_src,6813 .src = call_src,
7370 .r = .{ .simple = .comptime_call_modifier },6814 .r = .{ .simple = .comptime_call_modifier },
7371 } };6815 } };
7372 } else if (!inline_requested and try Type.fromInterned(func_ty_info.return_type).comptimeOnlySema(pt)) {6816 } else if (!inline_requested) {
7373 block.comptime_reason = .{6817 const ret_ty: Type = .fromInterned(func_ty_info.return_type);
7374 .reason = .{6818 if (ret_ty.comptimeOnly(zcu)) {
6819 block.comptime_reason = .{ .reason = .{
7375 .src = call_src,6820 .src = call_src,
7376 .r = .{6821 .r = .{ .comptime_only_ret_ty = .{
7377 .comptime_only_ret_ty = .{6822 .ty = .fromInterned(func_ty_info.return_type),
7378 .ty = .fromInterned(func_ty_info.return_type),6823 .is_generic_inst = false,
7379 .is_generic_inst = false,6824 .ret_ty_src = func_ret_ty_src,
7380 .ret_ty_src = func_ret_ty_src,6825 } },
7381 },6826 } };
7382 },6827 }
7383 },
7384 };
7385 }6828 }
7386 }6829 }
73876830
...@@ -7403,13 +6846,13 @@ fn analyzeCall(...@@ -7403,13 +6846,13 @@ fn analyzeCall(
7403 // This is the `inst_map` used when evaluating generic parameters and return types.6846 // This is the `inst_map` used when evaluating generic parameters and return types.
7404 var generic_inst_map: InstMap = .{};6847 var generic_inst_map: InstMap = .{};
7405 defer generic_inst_map.deinit(gpa);6848 defer generic_inst_map.deinit(gpa);
7406 if (func_ty_info.is_generic) {6849 if (any_generic_types) {
7407 try generic_inst_map.ensureSpaceForInstructions(gpa, fn_zir_info.param_body);6850 try generic_inst_map.ensureSpaceForInstructions(gpa, fn_zir_info.param_body);
7408 }6851 }
74096852
7410 // This exists so that `generic_block` below can include a "called from here" note back to this6853 // This exists so that `generic_block` below can include a "called from here" note back to this
7411 // call site when analyzing generic parameter/return types.6854 // 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) .{
7413 .call_block = block,6856 .call_block = block,
7414 .call_src = call_src,6857 .call_src = call_src,
7415 .func = func_val.?.toIntern(),6858 .func = func_val.?.toIntern(),
...@@ -7422,18 +6865,18 @@ fn analyzeCall(...@@ -7422,18 +6865,18 @@ fn analyzeCall(
7422 // This is the block in which we evaluate generic function components: that is, generic parameter6865 // This is the block in which we evaluate generic function components: that is, generic parameter
7423 // types and the generic return type. This must not be used if the function is not generic.6866 // types and the generic return type. This must not be used if the function is not generic.
7424 // `comptime_reason` is set as needed.6867 // `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) .{
7426 .parent = null,6869 .parent = null,
7427 .sema = sema,6870 .sema = sema,
7428 .namespace = fn_nav.analysis.?.namespace,6871 .namespace = fn_nav.analysis.?.namespace,
7429 .instructions = .{},6872 .instructions = .empty,
7430 .inlining = &generic_inlining,6873 .inlining = &generic_inlining,
7431 .src_base_inst = fn_nav.analysis.?.zir_index,6874 .src_base_inst = fn_nav.analysis.?.zir_index,
7432 .type_name_ctx = fn_nav.fqn,6875 .type_name_ctx = fn_nav.fqn,
7433 } else undefined;6876 } 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) {
7437 // We certainly depend on the generic owner's signature!6880 // We certainly depend on the generic owner's signature!
7438 try sema.declareDependency(.{ .src_hash = fn_tracked_inst });6881 try sema.declareDependency(.{ .src_hash = fn_tracked_inst });
7439 }6882 }
...@@ -7445,7 +6888,7 @@ fn analyzeCall(...@@ -7445,7 +6888,7 @@ fn analyzeCall(
7445 if (raw != .generic_poison_type) break :ty .fromInterned(raw);6888 if (raw != .generic_poison_type) break :ty .fromInterned(raw);
74466889
7447 // We must discover the generic parameter type.6890 // We must discover the generic parameter type.
7448 assert(func_ty_info.is_generic);6891 assert(any_generic_types);
7449 const param_inst_idx = fn_zir_info.param_body[arg_idx];6892 const param_inst_idx = fn_zir_info.param_body[arg_idx];
7450 const param_inst = fn_zir.instructions.get(@intFromEnum(param_inst_idx));6893 const param_inst = fn_zir.instructions.get(@intFromEnum(param_inst_idx));
7451 switch (param_inst.tag) {6894 switch (param_inst.tag) {
...@@ -7476,7 +6919,7 @@ fn analyzeCall(...@@ -7476,7 +6919,7 @@ fn analyzeCall(
7476 } };6919 } };
74776920
7478 const ty_ref = try sema.resolveInlineBody(&generic_block, body, param_inst_idx);6921 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
7481 if (!param_ty.isValidParamType(zcu)) {6924 if (!param_ty.isValidParamType(zcu)) {
7482 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";6925 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
...@@ -7490,15 +6933,15 @@ fn analyzeCall(...@@ -7490,15 +6933,15 @@ fn analyzeCall(
74906933
7491 arg.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, callee, maybe_func_inst);6934 arg.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, callee, maybe_func_inst);
7492 const arg_ty = sema.typeOf(arg.*);6935 const arg_ty = sema.typeOf(arg.*);
7493 if (arg_ty.zigTypeTag(zcu) == .noreturn) {6936 if (arg_ty.classify(zcu) == .no_possible_value) {
7494 return arg.*; // terminate analysis here6937 return arg.*; // terminate analysis here
7495 }6938 }
74966939
7497 if (func_ty_info.is_generic) {6940 if (any_generic_types) {
7498 // We need to put the argument into `generic_inst_map` so that other parameters can refer to it.6941 // We need to put the argument into `generic_inst_map` so that other parameters can refer to it.
7499 const param_inst_idx = fn_zir_info.param_body[arg_idx];6942 const param_inst_idx = fn_zir_info.param_body[arg_idx];
7500 const declared_comptime = if (std.math.cast(u5, arg_idx)) |i| func_ty_info.paramIsComptime(i) else false;6943 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);
7502 // We allow comptime-known arguments to propagate to generic types not only for comptime6945 // We allow comptime-known arguments to propagate to generic types not only for comptime
7503 // parameters, but if the call is known to be inline.6946 // parameters, but if the call is known to be inline.
7504 if (param_is_comptime or early_known_inline) {6947 if (param_is_comptime or early_known_inline) {
...@@ -7516,6 +6959,10 @@ fn analyzeCall(...@@ -7516,6 +6959,10 @@ fn analyzeCall(
7516 );6959 );
7517 }6960 }
7518 generic_inst_map.putAssumeCapacityNoClobber(param_inst_idx, arg.*);6961 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));
7519 } else {6966 } else {
7520 // We need a dummy instruction with this type. It doesn't actually need to be in any block,6967 // We need a dummy instruction with this type. It doesn't actually need to be in any block,
7521 // since it will never be referenced at runtime!6968 // since it will never be referenced at runtime!
...@@ -7532,7 +6979,7 @@ fn analyzeCall(...@@ -7532,7 +6979,7 @@ fn analyzeCall(
7532 // calls (where it should be the IES of the instantiation). However, it's how we print this6979 // calls (where it should be the IES of the instantiation). However, it's how we print this
7533 // in error messages.6980 // in error messages.
7534 const resolved_ret_ty: Type = ret_ty: {6981 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
7537 const maybe_poison_bare = if (fn_zir_info.inferred_error_set) maybe_poison: {6984 const maybe_poison_bare = if (fn_zir_info.inferred_error_set) maybe_poison: {
7538 break :maybe_poison ip.errorUnionPayload(func_ty_info.return_type);6985 break :maybe_poison ip.errorUnionPayload(func_ty_info.return_type);
...@@ -7542,7 +6989,7 @@ fn analyzeCall(...@@ -7542,7 +6989,7 @@ fn analyzeCall(
75426989
7543 // Evaluate the generic return type. As with generic parameters, we switch out `sema.code` and `sema.inst_map`.6990 // 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
7547 const old_code = sema.code;6994 const old_code = sema.code;
7548 const old_inst_map = sema.inst_map;6995 const old_inst_map = sema.inst_map;
...@@ -7565,7 +7012,7 @@ fn analyzeCall(...@@ -7565,7 +7012,7 @@ fn analyzeCall(
7565 } else bare: {7012 } else bare: {
7566 assert(fn_zir_info.ret_ty_body.len != 0);7013 assert(fn_zir_info.ret_ty_body.len != 0);
7567 const ty_ref = try sema.resolveInlineBody(&generic_block, fn_zir_info.ret_ty_body, fn_zir_inst);7014 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);
7569 };7016 };
7570 assert(bare_ty.toIntern() != .generic_poison_type);7017 assert(bare_ty.toIntern() != .generic_poison_type);
75717018
...@@ -7584,10 +7031,11 @@ fn analyzeCall(...@@ -7584,10 +7031,11 @@ fn analyzeCall(
75847031
7585 break :ret_ty full_ty;7032 break :ret_ty full_ty;
7586 };7033 };
7034 try sema.ensureLayoutResolved(resolved_ret_ty, func_ret_ty_src, .return_type);
75877035
7588 // If we've discovered after evaluating arguments that a generic function instantiation is7036 // If we've discovered after evaluating arguments that a generic function instantiation is
7589 // comptime-only, then we can mark the block as comptime *now*.7037 // 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)) {
7591 block.comptime_reason = .{7039 block.comptime_reason = .{
7592 .reason = .{7040 .reason = .{
7593 .src = call_src,7041 .src = call_src,
...@@ -7618,15 +7066,23 @@ fn analyzeCall(...@@ -7618,15 +7066,23 @@ fn analyzeCall(
7618 });7066 });
7619 if (func_ty_info.cc == .auto) {7067 if (func_ty_info.cc == .auto) {
7620 switch (sema.owner.unwrap()) {7068 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
7622 .func => |owner_func| ip.funcSetHasErrorTrace(io, owner_func, true),7077 .func => |owner_func| ip.funcSetHasErrorTrace(io, owner_func, true),
7623 }7078 }
7624 }7079 }
7625 for (args, 0..) |arg, arg_idx| {7080 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);
7627 }7083 }
7628 const runtime_func: Air.Inst.Ref, const runtime_args: []const Air.Inst.Ref = func: {7084 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
7631 // Instantiate the generic function!7087 // Instantiate the generic function!
76327088
...@@ -7648,13 +7104,13 @@ fn analyzeCall(...@@ -7648,13 +7104,13 @@ fn analyzeCall(
7648 break :c true;7104 break :c true;
7649 }7105 }
7650 }7106 }
7651 break :c try arg_ty.comptimeOnlySema(pt);7107 break :c arg_ty.comptimeOnly(zcu);
7652 };7108 };
7653 const is_noalias = if (std.math.cast(u5, arg_idx)) |i| func_ty_info.paramIsNoalias(i) else false;7109 const is_noalias = if (std.math.cast(u5, arg_idx)) |i| func_ty_info.paramIsNoalias(i) else false;
76547110
7655 if (is_comptime) {7111 if (is_comptime) {
7656 // We already emitted an error if the argument isn't comptime-known.7112 // 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();
7658 } else {7114 } else {
7659 comptime_arg.* = .none;7115 comptime_arg.* = .none;
7660 if (is_noalias) {7116 if (is_noalias) {
...@@ -7695,7 +7151,7 @@ fn analyzeCall(...@@ -7695,7 +7151,7 @@ fn analyzeCall(
7695 };7151 };
76967152
7697 ref_func: {7153 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;
7699 if (!ip.isFuncBody(runtime_func_val.toIntern())) break :ref_func;7155 if (!ip.isFuncBody(runtime_func_val.toIntern())) break :ref_func;
7700 const orig_fn_index = ip.unwrapCoercedFunc(runtime_func_val.toIntern());7156 const orig_fn_index = ip.unwrapCoercedFunc(runtime_func_val.toIntern());
7701 try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = orig_fn_index }));7157 try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = orig_fn_index }));
...@@ -7714,7 +7170,7 @@ fn analyzeCall(...@@ -7714,7 +7170,7 @@ fn analyzeCall(
7714 };7170 };
77157171
7716 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + runtime_args.len);7172 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(.{
7718 .tag = call_tag,7174 .tag = call_tag,
7719 .data = .{ .pl_op = .{7175 .data = .{ .pl_op = .{
7720 .operand = runtime_func,7176 .operand = runtime_func,
...@@ -7725,8 +7181,10 @@ fn analyzeCall(...@@ -7725,8 +7181,10 @@ fn analyzeCall(
7725 });7181 });
7726 sema.appendRefsAssumeCapacity(runtime_args);7182 sema.appendRefsAssumeCapacity(runtime_args);
77277183
7184 const actual_ret_ty = sema.typeOf(call_ref);
7185
7728 if (ensure_result_used) {7186 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);
7730 }7188 }
77317189
7732 if (call_tag == .call_always_tail) {7190 if (call_tag == .call_always_tail) {
...@@ -7736,29 +7194,32 @@ fn analyzeCall(...@@ -7736,29 +7194,32 @@ fn analyzeCall(
7736 .pointer => func_or_ptr_ty.childType(zcu),7194 .pointer => func_or_ptr_ty.childType(zcu),
7737 else => unreachable,7195 else => unreachable,
7738 };7196 };
7739 return sema.handleTailCall(block, call_src, runtime_func_ty, maybe_opv);7197 return sema.handleTailCall(block, call_src, runtime_func_ty, call_ref);
7740 }7198 }
77417199
7742 if (ip.isNoReturn(resolved_ret_ty.toIntern())) {7200 switch (actual_ret_ty.classify(zcu)) {
7743 const want_check = c: {7201 .no_possible_value => {
7744 if (!block.wantSafety()) break :c false;7202 const want_check = c: {
7745 if (func_val != null) break :c false;7203 if (!block.wantSafety()) break :c false;
7746 break :c true;7204 if (func_val != null) break :c false;
7747 };7205 break :c true;
7748 if (want_check) {7206 };
7749 try sema.safetyPanic(block, call_src, .noreturn_returned);7207 if (want_check) {
7750 } else {7208 try sema.safetyPanic(block, call_src, .noreturn_returned);
7751 _ = try block.addNoOp(.unreach);7209 } else {
7752 }7210 _ = try block.addNoOp(.unreach);
7753 return .unreachable_value;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,
7754 }7222 }
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;
7762 }7223 }
77637224
7764 // This is an inline call. The function must be comptime-known. We will analyze its body directly using this `Sema`.7225 // 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(...@@ -7836,14 +7297,14 @@ fn analyzeCall(
7836 if (zcu.comp.config.incremental) break :m false;7297 if (zcu.comp.config.incremental) break :m false;
7837 if (!block.isComptime()) break :m false;7298 if (!block.isComptime()) break :m false;
7838 for (args) |a| {7299 for (args) |a| {
7839 const val = (try sema.resolveValue(a)).?;7300 const val = sema.resolveValue(a).?;
7840 if (val.canMutateComptimeVarState(zcu)) break :m false;7301 if (val.canMutateComptimeVarState(zcu)) break :m false;
7841 }7302 }
7842 break :m true;7303 break :m true;
7843 };7304 };
7844 const memoized_arg_values: []const InternPool.Index = if (want_memoize) arg_vals: {7305 const memoized_arg_values: []const InternPool.Index = if (want_memoize) arg_vals: {
7845 const vals = try sema.arena.alloc(InternPool.Index, args.len);7306 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();
7847 break :arg_vals vals;7308 break :arg_vals vals;
7848 } else undefined;7309 } else undefined;
7849 if (want_memoize) memoize: {7310 if (want_memoize) memoize: {
...@@ -7927,7 +7388,7 @@ fn analyzeCall(...@@ -7927,7 +7388,7 @@ fn analyzeCall(
7927 .parent = null,7388 .parent = null,
7928 .sema = sema,7389 .sema = sema,
7929 .namespace = fn_nav.analysis.?.namespace,7390 .namespace = fn_nav.analysis.?.namespace,
7930 .instructions = .{},7391 .instructions = .empty,
7931 .inlining = &inlining,7392 .inlining = &inlining,
7932 .is_typeof = block.is_typeof,7393 .is_typeof = block.is_typeof,
7933 .comptime_reason = if (block.isComptime()) .inlining_parent else null,7394 .comptime_reason = if (block.isComptime()) .inlining_parent else null,
...@@ -8000,7 +7461,11 @@ fn analyzeCall(...@@ -8000,7 +7461,11 @@ fn analyzeCall(
8000 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, &inlining.merges, need_debug_scope);7461 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, &inlining.merges, need_debug_scope);
8001 };7462 };
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: {
8004 const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());7469 const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());
8005 break :r Air.internedToRef(val_resolved);7470 break :r Air.internedToRef(val_resolved);
8006 } else r: {7471 } else r: {
...@@ -8012,7 +7477,7 @@ fn analyzeCall(...@@ -8012,7 +7477,7 @@ fn analyzeCall(
8012 };7477 };
80137478
8014 if (block.isComptime()) {7479 if (block.isComptime()) {
8015 const result_val = (try sema.resolveValue(maybe_opv)).?;7480 const result_val = sema.resolveValue(maybe_opv).?;
8016 if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) {7481 if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) {
8017 _ = try pt.intern(.{ .memoized_call = .{7482 _ = try pt.intern(.{ .memoized_call = .{
8018 .func = func_val.?.toIntern(),7483 .func = func_val.?.toIntern(),
...@@ -8081,15 +7546,12 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8081,15 +7546,12 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8081 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;7546 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
8082 const maybe_wrapped_indexable_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, bin.lhs) orelse return .generic_poison_type;7547 const maybe_wrapped_indexable_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, bin.lhs) orelse return .generic_poison_type;
8083 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu);7548 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu);
8084 try indexable_ty.resolveFields(pt);
8085 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction7549 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction
8086 if (indexable_ty.zigTypeTag(zcu) == .@"struct") {7550 const elem_ty = switch (indexable_ty.zigTypeTag(zcu)) {
8087 const elem_type = indexable_ty.fieldType(@intFromEnum(bin.rhs), zcu);7551 .@"struct" => indexable_ty.fieldType(@intFromEnum(bin.rhs), zcu),
8088 return Air.internedToRef(elem_type.toIntern());7552 else => indexable_ty.indexableElem(zcu),
8089 } else {7553 };
8090 const elem_type = indexable_ty.elemType2(zcu);7554 return .fromType(elem_ty);
8091 return Air.internedToRef(elem_type.toIntern());
8092 }
8093}7555}
80947556
8095fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7557fn 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...@@ -8190,7 +7652,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8190 const len = try sema.resolveInt(block, len_src, extra.len, .usize, .{ .simple = .array_length });7652 const len = try sema.resolveInt(block, len_src, extra.len, .usize, .{ .simple = .array_length });
8191 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);7653 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);
8192 try sema.validateArrayElemType(block, elem_type, elem_src);7654 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);
8194 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);7656 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
8195 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{ .simple = .array_sentinel });7657 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{ .simple = .array_sentinel });
8196 if (sentinel_val.canMutateComptimeVarState(zcu)) {7658 if (sentinel_val.canMutateComptimeVarState(zcu)) {
...@@ -8306,11 +7768,11 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8306,11 +7768,11 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8306 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;7768 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8307 const src = block.nodeOffset(extra.node);7769 const src = block.nodeOffset(extra.node);
8308 const operand_src = block.builtinCallArgSrc(extra.node, 0);7770 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);
8310 const operand = try sema.coerce(block, .anyerror, uncasted_operand, operand_src);7772 const operand = try sema.coerce(block, .anyerror, uncasted_operand, operand_src);
8311 const err_int_ty = try pt.errorIntType();7773 const err_int_ty = try pt.errorIntType();
83127774
8313 if (try sema.resolveValue(operand)) |val| {7775 if (sema.resolveValue(operand)) |val| {
8314 if (val.isUndef(zcu)) {7776 if (val.isUndef(zcu)) {
8315 return pt.undefRef(err_int_ty);7777 return pt.undefRef(err_int_ty);
8316 }7778 }
...@@ -8350,12 +7812,12 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8350,12 +7812,12 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8350 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;7812 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8351 const src = block.nodeOffset(extra.node);7813 const src = block.nodeOffset(extra.node);
8352 const operand_src = block.builtinCallArgSrc(extra.node, 0);7814 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);
8354 const err_int_ty = try pt.errorIntType();7816 const err_int_ty = try pt.errorIntType();
8355 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);7817 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
83567818
8357 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {7819 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));
8359 if (int > len: {7821 if (int > len: {
8360 const mutate = &ip.global_error_set.mutate;7822 const mutate = &ip.global_error_set.mutate;
8361 mutate.map.mutex.lockUncancelable(io);7823 mutate.map.mutex.lockUncancelable(io);
...@@ -8397,8 +7859,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8397,8 +7859,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8397 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });7859 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
8398 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });7860 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
8399 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });7861 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
8400 const lhs = try sema.resolveInst(extra.lhs);7862 const lhs = sema.resolveInst(extra.lhs);
8401 const rhs = try sema.resolveInst(extra.rhs);7863 const rhs = sema.resolveInst(extra.rhs);
8402 if (sema.typeOf(lhs).zigTypeTag(zcu) == .bool and sema.typeOf(rhs).zigTypeTag(zcu) == .bool) {7864 if (sema.typeOf(lhs).zigTypeTag(zcu) == .bool and sema.typeOf(rhs).zigTypeTag(zcu) == .bool) {
8403 const msg = msg: {7865 const msg = msg: {
8404 const msg = try sema.errMsg(lhs_src, "expected error set type, found 'bool'", .{});7866 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...@@ -8408,8 +7870,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8408 };7870 };
8409 return sema.failWithOwnedErrorMsg(block, msg);7871 return sema.failWithOwnedErrorMsg(block, msg);
8410 }7872 }
8411 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);7873 const lhs_ty = try sema.analyzeAsType(block, lhs_src, .type, lhs);
8412 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);7874 const rhs_ty = try sema.analyzeAsType(block, rhs_src, .type, rhs);
8413 if (lhs_ty.zigTypeTag(zcu) != .error_set)7875 if (lhs_ty.zigTypeTag(zcu) != .error_set)
8414 return sema.fail(block, lhs_src, "expected error set type, found '{f}'", .{lhs_ty.fmt(pt)});7876 return sema.fail(block, lhs_src, "expected error set type, found '{f}'", .{lhs_ty.fmt(pt)});
8415 if (rhs_ty.zigTypeTag(zcu) != .error_set)7877 if (rhs_ty.zigTypeTag(zcu) != .error_set)
...@@ -8420,21 +7882,21 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8420,21 +7882,21 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8420 return .anyerror_type;7882 return .anyerror_type;
8421 }7883 }
84227884
8423 if (ip.isInferredErrorSetType(lhs_ty.toIntern())) {7885 switch (ip.indexToKey(lhs_ty.toIntern())) {
8424 switch (try sema.resolveInferredErrorSet(block, src, lhs_ty.toIntern())) {7886 .inferred_error_set_type => |func_index| {
8425 // isAnyError might have changed from a false negative to a true7887 try sema.ensureFuncIesResolved(block, src, func_index);
8426 // positive after resolution.7888 if (ip.funcIesResolvedUnordered(func_index) == .anyerror_type) return .anyerror_type;
8427 .anyerror_type => return .anyerror_type,7889 },
8428 else => {},7890 .error_set_type => {},
8429 }7891 else => unreachable,
8430 }7892 }
8431 if (ip.isInferredErrorSetType(rhs_ty.toIntern())) {7893 switch (ip.indexToKey(rhs_ty.toIntern())) {
8432 switch (try sema.resolveInferredErrorSet(block, src, rhs_ty.toIntern())) {7894 .inferred_error_set_type => |func_index| {
8433 // isAnyError might have changed from a false negative to a true7895 try sema.ensureFuncIesResolved(block, src, func_index);
8434 // positive after resolution.7896 if (ip.funcIesResolvedUnordered(func_index) == .anyerror_type) return .anyerror_type;
8435 .anyerror_type => return .anyerror_type,7897 },
8436 else => {},7898 .error_set_type => {},
8437 }7899 else => unreachable,
8438 }7900 }
84397901
8440 const err_set_ty = try sema.errorSetMerge(lhs_ty, rhs_ty);7902 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...@@ -8533,23 +7995,22 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8533 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;7995 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8534 const src = block.nodeOffset(inst_data.src_node);7996 const src = block.nodeOffset(inst_data.src_node);
8535 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);7997 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);
8537 const operand_ty = sema.typeOf(operand);7999 const operand_ty = sema.typeOf(operand);
85388000
8539 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(zcu)) {8001 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(zcu)) {
8540 .@"enum" => operand,8002 .@"enum" => operand,
8541 .@"union" => blk: {8003 .@"union" => blk: {
8542 try operand_ty.resolveFields(pt);8004 if (operand_ty.unionTagType(zcu) == null) {
8543 const tag_ty = operand_ty.unionTagType(zcu) orelse {
8544 return sema.fail(8005 return sema.fail(
8545 block,8006 block,
8546 operand_src,8007 operand_src,
8547 "untagged union '{f}' cannot be converted to integer",8008 "untagged union '{f}' cannot be converted to integer",
8548 .{operand_ty.fmt(pt)},8009 .{operand_ty.fmt(pt)},
8549 );8010 );
8550 };8011 }
85518012
8552 break :blk try sema.unionToTag(block, tag_ty, operand, operand_src);8013 break :blk try sema.unionToTag(block, operand);
8553 },8014 },
8554 else => {8015 else => {
8555 return sema.fail(block, operand_src, "expected enum or tagged union, found '{f}'", .{8016 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...@@ -8568,17 +8029,9 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8568 });8029 });
8569 }8030 }
85708031
8571 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {8032 if (sema.resolveValue(enum_tag)) |enum_tag_val| {
8572 return Air.internedToRef((try pt.getCoerced(opv, int_tag_ty)).toIntern());8033 if (enum_tag_val.isUndef(zcu)) return pt.undefRef(int_tag_ty);
8573 }8034 return .fromValue(enum_tag_val.intFromEnum(zcu));
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());
8582 }8035 }
85838036
8584 try sema.requireRuntimeBlock(block, src, operand_src);8037 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -8593,18 +8046,19 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8593,18 +8046,19 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8593 const src = block.nodeOffset(inst_data.src_node);8046 const src = block.nodeOffset(inst_data.src_node);
8594 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);8047 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
8595 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt");8048 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);
8597 const operand_ty = sema.typeOf(operand);8050 const operand_ty = sema.typeOf(operand);
85988051
8599 if (dest_ty.zigTypeTag(zcu) != .@"enum") {8052 if (dest_ty.zigTypeTag(zcu) != .@"enum") {
8600 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});8053 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});
8601 }8054 }
8055 try sema.ensureLayoutResolved(dest_ty, src, .init);
8602 _ = try sema.checkIntType(block, operand_src, operand_ty);8056 _ = try sema.checkIntType(block, operand_src, operand_ty);
86038057
8604 if (try sema.resolveValue(operand)) |int_val| {8058 if (sema.resolveValue(operand)) |int_val| {
8605 if (dest_ty.isNonexhaustiveEnum(zcu)) {8059 if (dest_ty.isNonexhaustiveEnum(zcu)) {
8606 const int_tag_ty = dest_ty.intTagType(zcu);8060 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)) {
8608 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());8062 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
8609 }8063 }
8610 return sema.fail(block, src, "int value '{f}' out of range of non-exhaustive enum '{f}'", .{8064 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...@@ -8626,19 +8080,15 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8626 return sema.failWithNeededComptime(block, operand_src, .{ .simple = .casted_to_comptime_enum });8080 return sema.failWithNeededComptime(block, operand_src, .{ .simple = .casted_to_comptime_enum });
8627 }8081 }
86288082
8629 if (try sema.typeHasOnePossibleValue(dest_ty)) |opv| {8083 if (try dest_ty.onePossibleValue(pt)) |opv| {
8630 if (block.wantSafety()) {8084 if (block.wantSafety()) {
8631 // The operand is runtime-known but the result is comptime-known. In8085 // The operand is runtime-known but the result is comptime-known. In
8632 // this case we still need a safety check.8086 // this case we still need a safety check.
8633 const expect_int_val = switch (zcu.intern_pool.indexToKey(opv.toIntern())) {8087 const expect_int = try pt.getCoerced(opv.intFromEnum(zcu), operand_ty);
8634 .enum_tag => |enum_tag| enum_tag.int,8088 const ok = try block.addBinOp(.cmp_eq, operand, .fromValue(expect_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()));
8639 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);8089 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
8640 }8090 }
8641 return Air.internedToRef(opv.toIntern());8091 return .fromValue(opv);
8642 }8092 }
86438093
8644 try sema.requireRuntimeBlock(block, src, operand_src);8094 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -8660,12 +8110,17 @@ fn zirOptionalPayloadPtr(...@@ -8660,12 +8110,17 @@ fn zirOptionalPayloadPtr(
8660 defer tracy.end();8110 defer tracy.end();
86618111
8662 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8112 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);
8664 const src = block.nodeOffset(inst_data.src_node);8114 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
8666 return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false);8120 return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false);
8667}8121}
86688122
8123/// Asserts that the layout of the pointer child type is already resolved.
8669fn analyzeOptionalPayloadPtr(8124fn analyzeOptionalPayloadPtr(
8670 sema: *Sema,8125 sema: *Sema,
8671 block: *Block,8126 block: *Block,
...@@ -8680,12 +8135,13 @@ fn analyzeOptionalPayloadPtr(...@@ -8680,12 +8135,13 @@ fn analyzeOptionalPayloadPtr(
8680 assert(optional_ptr_ty.zigTypeTag(zcu) == .pointer);8135 assert(optional_ptr_ty.zigTypeTag(zcu) == .pointer);
86818136
8682 const opt_type = optional_ptr_ty.childType(zcu);8137 const opt_type = optional_ptr_ty.childType(zcu);
8138 opt_type.assertHasLayout(zcu);
8683 if (opt_type.zigTypeTag(zcu) != .optional) {8139 if (opt_type.zigTypeTag(zcu) != .optional) {
8684 return sema.failWithExpectedOptionalType(block, src, opt_type);8140 return sema.failWithExpectedOptionalType(block, src, opt_type);
8685 }8141 }
86868142
8687 const child_type = opt_type.optionalChild(zcu);8143 const child_type = opt_type.optionalChild(zcu);
8688 const child_pointer = try pt.ptrTypeSema(.{8144 const child_pointer = try pt.ptrType(.{
8689 .child = child_type.toIntern(),8145 .child = child_type.toIntern(),
8690 .flags = .{8146 .flags = .{
8691 .is_const = optional_ptr_ty.isConstPtr(zcu),8147 .is_const = optional_ptr_ty.isConstPtr(zcu),
...@@ -8698,7 +8154,7 @@ fn analyzeOptionalPayloadPtr(...@@ -8698,7 +8154,7 @@ fn analyzeOptionalPayloadPtr(
8698 if (sema.isComptimeMutablePtr(ptr_val)) {8154 if (sema.isComptimeMutablePtr(ptr_val)) {
8699 // Set the optional to non-null at comptime.8155 // Set the optional to non-null at comptime.
8700 // If the payload is OPV, we must use that value instead of undef.8156 // 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);
8702 const opt_val = try pt.intern(.{ .opt = .{8158 const opt_val = try pt.intern(.{ .opt = .{
8703 .ty = opt_type.toIntern(),8159 .ty = opt_type.toIntern(),
8704 .val = payload_val.toIntern(),8160 .val = payload_val.toIntern(),
...@@ -8748,33 +8204,27 @@ fn zirOptionalPayload(...@@ -8748,33 +8204,27 @@ fn zirOptionalPayload(
8748 const zcu = pt.zcu;8204 const zcu = pt.zcu;
8749 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8205 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8750 const src = block.nodeOffset(inst_data.src_node);8206 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);
8752 const operand_ty = sema.typeOf(operand);8208 const operand_ty = sema.typeOf(operand);
8753 const result_ty = switch (operand_ty.zigTypeTag(zcu)) {8209 const result_ty = switch (operand_ty.zigTypeTag(zcu)) {
8754 .optional => operand_ty.optionalChild(zcu),8210 .optional => operand_ty.optionalChild(zcu),
8755 .pointer => t: {8211 // TODO: https://github.com/ziglang/zig/issues/6597 will eliminate this branch so that we only need to handle optionals.
8756 if (operand_ty.ptrSize(zcu) != .c) {8212 .pointer => switch (operand_ty.ptrSize(zcu)) {
8757 return sema.failWithExpectedOptionalType(block, src, operand_ty);8213 .c => operand_ty, // if `ptr` is a `[*c]T`, then `ptr.?` is also a `[*c]T`
8758 }8214 .one, .many, .slice => return sema.failWithExpectedOptionalType(block, src, operand_ty),
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 });
8772 },8215 },
8773 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),8216 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),
8774 };8217 };
87758218
8776 if (try sema.resolveDefinedValue(block, src, operand)) |val| {8219 ct: {
8777 if (val.optionalValue(zcu)) |payload| return Air.internedToRef(payload.toIntern());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`.
8778 if (block.isComptime()) return sema.fail(block, src, "unable to unwrap null", .{});8228 if (block.isComptime()) return sema.fail(block, src, "unable to unwrap null", .{});
8779 if (safety_check and block.wantSafety()) {8229 if (safety_check and block.wantSafety()) {
8780 try sema.safetyPanic(block, src, .unwrap_null);8230 try sema.safetyPanic(block, src, .unwrap_null);
...@@ -8784,11 +8234,14 @@ fn zirOptionalPayload(...@@ -8784,11 +8234,14 @@ fn zirOptionalPayload(
8784 return .unreachable_value;8234 return .unreachable_value;
8785 }8235 }
87868236
8787 try sema.requireRuntimeBlock(block, src, null);
8788 if (safety_check and block.wantSafety()) {8237 if (safety_check and block.wantSafety()) {
8789 const is_non_null = try block.addUnOp(.is_non_null, operand);8238 const is_non_null = try block.addUnOp(.is_non_null, operand);
8790 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);8239 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
8791 }8240 }
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
8792 return block.addTyOp(.optional_payload, result_ty, operand);8245 return block.addTyOp(.optional_payload, result_ty, operand);
8793}8246}
87948247
...@@ -8805,7 +8258,7 @@ fn zirErrUnionPayload(...@@ -8805,7 +8258,7 @@ fn zirErrUnionPayload(
8805 const zcu = pt.zcu;8258 const zcu = pt.zcu;
8806 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8259 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8807 const src = block.nodeOffset(inst_data.src_node);8260 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);
8809 const operand_src = src;8262 const operand_src = src;
8810 const err_union_ty = sema.typeOf(operand);8263 const err_union_ty = sema.typeOf(operand);
8811 if (err_union_ty.zigTypeTag(zcu) != .error_union) {8264 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
...@@ -8844,8 +8297,8 @@ fn analyzeErrUnionPayload(...@@ -8844,8 +8297,8 @@ fn analyzeErrUnionPayload(
8844 try sema.addSafetyCheckUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);8297 try sema.addSafetyCheckUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);
8845 }8298 }
88468299
8847 if (try sema.typeHasOnePossibleValue(payload_ty)) |payload_only_value| {8300 if (try payload_ty.onePossibleValue(pt)) |payload_opv| {
8848 return Air.internedToRef(payload_only_value.toIntern());8301 return .fromValue(payload_opv);
8849 }8302 }
88508303
8851 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);8304 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);
...@@ -8861,12 +8314,17 @@ fn zirErrUnionPayloadPtr(...@@ -8861,12 +8314,17 @@ fn zirErrUnionPayloadPtr(
8861 defer tracy.end();8314 defer tracy.end();
88628315
8863 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8316 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);
8865 const src = block.nodeOffset(inst_data.src_node);8318 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
8867 return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);8324 return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
8868}8325}
88698326
8327/// Asserts that the layout of the pointer child type is already resolved.
8870fn analyzeErrUnionPayloadPtr(8328fn analyzeErrUnionPayloadPtr(
8871 sema: *Sema,8329 sema: *Sema,
8872 block: *Block,8330 block: *Block,
...@@ -8887,8 +8345,9 @@ fn analyzeErrUnionPayloadPtr(...@@ -8887,8 +8345,9 @@ fn analyzeErrUnionPayloadPtr(
8887 }8345 }
88888346
8889 const err_union_ty = operand_ty.childType(zcu);8347 const err_union_ty = operand_ty.childType(zcu);
8348 err_union_ty.assertHasLayout(zcu);
8890 const payload_ty = err_union_ty.errorUnionPayload(zcu);8349 const payload_ty = err_union_ty.errorUnionPayload(zcu);
8891 const operand_pointer_ty = try pt.ptrTypeSema(.{8350 const operand_pointer_ty = try pt.ptrType(.{
8892 .child = payload_ty.toIntern(),8351 .child = payload_ty.toIntern(),
8893 .flags = .{8352 .flags = .{
8894 .is_const = operand_ty.isConstPtr(zcu),8353 .is_const = operand_ty.isConstPtr(zcu),
...@@ -8901,7 +8360,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -8901,7 +8360,7 @@ fn analyzeErrUnionPayloadPtr(
8901 if (sema.isComptimeMutablePtr(ptr_val)) {8360 if (sema.isComptimeMutablePtr(ptr_val)) {
8902 // Set the error union to non-error at comptime.8361 // Set the error union to non-error at comptime.
8903 // If the payload is OPV, we must use that value instead of undef.8362 // 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);
8905 const eu_val = try pt.intern(.{ .error_union = .{8364 const eu_val = try pt.intern(.{ .error_union = .{
8906 .ty = err_union_ty.toIntern(),8365 .ty = err_union_ty.toIntern(),
8907 .val = .{ .payload = payload_val.toIntern() },8366 .val = .{ .payload = payload_val.toIntern() },
...@@ -8948,7 +8407,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -8948,7 +8407,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
89488407
8949 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8408 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8950 const src = block.nodeOffset(inst_data.src_node);8409 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);
8952 return sema.analyzeErrUnionCode(block, src, operand);8411 return sema.analyzeErrUnionCode(block, src, operand);
8953}8412}
89548413
...@@ -8984,7 +8443,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -8984,7 +8443,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
89848443
8985 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8444 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8986 const src = block.nodeOffset(inst_data.src_node);8445 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);
8988 return sema.analyzeErrUnionCodePtr(block, src, operand);8447 return sema.analyzeErrUnionCodePtr(block, src, operand);
8989}8448}
89908449
...@@ -9302,11 +8761,12 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:...@@ -9302,11 +8761,12 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:
9302 }8761 }
9303}8762}
93048763
9305fn checkParamTypeCommon(8764fn checkParamType(
9306 sema: *Sema,8765 sema: *Sema,
9307 block: *Block,8766 block: *Block,
9308 param_idx: u32,8767 param_idx: u32,
9309 param_ty: Type,8768 param_ty: Type,
8769 param_is_comptime: bool,
9310 param_is_noalias: bool,8770 param_is_noalias: bool,
9311 param_src: LazySrcLoc,8771 param_src: LazySrcLoc,
9312 cc: std.builtin.CallingConvention,8772 cc: std.builtin.CallingConvention,
...@@ -9321,29 +8781,22 @@ fn checkParamTypeCommon(...@@ -9321,29 +8781,22 @@ fn checkParamTypeCommon(
9321 opaque_str, param_ty.fmt(pt),8781 opaque_str, param_ty.fmt(pt),
9322 });8782 });
9323 }8783 }
9324 if (!param_ty.isGenericPoison() and8784 if (!target_util.fnCallConvAllowsZigTypes(cc)) {
9325 !target_util.fnCallConvAllowsZigTypes(cc) and8785 if (param_is_comptime) {
9326 !try sema.validateExternType(param_ty, .param_ty))8786 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{t}'", .{cc});
9327 {8787 }
9328 return sema.failWithOwnedErrorMsg(block, msg: {8788 if (param_ty.isGenericPoison()) {
9329 const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{8789 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{t}'", .{cc});
9330 param_ty.fmt(pt), @tagName(cc),8790 }
9331 });8791 // The `validateExtern` check happens later, in `validateResolvedFuncType`.
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 });
9339 }8792 }
9340 switch (cc) {8793 switch (cc) {
9341 .x86_64_interrupt, .x86_interrupt => {8794 .x86_64_interrupt, .x86_interrupt => {
9342 const err_code_size = target.ptrBitWidth();8795 const err_code_size = target.ptrBitWidth();
9343 switch (param_idx) {8796 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)}),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}),
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 }),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 }),
9346 else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), param_idx + 1 }),8799 else => return sema.fail(block, param_src, "'{t}' calling convention supports up to 2 parameters, found {d}", .{ cc, param_idx + 1 }),
9347 }8800 }
9348 },8801 },
9349 .arc_interrupt,8802 .arc_interrupt,
...@@ -9359,7 +8812,7 @@ fn checkParamTypeCommon(...@@ -9359,7 +8812,7 @@ fn checkParamTypeCommon(
9359 .m68k_interrupt,8812 .m68k_interrupt,
9360 .msp430_interrupt,8813 .msp430_interrupt,
9361 .avr_signal,8814 .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}),
9363 else => {},8816 else => {},
9364 }8817 }
9365 if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) {8818 if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) {
...@@ -9367,7 +8820,7 @@ fn checkParamTypeCommon(...@@ -9367,7 +8820,7 @@ fn checkParamTypeCommon(
9367 }8820 }
9368}8821}
93698822
9370fn checkReturnTypeAndCallConvCommon(8823fn checkReturnTypeAndCallConv(
9371 sema: *Sema,8824 sema: *Sema,
9372 block: *Block,8825 block: *Block,
9373 bare_ret_ty: Type,8826 bare_ret_ty: Type,
...@@ -9381,7 +8834,6 @@ fn checkReturnTypeAndCallConvCommon(...@@ -9381,7 +8834,6 @@ fn checkReturnTypeAndCallConvCommon(
9381) CompileError!void {8834) CompileError!void {
9382 const pt = sema.pt;8835 const pt = sema.pt;
9383 const zcu = pt.zcu;8836 const zcu = pt.zcu;
9384 const gpa = zcu.gpa;
9385 if (opt_varargs_src) |varargs_src| {8837 if (opt_varargs_src) |varargs_src| {
9386 try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv");8838 try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv");
9387 }8839 }
...@@ -9395,21 +8847,14 @@ fn checkReturnTypeAndCallConvCommon(...@@ -9395,21 +8847,14 @@ fn checkReturnTypeAndCallConvCommon(
9395 opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt),8847 opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt),
9396 });8848 });
9397 }8849 }
9398 if (!bare_ret_ty.isGenericPoison() and8850 if (!target_util.fnCallConvAllowsZigTypes(@"callconv")) {
9399 !target_util.fnCallConvAllowsZigTypes(@"callconv") and8851 if (inferred_error_set) {
9400 (inferred_error_set or !try sema.validateExternType(bare_ret_ty, .ret_ty)))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" });
9401 {8853 }
9402 return sema.failWithOwnedErrorMsg(block, msg: {8854 if (bare_ret_ty.isGenericPoison()) {
9403 const msg = try sema.errMsg(ret_ty_src, "return type '{s}{f}' not allowed in function with calling convention '{s}'", .{8855 return sema.fail(block, ret_ty_src, "generic return type not allowed in function with calling convention '{t}'", .{@"callconv"});
9404 ies_ret_ty_prefix, bare_ret_ty.fmt(pt), @tagName(@"callconv"),8856 }
9405 });8857 // The `validateExtern` check happens later, in `validateResolvedFuncType`.
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 });
9413 }8858 }
9414 validate_incoming_stack_align: {8859 validate_incoming_stack_align: {
9415 const a: u64 = switch (@"callconv") {8860 const a: u64 = switch (@"callconv") {
...@@ -9444,7 +8889,7 @@ fn checkReturnTypeAndCallConvCommon(...@@ -9444,7 +8889,7 @@ fn checkReturnTypeAndCallConvCommon(
9444 else => false,8889 else => false,
9445 };8890 };
9446 if (!ret_ok) {8891 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"});
9448 }8893 }
9449 },8894 },
9450 .@"inline" => if (is_noinline) {8895 .@"inline" => if (is_noinline) {
...@@ -9465,18 +8910,76 @@ fn checkReturnTypeAndCallConvCommon(...@@ -9465,18 +8910,76 @@ fn checkReturnTypeAndCallConvCommon(
9465 }8910 }
9466 }8911 }
9467 };8912 };
9468 return sema.fail(block, callconv_src, "calling convention '{s}' only available on architectures {f}", .{8913 return sema.fail(block, callconv_src, "calling convention '{t}' only available on architectures {f}", .{
9469 @tagName(@"callconv"),8914 @"callconv", ArchListFormatter{ .archs = allowed_archs },
9470 ArchListFormatter{ .archs = allowed_archs },
9471 });8915 });
9472 },8916 },
9473 .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{s}' not supported by compiler backend '{s}'", .{8917 .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{t}' not supported by compiler backend '{t}'", .{
9474 @tagName(@"callconv"),8918 @"callconv", bad_backend,
9475 @tagName(bad_backend),
9476 }),8919 }),
9477 }8920 }
9478}8921}
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
9480fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {8983fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
9481 return switch (cc) {8984 return switch (cc) {
9482 .naked,8985 .naked,
...@@ -9569,12 +9072,9 @@ fn funcCommon(...@@ -9569,12 +9072,9 @@ fn funcCommon(
9569 const io = comp.io;9072 const io = comp.io;
9570 const ip = &zcu.intern_pool;9073 const ip = &zcu.intern_pool;
95719074
9075 const src = block.nodeOffset(src_node_offset);
9572 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });9076 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
9573 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });9077 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
9579 var comptime_bits: u32 = 0;9079 var comptime_bits: u32 = 0;
9580 for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| {9080 for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| {
...@@ -9587,49 +9087,21 @@ fn funcCommon(...@@ -9587,49 +9087,21 @@ fn funcCommon(
9587 .fn_proto_node_offset = src_node_offset,9087 .fn_proto_node_offset = src_node_offset,
9588 .param_index = @intCast(i),9088 .param_index = @intCast(i),
9589 } });9089 } });
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 }
9595 if (param_is_comptime) {9090 if (param_is_comptime) {
9596 comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error9091 comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error
9597 }9092 }
9598 if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc)) {9093 try sema.checkParamType(
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(
9605 block,9094 block,
9606 @intCast(i),9095 @intCast(i),
9607 param_ty,9096 param_ty,
9097 param_is_comptime,
9608 is_noalias,9098 is_noalias,
9609 param_src,9099 param_src,
9610 cc,9100 cc,
9611 );9101 );
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", .{});
9630 }9102 }
96319103
9632 try sema.checkReturnTypeAndCallConvCommon(9104 try sema.checkReturnTypeAndCallConv(
9633 block,9105 block,
9634 bare_return_type,9106 bare_return_type,
9635 ret_ty_src,9107 ret_ty_src,
...@@ -9643,48 +9115,28 @@ fn funcCommon(...@@ -9643,48 +9115,28 @@ fn funcCommon(
9643 is_noinline,9115 is_noinline,
9644 );9116 );
96459117
9646 // If the return type is comptime-only but not dependent on parameters then9118 const param_types = block.params.items(.ty);
9647 // all parameter types also need to be comptime.9119
9648 if (has_body and ret_ty_requires_comptime and !block.isComptime()) comptime_check: {9120 if (has_body) {
9649 for (block.params.items(.is_comptime)) |is_comptime| {9121 for (param_types, 0..) |param_ty_ip, param_index| {
9650 if (!is_comptime) break;9122 const param_ty: Type = .fromInterned(param_ty_ip);
9651 } else break :comptime_check;9123 const param_src = block.src(.{ .fn_proto_param = .{
9652 const ies_ret_ty_prefix: []const u8 = if (inferred_error_set) "!" else "";9124 .fn_proto_node_offset = src_node_offset,
9653 const msg = try sema.errMsg(9125 .param_index = @intCast(param_index),
9654 ret_ty_src,9126 } });
9655 "function with comptime-only return type '{s}{f}' requires all parameters to be comptime",9127 try sema.ensureLayoutResolved(param_ty, param_src, .parameter);
9656 .{ ies_ret_ty_prefix, bare_return_type.fmt(pt) },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),
9657 );9137 );
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);
9684 }9138 }
96859139
9686 const param_types = block.params.items(.ty);
9687
9688 if (inferred_error_set) {9140 if (inferred_error_set) {
9689 assert(has_body);9141 assert(has_body);
9690 return .fromIntern(try ip.getFuncDeclIes(gpa, io, pt.tid, .{9142 return .fromIntern(try ip.getFuncDeclIes(gpa, io, pt.tid, .{
...@@ -9696,7 +9148,6 @@ fn funcCommon(...@@ -9696,7 +9148,6 @@ fn funcCommon(
9696 .bare_return_type = bare_return_type.toIntern(),9148 .bare_return_type = bare_return_type.toIntern(),
9697 .cc = cc,9149 .cc = cc,
9698 .is_var_args = var_args,9150 .is_var_args = var_args,
9699 .is_generic = is_generic,
9700 .is_noinline = is_noinline,9151 .is_noinline = is_noinline,
97019152
9702 .zir_body_inst = try block.trackZir(func_inst),9153 .zir_body_inst = try block.trackZir(func_inst),
...@@ -9714,7 +9165,6 @@ fn funcCommon(...@@ -9714,7 +9165,6 @@ fn funcCommon(
9714 .return_type = bare_return_type.toIntern(),9165 .return_type = bare_return_type.toIntern(),
9715 .cc = cc,9166 .cc = cc,
9716 .is_var_args = var_args,9167 .is_var_args = var_args,
9717 .is_generic = is_generic,
9718 .is_noinline = is_noinline,9168 .is_noinline = is_noinline,
9719 });9169 });
97209170
...@@ -9756,7 +9206,7 @@ fn zirParam(...@@ -9756,7 +9206,7 @@ fn zirParam(
9756 }9206 }
97579207
9758 const param_ty_inst = try sema.resolveInlineBody(block, body, inst);9208 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);
9760 };9210 };
97619211
9762 try block.params.append(sema.arena, .{9212 try block.params.append(sema.arena, .{
...@@ -9812,7 +9262,7 @@ fn analyzeAs(...@@ -9812,7 +9262,7 @@ fn analyzeAs(
9812) CompileError!Air.Inst.Ref {9262) CompileError!Air.Inst.Ref {
9813 const pt = sema.pt;9263 const pt = sema.pt;
9814 const zcu = pt.zcu;9264 const zcu = pt.zcu;
9815 const operand = try sema.resolveInst(zir_operand);9265 const operand = sema.resolveInst(zir_operand);
9816 const dest_ty = try sema.resolveTypeOrPoison(block, src, zir_dest_type) orelse return operand;9266 const dest_ty = try sema.resolveTypeOrPoison(block, src, zir_dest_type) orelse return operand;
9817 switch (dest_ty.zigTypeTag(zcu)) {9267 switch (dest_ty.zigTypeTag(zcu)) {
9818 .@"opaque" => return sema.fail(block, src, "cannot cast to opaque type '{f}'", .{dest_ty.fmt(pt)}),9268 .@"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!...@@ -9838,32 +9288,23 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
9838 const zcu = pt.zcu;9288 const zcu = pt.zcu;
9839 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;9289 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
9840 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);9290 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);
9842 const operand_ty = sema.typeOf(operand);9292 const operand_ty = sema.typeOf(operand);
9843 const ptr_ty = operand_ty.scalarType(zcu);9293 const ptr_ty = operand_ty.scalarType(zcu);
9844 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;9294 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
9845 if (!ptr_ty.isPtrAtRuntime(zcu)) {9295 if (!ptr_ty.isPtrAtRuntime(zcu)) {
9846 return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)});9296 return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)});
9847 }9297 }
9848 const pointee_ty = ptr_ty.childType(zcu);9298
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 }
9858 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;9299 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;
9859 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .usize_type, .len = len }) else .usize;9300 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: {
9862 if (!is_vector) {9303 if (!is_vector) {
9863 if (operand_val.isUndef(zcu)) {9304 if (operand_val.isUndef(zcu)) {
9864 return .undef_usize;9305 return .undef_usize;
9865 }9306 }
9866 const addr = try operand_val.getUnsignedIntSema(pt) orelse {9307 const addr = operand_val.getUnsignedInt(zcu) orelse {
9867 // Wasn't an integer pointer. This is a runtime operation.9308 // Wasn't an integer pointer. This is a runtime operation.
9868 break :ct;9309 break :ct;
9869 };9310 };
...@@ -9879,7 +9320,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -9879,7 +9320,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
9879 new_elem.* = .undef_usize;9320 new_elem.* = .undef_usize;
9880 continue;9321 continue;
9881 }9322 }
9882 const addr = try ptr_val.getUnsignedIntSema(pt) orelse {9323 const addr = ptr_val.getUnsignedInt(zcu) orelse {
9883 // A vector element wasn't an integer pointer. This is a runtime operation.9324 // A vector element wasn't an integer pointer. This is a runtime operation.
9884 break :ct;9325 break :ct;
9885 };9326 };
...@@ -9917,7 +9358,7 @@ fn zirFieldPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -9917,7 +9358,7 @@ fn zirFieldPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
9917 sema.code.nullTerminatedString(extra.field_name_start),9358 sema.code.nullTerminatedString(extra.field_name_start),
9918 .no_embedded_nulls,9359 .no_embedded_nulls,
9919 );9360 );
9920 const object_ptr = try sema.resolveInst(extra.lhs);9361 const object_ptr = sema.resolveInst(extra.lhs);
9921 return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src);9362 return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src);
9922}9363}
99239364
...@@ -9942,7 +9383,7 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9942,7 +9383,7 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9942 sema.code.nullTerminatedString(extra.field_name_start),9383 sema.code.nullTerminatedString(extra.field_name_start),
9943 .no_embedded_nulls,9384 .no_embedded_nulls,
9944 );9385 );
9945 const object_ptr = try sema.resolveInst(extra.lhs);9386 const object_ptr = sema.resolveInst(extra.lhs);
9946 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);9387 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
9947}9388}
99489389
...@@ -9967,7 +9408,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi...@@ -9967,7 +9408,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
9967 sema.code.nullTerminatedString(extra.field_name_start),9408 sema.code.nullTerminatedString(extra.field_name_start),
9968 .no_embedded_nulls,9409 .no_embedded_nulls,
9969 );9410 );
9970 const object_ptr = try sema.resolveInst(extra.lhs);9411 const object_ptr = sema.resolveInst(extra.lhs);
9971 const struct_ty = sema.typeOf(object_ptr).childType(zcu);9412 const struct_ty = sema.typeOf(object_ptr).childType(zcu);
9972 switch (struct_ty.zigTypeTag(zcu)) {9413 switch (struct_ty.zigTypeTag(zcu)) {
9973 .@"struct", .@"union" => {9414 .@"struct", .@"union" => {
...@@ -9987,7 +9428,7 @@ fn zirFieldPtrNamedLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -9987,7 +9428,7 @@ fn zirFieldPtrNamedLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
9987 const src = block.nodeOffset(inst_data.src_node);9428 const src = block.nodeOffset(inst_data.src_node);
9988 const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);9429 const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
9989 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;9430 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);
9991 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });9432 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });
9992 return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src);9433 return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src);
9993}9434}
...@@ -10000,7 +9441,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -10000,7 +9441,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
10000 const src = block.nodeOffset(inst_data.src_node);9441 const src = block.nodeOffset(inst_data.src_node);
10001 const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);9442 const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
10002 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;9443 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);
10004 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });9445 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });
10005 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);9446 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
10006}9447}
...@@ -10015,7 +9456,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10015,7 +9456,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10015 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9456 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
100169457
10017 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast");9458 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
10020 return sema.intCast(block, block.nodeOffset(inst_data.src_node), dest_ty, src, operand, operand_src);9461 return sema.intCast(block, block.nodeOffset(inst_data.src_node), dest_ty, src, operand, operand_src);
10021}9462}
...@@ -10044,7 +9485,7 @@ fn intCast(...@@ -10044,7 +9485,7 @@ fn intCast(
10044 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, dest_ty_src, operand_src);9485 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, dest_ty_src, operand_src);
10045 const is_vector = dest_ty.zigTypeTag(zcu) == .vector;9486 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| {
10048 // requirement: intCast(u0, input) iff input == 09489 // requirement: intCast(u0, input) iff input == 0
10049 if (block.wantSafety()) {9490 if (block.wantSafety()) {
10050 try sema.requireRuntimeBlock(block, src, operand_src);9491 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -10090,7 +9531,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10090,7 +9531,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10090 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9531 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
100919532
10092 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast");9533 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);
10094 const operand_ty = sema.typeOf(operand);9535 const operand_ty = sema.typeOf(operand);
10095 switch (dest_ty.zigTypeTag(zcu)) {9536 switch (dest_ty.zigTypeTag(zcu)) {
10096 .@"anyframe",9537 .@"anyframe",
...@@ -10258,7 +9699,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10258,7 +9699,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10258 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast");9699 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast");
10259 const dest_scalar_ty = dest_ty.scalarType(zcu);9700 const dest_scalar_ty = dest_ty.scalarType(zcu);
102609701
10261 const operand = try sema.resolveInst(extra.rhs);9702 const operand = sema.resolveInst(extra.rhs);
10262 const operand_ty = sema.typeOf(operand);9703 const operand_ty = sema.typeOf(operand);
10263 const operand_scalar_ty = operand_ty.scalarType(zcu);9704 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...@@ -10287,7 +9728,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10287 ),9728 ),
10288 }9729 }
102899730
10290 if (try sema.resolveValue(operand)) |operand_val| {9731 if (sema.resolveValue(operand)) |operand_val| {
10291 if (!is_vector) {9732 if (!is_vector) {
10292 return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern());9733 return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern());
10293 }9734 }
...@@ -10319,8 +9760,8 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10319,8 +9760,8 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10319 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9760 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10320 const src = block.nodeOffset(inst_data.src_node);9761 const src = block.nodeOffset(inst_data.src_node);
10321 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9762 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10322 const array = try sema.resolveInst(extra.lhs);9763 const array = sema.resolveInst(extra.lhs);
10323 const elem_index = try sema.resolveInst(extra.rhs);9764 const elem_index = sema.resolveInst(extra.rhs);
10324 return sema.elemVal(block, src, array, elem_index, src, false);9765 return sema.elemVal(block, src, array, elem_index, src, false);
10325}9766}
103269767
...@@ -10332,8 +9773,8 @@ fn zirElemPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10332,8 +9773,8 @@ fn zirElemPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10332 const src = block.nodeOffset(inst_data.src_node);9773 const src = block.nodeOffset(inst_data.src_node);
10333 const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });9774 const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
10334 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9775 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10335 const array_ptr = try sema.resolveInst(extra.lhs);9776 const array_ptr = sema.resolveInst(extra.lhs);
10336 const uncoerced_elem_index = try sema.resolveInst(extra.rhs);9777 const uncoerced_elem_index = sema.resolveInst(extra.rhs);
10337 if (try sema.resolveDefinedValue(block, src, array_ptr)) |array_ptr_val| {9778 if (try sema.resolveDefinedValue(block, src, array_ptr)) |array_ptr_val| {
10338 const array_ptr_ty = sema.typeOf(array_ptr);9779 const array_ptr_ty = sema.typeOf(array_ptr);
10339 if (try sema.pointerDeref(block, src, array_ptr_val, array_ptr_ty)) |array_val| {9780 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!...@@ -10351,7 +9792,7 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10351 defer tracy.end();9792 defer tracy.end();
103529793
10353 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;9794 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);
10355 const elem_index = try sema.pt.intRef(.usize, inst_data.idx);9796 const elem_index = try sema.pt.intRef(.usize, inst_data.idx);
10356 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);9797 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);
10357}9798}
...@@ -10365,8 +9806,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10365,8 +9806,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10365 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9806 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10366 const src = block.nodeOffset(inst_data.src_node);9807 const src = block.nodeOffset(inst_data.src_node);
10367 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9808 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10368 const array_ptr = try sema.resolveInst(extra.lhs);9809 const array_ptr = sema.resolveInst(extra.lhs);
10369 const elem_index = try sema.resolveInst(extra.rhs);9810 const elem_index = sema.resolveInst(extra.rhs);
10370 const indexable_ty = sema.typeOf(array_ptr);9811 const indexable_ty = sema.typeOf(array_ptr);
10371 if (indexable_ty.zigTypeTag(zcu) != .pointer) {9812 if (indexable_ty.zigTypeTag(zcu) != .pointer) {
10372 const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });9813 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...@@ -10382,6 +9823,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10382 };9823 };
10383 return sema.failWithOwnedErrorMsg(block, msg);9824 return sema.failWithOwnedErrorMsg(block, msg);
10384 }9825 }
9826 try sema.checkIndexable(block, src, indexable_ty);
9827 try sema.ensureLayoutResolved(indexable_ty.childType(zcu), src, .ptr_access);
10385 return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false, false);9828 return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false, false);
10386}9829}
103879830
...@@ -10393,8 +9836,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10393,8 +9836,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10393 const src = block.nodeOffset(inst_data.src_node);9836 const src = block.nodeOffset(inst_data.src_node);
10394 const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });9837 const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
10395 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9838 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10396 const array_ptr = try sema.resolveInst(extra.lhs);9839 const array_ptr = sema.resolveInst(extra.lhs);
10397 const uncoerced_elem_index = try sema.resolveInst(extra.rhs);9840 const uncoerced_elem_index = sema.resolveInst(extra.rhs);
10398 const elem_index = try sema.coerce(block, .usize, uncoerced_elem_index, elem_index_src);9841 const elem_index = try sema.coerce(block, .usize, uncoerced_elem_index, elem_index_src);
10399 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true);9842 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true);
10400}9843}
...@@ -10408,7 +9851,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile...@@ -10408,7 +9851,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
10408 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9851 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10409 const src = block.nodeOffset(inst_data.src_node);9852 const src = block.nodeOffset(inst_data.src_node);
10410 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;9853 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);
10412 const elem_index = try pt.intRef(.usize, extra.index);9855 const elem_index = try pt.intRef(.usize, extra.index);
10413 const array_ty = sema.typeOf(array_ptr).childType(zcu);9856 const array_ty = sema.typeOf(array_ptr).childType(zcu);
10414 switch (array_ty.zigTypeTag(zcu)) {9857 switch (array_ty.zigTypeTag(zcu)) {
...@@ -10427,8 +9870,8 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10427,8 +9870,8 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10427 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9870 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10428 const src = block.nodeOffset(inst_data.src_node);9871 const src = block.nodeOffset(inst_data.src_node);
10429 const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;9872 const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;
10430 const array_ptr = try sema.resolveInst(extra.lhs);9873 const array_ptr = sema.resolveInst(extra.lhs);
10431 const start = try sema.resolveInst(extra.start);9874 const start = sema.resolveInst(extra.start);
10432 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });9875 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
10433 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });9876 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
10434 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });9877 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...@@ -10443,9 +9886,9 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10443 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9886 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10444 const src = block.nodeOffset(inst_data.src_node);9887 const src = block.nodeOffset(inst_data.src_node);
10445 const extra = sema.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;9888 const extra = sema.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;
10446 const array_ptr = try sema.resolveInst(extra.lhs);9889 const array_ptr = sema.resolveInst(extra.lhs);
10447 const start = try sema.resolveInst(extra.start);9890 const start = sema.resolveInst(extra.start);
10448 const end = try sema.resolveInst(extra.end);9891 const end = sema.resolveInst(extra.end);
10449 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });9892 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
10450 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });9893 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
10451 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });9894 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...@@ -10461,10 +9904,10 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
10461 const src = block.nodeOffset(inst_data.src_node);9904 const src = block.nodeOffset(inst_data.src_node);
10462 const sentinel_src = block.src(.{ .node_offset_slice_sentinel = inst_data.src_node });9905 const sentinel_src = block.src(.{ .node_offset_slice_sentinel = inst_data.src_node });
10463 const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;9906 const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
10464 const array_ptr = try sema.resolveInst(extra.lhs);9907 const array_ptr = sema.resolveInst(extra.lhs);
10465 const start = try sema.resolveInst(extra.start);9908 const start = sema.resolveInst(extra.start);
10466 const end: Air.Inst.Ref = if (extra.end == .none) .none else try sema.resolveInst(extra.end);9909 const end: Air.Inst.Ref = if (extra.end == .none) .none else sema.resolveInst(extra.end);
10467 const sentinel = try sema.resolveInst(extra.sentinel);9910 const sentinel = sema.resolveInst(extra.sentinel);
10468 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });9911 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
10469 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });9912 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
10470 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });9913 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...@@ -10479,10 +9922,10 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10479 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9922 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10480 const src = block.nodeOffset(inst_data.src_node);9923 const src = block.nodeOffset(inst_data.src_node);
10481 const extra = sema.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;9924 const extra = sema.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;
10482 const array_ptr = try sema.resolveInst(extra.lhs);9925 const array_ptr = sema.resolveInst(extra.lhs);
10483 const start = try sema.resolveInst(extra.start);9926 const start = sema.resolveInst(extra.start);
10484 const len = try sema.resolveInst(extra.len);9927 const len = sema.resolveInst(extra.len);
10485 const sentinel = if (extra.sentinel == .none) .none else try sema.resolveInst(extra.sentinel);9928 const sentinel = if (extra.sentinel == .none) .none else sema.resolveInst(extra.sentinel);
10486 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });9929 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
10487 const start_src = block.src(.{ .node_offset_slice_start = extra.start_src_node_offset });9930 const start_src = block.src(.{ .node_offset_slice_start = extra.start_src_node_offset });
10488 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });9931 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...@@ -10510,7 +9953,7 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
10510 // This is like the logic in `analyzeSlice`; since we've evaluated the LHS as an lvalue, we will9953 // This is like the logic in `analyzeSlice`; since we've evaluated the LHS as an lvalue, we will
10511 // have a double pointer if it was already a pointer.9954 // 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));
10514 const lhs_ty = switch (lhs_ptr_ty.zigTypeTag(zcu)) {9957 const lhs_ty = switch (lhs_ptr_ty.zigTypeTag(zcu)) {
10515 .pointer => lhs_ptr_ty.childType(zcu),9958 .pointer => lhs_ptr_ty.childType(zcu),
10516 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{lhs_ptr_ty.fmt(pt)}),9959 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...@@ -10557,9 +10000,9 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
10557 var label: Block.Label = .{10000 var label: Block.Label = .{
10558 .zir_block = inst,10001 .zir_block = inst,
10559 .merges = .{10002 .merges = .{
10560 .src_locs = .{},10003 .src_locs = .empty,
10561 .results = .{},10004 .results = .empty,
10562 .br_list = .{},10005 .br_list = .empty,
10563 .block_inst = block_inst,10006 .block_inst = block_inst,
10564 },10007 },
10565 };10008 };
...@@ -10590,12 +10033,14 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -10590,12 +10033,14 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
10590 // Lastly, we analyze the error prong(s) as a regular switch.10033 // Lastly, we analyze the error prong(s) as a regular switch.
1059110034
10592 const raw_switch_operand, const non_err_cond, const non_err_hint = non_err: {10035 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);
10594 const err_union_ty: Type = err_union_ty: {10037 const err_union_ty: Type = err_union_ty: {
10595 const raw_operand_ty = sema.typeOf(eu_maybe_ptr);10038 const raw_operand_ty = sema.typeOf(eu_maybe_ptr);
10596 if (!non_err_case.operand_is_ref) break :err_union_ty raw_operand_ty;10039 if (!non_err_case.operand_is_ref) break :err_union_ty raw_operand_ty;
10597 try sema.checkPtrOperand(block, operand_src, raw_operand_ty);10040 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;
10599 };10044 };
10600 if (err_union_ty.zigTypeTag(zcu) != .error_union) {10045 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
10601 return sema.fail(block, operand_src, "expected error union type, found '{f}'", .{10046 return sema.fail(block, operand_src, "expected error union type, found '{f}'", .{
...@@ -10711,9 +10156,9 @@ fn zirSwitchBlock(...@@ -10711,9 +10156,9 @@ fn zirSwitchBlock(
10711 var label: Block.Label = .{10156 var label: Block.Label = .{
10712 .zir_block = inst,10157 .zir_block = inst,
10713 .merges = .{10158 .merges = .{
10714 .src_locs = .{},10159 .src_locs = .empty,
10715 .results = .{},10160 .results = .empty,
10716 .br_list = .{},10161 .br_list = .empty,
10717 .block_inst = block_inst,10162 .block_inst = block_inst,
10718 },10163 },
10719 };10164 };
...@@ -10723,7 +10168,7 @@ fn zirSwitchBlock(...@@ -10723,7 +10168,7 @@ fn zirSwitchBlock(
10723 defer child_block.instructions.deinit(sema.gpa);10168 defer child_block.instructions.deinit(sema.gpa);
10724 defer merges.deinit(sema.gpa);10169 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);
10727 const validated_switch = try sema.validateSwitchBlock(block, raw_operand, operand_is_ref, inst, &zir_switch);10172 const validated_switch = try sema.validateSwitchBlock(block, raw_operand, operand_is_ref, inst, &zir_switch);
10728 const maybe_ref = try sema.analyzeSwitchBlock(block, &child_block, raw_operand, operand_is_ref, merges, inst, &zir_switch, &validated_switch);10173 const maybe_ref = try sema.analyzeSwitchBlock(block, &child_block, raw_operand, operand_is_ref, merges, inst, &zir_switch, &validated_switch);
10729 return maybe_ref orelse {10174 return maybe_ref orelse {
...@@ -10764,18 +10209,19 @@ fn analyzeSwitchBlock(...@@ -10764,18 +10209,19 @@ fn analyzeSwitchBlock(
10764 .{ raw_operand, .none };10209 .{ raw_operand, .none };
1076510210
10766 const operand_ty = sema.typeOf(val);10211 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);
10768 const init_cond: Air.Inst.Ref, const item_ty: Type = switch (operand_ty.zigTypeTag(zcu)) {10214 const init_cond: Air.Inst.Ref, const item_ty: Type = switch (operand_ty.zigTypeTag(zcu)) {
10769 .@"union" => tag: {10215 .@"union" => tag: {
10770 const tag_ty = operand_ty.unionTagType(zcu).?;10216 const tag_val = try sema.unionToTag(block, val);
10771 const tag_val = try sema.unionToTag(block, tag_ty, val, operand_src);10217 break :tag .{ tag_val, sema.typeOf(tag_val) };
10772 break :tag .{ tag_val, tag_ty };
10773 },10218 },
10774 else => .{10219 else => .{
10775 if (maybe_operand_opv) |operand_opv| .fromValue(operand_opv) else val,10220 if (maybe_operand_opv) |operand_opv| .fromValue(operand_opv) else val,
10776 operand_ty,10221 operand_ty,
10777 },10222 },
10778 };10223 };
10224 item_ty.assertHasLayout(zcu);
1077910225
10780 if (zir_switch.has_continue and !block.isComptime()) {10226 if (zir_switch.has_continue and !block.isComptime()) {
10781 const operand_alloc: Air.Inst.Ref = if (zir_switch.any_maybe_runtime_capture and10227 const operand_alloc: Air.Inst.Ref = if (zir_switch.any_maybe_runtime_capture and
...@@ -10849,7 +10295,7 @@ fn analyzeSwitchBlock(...@@ -10849,7 +10295,7 @@ fn analyzeSwitchBlock(
10849 if (extra.block_inst != switch_inst) return error.ComptimeBreak;10295 if (extra.block_inst != switch_inst) return error.ComptimeBreak;
10850 // This is a `switch_continue` targeting this block. Change the operand and start over.10296 // This is a `switch_continue` targeting this block. Change the operand and start over.
10851 const new_operand_src = child_block.nodeOffset(extra.operand_src_node.unwrap().?);10297 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);
10853 const new_operand = try sema.coerce(child_block, raw_operand_ty, new_operand_uncoerced, new_operand_src);10299 const new_operand = try sema.coerce(child_block, raw_operand_ty, new_operand_uncoerced, new_operand_src);
1085410300
10855 try sema.emitBackwardBranch(child_block, src);10301 try sema.emitBackwardBranch(child_block, src);
...@@ -10860,7 +10306,7 @@ fn analyzeSwitchBlock(...@@ -10860,7 +10306,7 @@ fn analyzeSwitchBlock(
10860 .{ new_operand, .none };10306 .{ new_operand, .none };
1086110307
10862 const new_cond_ref = if (union_originally)10308 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)
10864 else10310 else
10865 new_val;10311 new_val;
1086610312
...@@ -10881,7 +10327,7 @@ fn analyzeSwitchBlock(...@@ -10881,7 +10327,7 @@ fn analyzeSwitchBlock(
10881 unreachable;10327 unreachable;
10882 }10328 }
1088310329
10884 if (try sema.typeHasOnePossibleValue(item_ty)) |item_opv| {10330 if (try item_ty.onePossibleValue(pt)) |item_opv| {
10885 // We simplify conditions with OPV to either a `loop` or a `block` since10331 // We simplify conditions with OPV to either a `loop` or a `block` since
10886 // we cannot switch on a value which doesn't exist at runtime.10332 // we cannot switch on a value which doesn't exist at runtime.
10887 assert(operand == .loop); // `simple` should have already been comptime-resolved above!10333 assert(operand == .loop); // `simple` should have already been comptime-resolved above!
...@@ -10912,7 +10358,7 @@ fn analyzeSwitchBlock(...@@ -10912,7 +10358,7 @@ fn analyzeSwitchBlock(
10912 assert(case.range_infos.len == 0);10358 assert(case.range_infos.len == 0);
10913 for (case.item_infos, item_refs) |item_info, item_ref| {10359 for (case.item_infos, item_refs) |item_info, item_ref| {
10914 if (item_info.bodyLen()) |body_len| extra_index += body_len;10360 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)) {
10916 break :skip_case;10362 break :skip_case;
10917 }10363 }
10918 }10364 }
...@@ -10928,7 +10374,7 @@ fn analyzeSwitchBlock(...@@ -10928,7 +10374,7 @@ fn analyzeSwitchBlock(
10928 unreachable; // malformed validated switch10374 unreachable; // malformed validated switch
10929 };10375 };
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);
10932 if (!analyze_body) return .unreachable_value;10378 if (!analyze_body) return .unreachable_value;
1093310379
10934 if (!(err_set and10380 if (!(err_set and
...@@ -10938,10 +10384,10 @@ fn analyzeSwitchBlock(...@@ -10938,10 +10384,10 @@ fn analyzeSwitchBlock(
10938 const payload_inst: Zir.Inst.Index = if (capture != .none) inst: {10384 const payload_inst: Zir.Inst.Index = if (capture != .none) inst: {
10939 const payload_inst = zir_switch.payload_capture_placeholder.unwrap() orelse switch_inst;10385 const payload_inst = zir_switch.payload_capture_placeholder.unwrap() orelse switch_inst;
10940 const payload_ref: Air.Inst.Ref = payload_ref: {10386 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)) {
10942 .@"union" => item_val: {10388 .@"union" => item_val: {
10943 if (maybe_operand_opv) |operand_opv| {10389 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);
10945 }10391 }
10946 assert(union_originally); // operand type must be union, otherwise it would be an OPV type here10392 assert(union_originally); // operand type must be union, otherwise it would be an OPV type here
10947 assert(zir_switch.any_maybe_runtime_capture); // there's a payload capture10393 assert(zir_switch.any_maybe_runtime_capture); // there's a payload capture
...@@ -10978,10 +10424,10 @@ fn analyzeSwitchBlock(...@@ -10978,10 +10424,10 @@ fn analyzeSwitchBlock(
10978 validated_switch.else_err_ty,10424 validated_switch.else_err_ty,
10979 );10425 );
10980 },10426 },
10981 else => item_opv.toIntern(),10427 else => item_opv,
10982 };10428 };
10983 break :payload_ref switch (capture) {10429 break :payload_ref switch (capture) {
10984 .by_val => .fromIntern(item_val),10430 .by_val => .fromValue(item_val),
10985 .by_ref => try sema.uavRef(item_val),10431 .by_ref => try sema.uavRef(item_val),
10986 .none => unreachable,10432 .none => unreachable,
10987 };10433 };
...@@ -11186,7 +10632,7 @@ fn finishSwitchBr(...@@ -11186,7 +10632,7 @@ fn finishSwitchBr(
11186 if (item_ref == .none) is_under_prong = true;10632 if (item_ref == .none) is_under_prong = true;
11187 if (item_info.bodyLen()) |body_len| extra_index += body_len;10633 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);
11190 if (analyze_body) any_analyze_body = true;10636 if (analyze_body) any_analyze_body = true;
1119110637
11192 if (prong_info.is_inline) {10638 if (prong_info.is_inline) {
...@@ -11246,11 +10692,11 @@ fn finishSwitchBr(...@@ -11246,11 +10692,11 @@ fn finishSwitchBr(
11246 any_analyze_body = true; // always an integer range, always needs analysis10692 any_analyze_body = true; // always an integer range, always needs analysis
1124710693
11248 if (prong_info.is_inline) {10694 if (prong_info.is_inline) {
11249 var item = sema.resolveConstDefinedValue(block, .unneeded, range_ref[0], undefined) catch unreachable;10695 var item = sema.resolveValue(range_ref[0]).?;
11250 const item_last = sema.resolveConstDefinedValue(block, .unneeded, range_ref[1], undefined) catch unreachable;10696 const item_last = sema.resolveValue(range_ref[1]).?;
1125110697
11252 if (try item.getUnsignedIntSema(pt)) |first_int| {10698 if (item.getUnsignedInt(zcu)) |first_int| {
11253 if (try item_last.getUnsignedIntSema(pt)) |last_int| {10699 if (item_last.getUnsignedInt(zcu)) |last_int| {
11254 if (std.math.cast(u32, last_int - first_int)) |range_len| {10700 if (std.math.cast(u32, last_int - first_int)) |range_len| {
11255 try branch_hints.ensureUnusedCapacity(gpa, range_len);10701 try branch_hints.ensureUnusedCapacity(gpa, range_len);
11256 }10702 }
...@@ -11259,7 +10705,6 @@ fn finishSwitchBr(...@@ -11259,7 +10705,6 @@ fn finishSwitchBr(
1125910705
11260 var prev_result_overflowed = false;10706 var prev_result_overflowed = false;
11261 while (item.compareScalar(.lte, item_last, operand_ty, zcu)) : ({10707 while (item.compareScalar(.lte, item_last, operand_ty, zcu)) : ({
11262 // Previous validation has resolved any possible lazy values.
11263 const int_val: Value, const int_ty: Type = switch (operand_ty.zigTypeTag(zcu)) {10708 const int_val: Value, const int_ty: Type = switch (operand_ty.zigTypeTag(zcu)) {
11264 .int => .{ item, operand_ty },10709 .int => .{ item, operand_ty },
11265 .@"enum" => b: {10710 .@"enum" => b: {
...@@ -11426,7 +10871,7 @@ fn finishSwitchBr(...@@ -11426,7 +10871,7 @@ fn finishSwitchBr(
1142610871
11427 const item_ref: Air.Inst.Ref = .fromValue(item_val);10872 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
11431 if (emit_bb) try sema.emitBackwardBranch(block, else_prong_src);10876 if (emit_bb) try sema.emitBackwardBranch(block, else_prong_src);
11432 emit_bb = true;10877 emit_bb = true;
...@@ -11896,72 +11341,69 @@ fn validateSwitchBlock(...@@ -11896,72 +11341,69 @@ fn validateSwitchBlock(
11896 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{tag_capture_inst});11341 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{tag_capture_inst});
11897 }11342 }
1189811343
11899 const operand_ty: Type, const item_ty: Type = check_operand: {11344 const operand_ty = operand_ty: {
11900 const operand_ty = operand_ty: {11345 const raw_operand_ty = sema.typeOf(raw_operand);
11901 const raw_operand_ty = sema.typeOf(raw_operand);11346 if (operand_is_ref) {
11902 if (operand_is_ref) {11347 try sema.checkPtrType(block, operand_src, raw_operand_ty, false);
11903 try sema.checkPtrType(block, operand_src, raw_operand_ty, false);11348 const child_ty = raw_operand_ty.childType(zcu);
11904 break :operand_ty raw_operand_ty.childType(zcu);11349 try sema.ensureLayoutResolved(child_ty, operand_src, .ptr_access);
11905 }11350 break :operand_ty child_ty;
11906 break :operand_ty raw_operand_ty;11351 }
11907 };11352 break :operand_ty raw_operand_ty;
1190811353 };
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,
1192111354
11922 .@"union" => {11355 const item_ty: Type = item_ty: {
11923 try operand_ty.resolveFields(pt);11356 switch (operand_ty.zigTypeTag(zcu)) {
11924 const enum_ty = operand_ty.unionTagType(zcu) orelse {11357 .@"enum",
11925 return sema.failWithOwnedErrorMsg(block, msg: {11358 .error_set,
11926 const msg = try sema.errMsg(operand_src, "switch on union with no attached enum", .{});11359 .int,
11927 errdefer msg.destroy(sema.gpa);11360 .comptime_int,
11928 if (operand_ty.srcLocOrNull(zcu)) |union_src| {11361 .type,
11929 try sema.errNote(union_src, msg, "consider 'union(enum)' here", .{});11362 .enum_literal,
11930 }11363 .@"fn",
11931 break :msg msg;11364 .bool,
11932 });11365 .void,
11933 };11366 => break :item_ty operand_ty,
11934 break :item_ty enum_ty;
11935 },
1193611367
11937 .pointer => {11368 .@"union" => {
11938 if (!operand_ty.isSlice(zcu)) {11369 const enum_ty = operand_ty.unionTagType(zcu) orelse {
11939 break :item_ty operand_ty;11370 return sema.failWithOwnedErrorMsg(block, msg: {
11940 }11371 const msg = try sema.errMsg(operand_src, "switch on union with no attached enum", .{});
11941 },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 => {},11382 .pointer => {
11944 }11383 if (!operand_ty.isSlice(zcu)) {
11945 return sema.fail(block, operand_src, "switch on type '{f}'", .{operand_ty.fmt(pt)});11384 break :item_ty operand_ty;
11946 };11385 }
11386 },
1194711387
11948 if (zir_switch.has_continue and !block.isComptime()) {11388 else => {},
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);
11960 }11389 }
1196111390 return sema.fail(block, operand_src, "switch on type '{f}'", .{operand_ty.fmt(pt)});
11962 break :check_operand .{ operand_ty, item_ty };
11963 };11391 };
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
11965 const has_else = zir_switch.else_case != null;11407 const has_else = zir_switch.else_case != null;
11966 const has_under = zir_switch.has_under;11408 const has_under = zir_switch.has_under;
1196711409
...@@ -12305,7 +11747,7 @@ fn resolveSwitchBlock(...@@ -12305,7 +11747,7 @@ fn resolveSwitchBlock(
12305 child_block: *Block,11747 child_block: *Block,
12306 operand: SwitchOperand,11748 operand: SwitchOperand,
12307 raw_operand_ty: Type,11749 raw_operand_ty: Type,
12308 maybe_lazy_cond_val: Value,11750 cond_val: Value,
12309 merges: *Block.Merges,11751 merges: *Block.Merges,
12310 switch_inst: Zir.Inst.Index,11752 switch_inst: Zir.Inst.Index,
12311 zir_switch: *const Zir.UnwrappedSwitchBlock,11753 zir_switch: *const Zir.UnwrappedSwitchBlock,
...@@ -12325,9 +11767,6 @@ fn resolveSwitchBlock(...@@ -12325,9 +11767,6 @@ fn resolveSwitchBlock(
12325 const err_set = item_ty.zigTypeTag(zcu) == .error_set;11767 const err_set = item_ty.zigTypeTag(zcu) == .error_set;
1232611768
12327 const cond_ref = operand.simple.cond;11769 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
12332 const case_vals = validated_switch.case_vals;11771 const case_vals = validated_switch.case_vals;
12333 var case_val_idx: usize = 0;11772 var case_val_idx: usize = 0;
...@@ -12365,7 +11804,7 @@ fn resolveSwitchBlock(...@@ -12365,7 +11804,7 @@ fn resolveSwitchBlock(
12365 };11804 };
12366 continue;11805 continue;
12367 }11806 }
12368 const item_val = sema.resolveConstDefinedValue(child_block, .unneeded, item_ref, undefined) catch unreachable;11807 const item_val = sema.resolveValue(item_ref).?;
12369 if (cond_val.eql(item_val, item_ty, zcu)) {11808 if (cond_val.eql(item_val, item_ty, zcu)) {
12370 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, prong_body, cond_ref);11809 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, prong_body, cond_ref);
12371 if (union_originally and operand_ty.unionFieldType(item_val, zcu).?.isNoReturn(zcu)) {11810 if (union_originally and operand_ty.unionFieldType(item_val, zcu).?.isNoReturn(zcu)) {
...@@ -12398,8 +11837,8 @@ fn resolveSwitchBlock(...@@ -12398,8 +11837,8 @@ fn resolveSwitchBlock(
12398 }11837 }
12399 }11838 }
12400 for (range_refs) |range_ref| {11839 for (range_refs) |range_ref| {
12401 const first_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_ref[0], undefined) catch unreachable;11840 const first_val = sema.resolveValue(range_ref[0]).?;
12402 const last_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_ref[1], undefined) catch unreachable;11841 const last_val = sema.resolveValue(range_ref[1]).?;
12403 if ((try sema.compareAll(cond_val, .gte, first_val, item_ty)) and11842 if ((try sema.compareAll(cond_val, .gte, first_val, item_ty)) and
12404 (try sema.compareAll(cond_val, .lte, last_val, item_ty)))11843 (try sema.compareAll(cond_val, .lte, last_val, item_ty)))
12405 {11844 {
...@@ -12608,7 +12047,6 @@ fn resolveSwitchProng(...@@ -12608,7 +12047,6 @@ fn resolveSwitchProng(
1260812047
12609fn wantSwitchProngBodyAnalysis(12048fn wantSwitchProngBodyAnalysis(
12610 sema: *Sema,12049 sema: *Sema,
12611 block: *Block,
12612 item_ref: Air.Inst.Ref,12050 item_ref: Air.Inst.Ref,
12613 operand_ty: Type,12051 operand_ty: Type,
12614 union_originally: bool,12052 union_originally: bool,
...@@ -12617,16 +12055,14 @@ fn wantSwitchProngBodyAnalysis(...@@ -12617,16 +12055,14 @@ fn wantSwitchProngBodyAnalysis(
12617) bool {12055) bool {
12618 const zcu = sema.pt.zcu;12056 const zcu = sema.pt.zcu;
12619 if (union_originally) {12057 if (union_originally) {
12620 const unresolved_item_val = sema.resolveConstDefinedValue(block, .unneeded, item_ref, undefined) catch unreachable;12058 const item_val = sema.resolveValue(item_ref).?;
12621 const item_val = sema.resolveLazyValue(unresolved_item_val) catch unreachable;
12622 const field_ty = operand_ty.unionFieldType(item_val, zcu).?;12059 const field_ty = operand_ty.unionFieldType(item_val, zcu).?;
12623 if (field_ty.isNoReturn(zcu)) return false;12060 if (field_ty.isNoReturn(zcu)) return false;
12624 }12061 }
12625 if (err_set and prong_is_comptime_unreach) {12062 if (err_set and prong_is_comptime_unreach) {
12626 const unresolved_item_val = sema.resolveConstDefinedValue(block, .unneeded, item_ref, undefined) catch unreachable;12063 const item_val = sema.resolveValue(item_ref).?;
12627 const item_val = sema.resolveLazyValue(unresolved_item_val) catch unreachable;
12628 const err_name = item_val.getErrorName(zcu).unwrap().?;12064 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;
12630 }12066 }
12631 return true;12067 return true;
12632}12068}
...@@ -12772,8 +12208,7 @@ fn analyzeSwitchTagCapture(...@@ -12772,8 +12208,7 @@ fn analyzeSwitchTagCapture(
12772 .item_refs => |refs| if (refs.len == 1) return refs[0],12208 .item_refs => |refs| if (refs.len == 1) return refs[0],
12773 .special => {},12209 .special => {},
12774 }12210 }
12775 const tag_ty = operand_ty.unionTagType(zcu).?;12211 return sema.unionToTag(case_block, operand_val);
12776 return sema.unionToTag(case_block, tag_ty, operand_val, tag_capture_src);
12777}12212}
1277812213
12779fn analyzeSwitchPayloadCapture(12214fn analyzeSwitchPayloadCapture(
...@@ -12800,14 +12235,14 @@ fn analyzeSwitchPayloadCapture(...@@ -12800,14 +12235,14 @@ fn analyzeSwitchPayloadCapture(
12800 const switch_node_offset = operand_src.offset.node_offset_switch_operand;12235 const switch_node_offset = operand_src.offset.node_offset_switch_operand;
1280112236
12802 if (kind == .inline_ref) {12237 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).?;
12804 if (operand_ty.zigTypeTag(zcu) == .@"union") {12239 if (operand_ty.zigTypeTag(zcu) == .@"union") {
12805 const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?);12240 const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?);
12806 const union_obj = zcu.typeToUnion(operand_ty).?;12241 const union_obj = zcu.typeToUnion(operand_ty).?;
12807 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);12242 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
12808 if (capture_by_ref) {12243 if (capture_by_ref) {
12809 const operand_ptr_info = sema.typeOf(operand_ptr).ptrInfo(zcu);12244 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(.{
12811 .child = field_ty.toIntern(),12246 .child = field_ty.toIntern(),
12812 .flags = .{12247 .flags = .{
12813 .is_const = operand_ptr_info.flags.is_const,12248 .is_const = operand_ptr_info.flags.is_const,
...@@ -12821,10 +12256,11 @@ fn analyzeSwitchPayloadCapture(...@@ -12821,10 +12256,11 @@ fn analyzeSwitchPayloadCapture(
12821 const tag_and_val = ip.indexToKey(union_val.toIntern()).un;12256 const tag_and_val = ip.indexToKey(union_val.toIntern()).un;
12822 return .fromIntern(tag_and_val.val);12257 return .fromIntern(tag_and_val.val);
12823 }12258 }
12259 if (try field_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
12824 return case_block.addStructFieldVal(operand_val, field_index, field_ty);12260 return case_block.addStructFieldVal(operand_val, field_index, field_ty);
12825 }12261 }
12826 } else if (capture_by_ref) {12262 } else if (capture_by_ref) {
12827 return sema.uavRef(item_val.toIntern());12263 return sema.uavRef(item_val);
12828 } else {12264 } else {
12829 return kind.inline_ref;12265 return kind.inline_ref;
12830 }12266 }
...@@ -12850,14 +12286,14 @@ fn analyzeSwitchPayloadCapture(...@@ -12850,14 +12286,14 @@ fn analyzeSwitchPayloadCapture(
12850 const case_vals = kind.item_refs;12286 const case_vals = kind.item_refs;
1285112287
12852 const union_obj = zcu.typeToUnion(operand_ty).?;12288 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
12855 const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?;12291 const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?;
12856 const first_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[first_field_index]);12292 const first_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[first_field_index]);
1285712293
12858 const field_indices = try sema.arena.alloc(u32, case_vals.len);12294 const field_indices = try sema.arena.alloc(u32, case_vals.len);
12859 for (case_vals, field_indices) |item, *field_idx| {12295 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).?;
12861 field_idx.* = zcu.unionTagFieldIndex(union_obj, item_val).?;12297 field_idx.* = zcu.unionTagFieldIndex(union_obj, item_val).?;
12862 }12298 }
1286312299
...@@ -12906,23 +12342,14 @@ fn analyzeSwitchPayloadCapture(...@@ -12906,23 +12342,14 @@ fn analyzeSwitchPayloadCapture(
1290612342
12907 // By-reference captures have some further restrictions which make them easier to emit12343 // By-reference captures have some further restrictions which make them easier to emit
12908 if (capture_by_ref) {12344 if (capture_by_ref) {
12909 const operand_ptr_info = sema.typeOf(operand_ptr).ptrInfo(zcu);12345 const operand_ptr_ty = sema.typeOf(operand_ptr);
12910 const capture_ptr_ty = resolve: {12346 const capture_ptr_ty = resolve: {
12911 // By-ref captures of hetereogeneous types are only allowed if all field12347 // By-ref captures of hetereogeneous types are only allowed if all field
12912 // pointer types are peer resolvable to each other.12348 // pointer types are peer resolvable to each other.
12913 // We need values to run PTR on, so make a bunch of undef constants.12349 // We need values to run PTR on, so make a bunch of undef constants.
12914 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);12350 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
12915 for (field_indices, dummy_captures) |field_idx, *dummy| {12351 for (field_indices, dummy_captures) |field_index, *dummy| {
12916 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]);12352 const field_ptr_ty = try operand_ptr_ty.fieldPtrType(field_index, pt);
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 });
12926 dummy.* = try pt.undefRef(field_ptr_ty);12353 dummy.* = try pt.undefRef(field_ptr_ty);
12927 }12354 }
12928 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);12355 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
...@@ -12963,6 +12390,8 @@ fn analyzeSwitchPayloadCapture(...@@ -12963,6 +12390,8 @@ fn analyzeSwitchPayloadCapture(
12963 return case_block.addStructFieldPtr(operand_ptr, first_field_index, capture_ptr_ty);12390 return case_block.addStructFieldPtr(operand_ptr, first_field_index, capture_ptr_ty);
12964 }12391 }
1296512392
12393 if (try capture_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
12394
12966 if (try sema.resolveDefinedValue(case_block, operand_src, operand_val)) |operand_val_val| {12395 if (try sema.resolveDefinedValue(case_block, operand_src, operand_val)) |operand_val_val| {
12967 if (operand_val_val.isUndef(zcu)) return pt.undefRef(capture_ty);12396 if (operand_val_val.isUndef(zcu)) return pt.undefRef(capture_ty);
12968 const union_val = ip.indexToKey(operand_val_val.toIntern()).un;12397 const union_val = ip.indexToKey(operand_val_val.toIntern()).un;
...@@ -13119,7 +12548,7 @@ fn analyzeSwitchPayloadCapture(...@@ -13119,7 +12548,7 @@ fn analyzeSwitchPayloadCapture(
13119 try sema.air_instructions.append(sema.gpa, .{12548 try sema.air_instructions.append(sema.gpa, .{
13120 .tag = .get_union_tag,12549 .tag = .get_union_tag,
13121 .data = .{ .ty_op = .{12550 .data = .{ .ty_op = .{
13122 .ty = .fromIntern(union_obj.enum_tag_ty),12551 .ty = .fromIntern(union_obj.enum_tag_type),
13123 .operand = operand_val,12552 .operand = operand_val,
13124 } },12553 } },
13125 });12554 });
...@@ -13146,7 +12575,7 @@ fn analyzeSwitchPayloadCapture(...@@ -13146,7 +12575,7 @@ fn analyzeSwitchPayloadCapture(
1314612575
13147 const case_vals = kind.item_refs;12576 const case_vals = kind.item_refs;
13148 if (case_vals.len == 1) {12577 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]).?;
13150 const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);12579 const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);
13151 return sema.bitCast(case_block, item_ty, .fromValue(item_val), operand_src, null);12580 return sema.bitCast(case_block, item_ty, .fromValue(item_val), operand_src, null);
13152 }12581 }
...@@ -13154,7 +12583,7 @@ fn analyzeSwitchPayloadCapture(...@@ -13154,7 +12583,7 @@ fn analyzeSwitchPayloadCapture(
13154 var names: InferredErrorSet.NameMap = .{};12583 var names: InferredErrorSet.NameMap = .{};
13155 try names.ensureUnusedCapacity(sema.arena, case_vals.len);12584 try names.ensureUnusedCapacity(sema.arena, case_vals.len);
13156 for (case_vals) |err| {12585 for (case_vals) |err| {
13157 const err_val = sema.resolveConstDefinedValue(case_block, .unneeded, err, undefined) catch unreachable;12586 const err_val = sema.resolveValue(err).?;
13158 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});12587 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});
13159 }12588 }
13160 const error_ty = try pt.errorSetFromUnsortedNames(names.keys());12589 const error_ty = try pt.errorSetFromUnsortedNames(names.keys());
...@@ -13249,7 +12678,7 @@ fn resolveSwitchItem(...@@ -13249,7 +12678,7 @@ fn resolveSwitchItem(
13249 // We allow prongs with errors which are not part of the error set12678 // We allow prongs with errors which are not part of the error set
13250 // being switched on if their prong body is `=> comptime unreachable,`.12679 // being switched on if their prong body is `=> comptime unreachable,`.
13251 switch (try sema.coerceInMemoryAllowedErrorSets(block, item_ty, uncoerced_ty, item_src, item_src)) {12680 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| {
13253 break :item_ref try sema.coerceInMemory(uncoerced_val, item_ty);12682 break :item_ref try sema.coerceInMemory(uncoerced_val, item_ty);
13254 },12683 },
13255 .missing_error => if (prong_is_comptime_unreach) {12684 .missing_error => if (prong_is_comptime_unreach) {
...@@ -13261,17 +12690,8 @@ fn resolveSwitchItem(...@@ -13261,17 +12690,8 @@ fn resolveSwitchItem(
13261 }12690 }
13262 break :item_ref try sema.coerce(block, item_ty, uncoerced, item_src);12691 break :item_ref try sema.coerce(block, item_ty, uncoerced, item_src);
13263 };12692 };
13264 const maybe_lazy = try sema.resolveConstDefinedValue(block, item_src, item_ref, .{ .simple = .switch_item });12693 const val = try sema.resolveConstDefinedValue(block, item_src, item_ref, .{ .simple = .switch_item });
1326512694 return .{ .{ .ref = item_ref, .val = val }, end };
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 };
13275}12695}
1327612696
13277fn validateSwitchItemOrRange(12697fn validateSwitchItemOrRange(
...@@ -13422,7 +12842,7 @@ fn maybeErrorUnwrap(...@@ -13422,7 +12842,7 @@ fn maybeErrorUnwrap(
13422 },12842 },
13423 .panic => {12843 .panic => {
13424 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;12844 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
13427 const panic_fn = try getBuiltin(sema, operand_src, .@"panic.call");12847 const panic_fn = try getBuiltin(sema, operand_src, .@"panic.call");
13428 const args: [2]Air.Inst.Ref = .{ msg_inst, .null_value };12848 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...@@ -13445,7 +12865,7 @@ fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Ind
13445 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;12865 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;
1344612866
13447 const err_inst_data = sema.code.instructions.items(.data)[@intFromEnum(index)].un_node;12867 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);
13449 const operand_ty = sema.typeOf(err_operand);12869 const operand_ty = sema.typeOf(err_operand);
13450 if (operand_ty.zigTypeTag(zcu) == .error_set) {12870 if (operand_ty.zigTypeTag(zcu) == .error_set) {
13451 try sema.maybeErrorUnwrapComptime(block, body, err_operand);12871 try sema.maybeErrorUnwrapComptime(block, body, err_operand);
...@@ -13488,7 +12908,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13488,7 +12908,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13488 const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);12908 const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
13489 const ty = try sema.resolveType(block, ty_src, extra.lhs);12909 const ty = try sema.resolveType(block, ty_src, extra.lhs);
13490 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{ .simple = .field_name });12910 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);
13492 const ip = &zcu.intern_pool;12912 const ip = &zcu.intern_pool;
1349312913
13494 const has_field = hf: {12914 const has_field = hf: {
...@@ -13510,7 +12930,8 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13510,7 +12930,8 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13510 },12930 },
13511 .union_type => {12931 .union_type => {
13512 const union_type = ip.loadUnionType(ty.toIntern());12932 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;
13514 },12935 },
13515 .enum_type => {12936 .enum_type => {
13516 break :hf ip.loadEnumType(ty.toIntern()).nameIndex(ip, field_name) != null;12937 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....@@ -13568,17 +12989,18 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13568 const file = zcu.fileByIndex(file_index);12989 const file = zcu.fileByIndex(file_index);
13569 switch (file.getMode()) {12990 switch (file.getMode()) {
13570 .zig => {12991 .zig => {
13571 try pt.ensureFileAnalyzed(file_index);12992 try pt.ensureFilePopulated(file_index);
13572 const ty = zcu.fileRootType(file_index);12993 const ty: Type = .fromInterned(zcu.fileRootType(file_index));
13573 try sema.declareDependency(.{ .interned = ty });
13574 try sema.addTypeReferenceEntry(operand_src, ty);12994 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);
13576 },12998 },
13577 .zon => {12999 .zon => {
13578 const res_ty: InternPool.Index = b: {13000 const res_ty: InternPool.Index = b: {
13579 if (extra.res_ty == .none) break :b .none;13001 if (extra.res_ty == .none) break :b .none;
13580 const res_ty_inst = try sema.resolveInst(extra.res_ty);13002 const res_ty_inst = sema.resolveInst(extra.res_ty);
13581 const res_ty = try sema.analyzeAsType(block, operand_src, res_ty_inst);13003 const res_ty = try sema.analyzeAsType(block, operand_src, .type, res_ty_inst);
13582 if (res_ty.isGenericPoison()) break :b .none;13004 if (res_ty.isGenericPoison()) break :b .none;
13583 break :b res_ty.toIntern();13005 break :b res_ty.toIntern();
13584 };13006 };
...@@ -13665,8 +13087,8 @@ fn zirShl(...@@ -13665,8 +13087,8 @@ fn zirShl(
13665 const zcu = pt.zcu;13087 const zcu = pt.zcu;
13666 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13088 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13667 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13089 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13668 const lhs = try sema.resolveInst(extra.lhs);13090 const lhs = sema.resolveInst(extra.lhs);
13669 const rhs = try sema.resolveInst(extra.rhs);13091 const rhs = sema.resolveInst(extra.rhs);
13670 const lhs_ty = sema.typeOf(lhs);13092 const lhs_ty = sema.typeOf(lhs);
13671 const rhs_ty = sema.typeOf(rhs);13093 const rhs_ty = sema.typeOf(rhs);
1367213094
...@@ -13692,8 +13114,8 @@ fn zirShl(...@@ -13692,8 +13114,8 @@ fn zirShl(
13692 // we already know `scalar_rhs_ty` is valid for `.shl` -- we only need to validate for `.shl_sat`.13114 // we already know `scalar_rhs_ty` is valid for `.shl` -- we only need to validate for `.shl_sat`.
13693 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);13115 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
1369413116
13695 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);13117 const maybe_lhs_val = sema.resolveValue(lhs);
13696 const maybe_rhs_val = try sema.resolveValueResolveLazy(rhs);13118 const maybe_rhs_val = sema.resolveValue(rhs);
1369713119
13698 const runtime_src = rs: {13120 const runtime_src = rs: {
13699 if (maybe_rhs_val) |rhs_val| {13121 if (maybe_rhs_val) |rhs_val| {
...@@ -13713,11 +13135,11 @@ fn zirShl(...@@ -13713,11 +13135,11 @@ fn zirShl(
13713 const bits = scalar_ty.intInfo(zcu).bits;13135 const bits = scalar_ty.intInfo(zcu).bits;
13714 switch (rhs_ty.zigTypeTag(zcu)) {13136 switch (rhs_ty.zigTypeTag(zcu)) {
13715 .int, .comptime_int => {13137 .int, .comptime_int => {
13716 switch (try rhs_val.orderAgainstZeroSema(pt)) {13138 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
13717 .gt => {13139 .gt => {
13718 if (air_tag != .shl_sat) {13140 if (air_tag != .shl_sat) {
13719 var rhs_space: Value.BigIntSpace = undefined;13141 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);
13721 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {13143 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
13722 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);13144 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
13723 }13145 }
...@@ -13736,11 +13158,11 @@ fn zirShl(...@@ -13736,11 +13158,11 @@ fn zirShl(
13736 .shl, .shl_exact => return sema.failWithUseOfUndef(block, rhs_src, elem_idx),13158 .shl, .shl_exact => return sema.failWithUseOfUndef(block, rhs_src, elem_idx),
13737 else => unreachable,13159 else => unreachable,
13738 };13160 };
13739 switch (try rhs_elem.orderAgainstZeroSema(pt)) {13161 switch (Value.order(rhs_elem, .zero_comptime_int, zcu)) {
13740 .gt => {13162 .gt => {
13741 if (air_tag != .shl_sat) {13163 if (air_tag != .shl_sat) {
13742 var rhs_elem_space: Value.BigIntSpace = undefined;13164 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);
13744 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {13166 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
13745 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);13167 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
13746 }13168 }
...@@ -13769,7 +13191,7 @@ fn zirShl(...@@ -13769,7 +13191,7 @@ fn zirShl(
13769 .shl, .shl_exact => try sema.checkAllScalarsDefined(block, lhs_src, lhs_val),13191 .shl, .shl_exact => try sema.checkAllScalarsDefined(block, lhs_src, lhs_val),
13770 else => unreachable,13192 else => unreachable,
13771 }13193 }
13772 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) return lhs;13194 if (lhs_val.compareAllWithZero(.eq, zcu)) return lhs;
13773 }13195 }
13774 }13196 }
13775 break :rs rhs_src;13197 break :rs rhs_src;
...@@ -13785,13 +13207,13 @@ fn zirShl(...@@ -13785,13 +13207,13 @@ fn zirShl(
13785 const rt_rhs_scalar_ty = try pt.smallestUnsignedInt(bit_count);13207 const rt_rhs_scalar_ty = try pt.smallestUnsignedInt(bit_count);
13786 if (!rhs_ty.isVector(zcu)) break :rt_rhs try pt.intValue(13208 if (!rhs_ty.isVector(zcu)) break :rt_rhs try pt.intValue(
13787 rt_rhs_scalar_ty,13209 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),
13789 );13211 );
13790 const rhs_len = rhs_ty.vectorLen(zcu);13212 const rhs_len = rhs_ty.vectorLen(zcu);
13791 const rhs_elems = try sema.arena.alloc(InternPool.Index, rhs_len);13213 const rhs_elems = try sema.arena.alloc(InternPool.Index, rhs_len);
13792 for (rhs_elems, 0..) |*rhs_elem, i| rhs_elem.* = (try pt.intValue(13214 for (rhs_elems, 0..) |*rhs_elem, i| rhs_elem.* = (try pt.intValue(
13793 rt_rhs_scalar_ty,13215 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),
13795 )).toIntern();13217 )).toIntern();
13796 break :rt_rhs try pt.aggregateValue(try pt.vectorType(.{13218 break :rt_rhs try pt.aggregateValue(try pt.vectorType(.{
13797 .len = rhs_len,13219 .len = rhs_len,
...@@ -13855,8 +13277,8 @@ fn zirShr(...@@ -13855,8 +13277,8 @@ fn zirShr(
13855 const zcu = pt.zcu;13277 const zcu = pt.zcu;
13856 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13278 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13857 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13279 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13858 const lhs = try sema.resolveInst(extra.lhs);13280 const lhs = sema.resolveInst(extra.lhs);
13859 const rhs = try sema.resolveInst(extra.rhs);13281 const rhs = sema.resolveInst(extra.rhs);
13860 const lhs_ty = sema.typeOf(lhs);13282 const lhs_ty = sema.typeOf(lhs);
13861 const rhs_ty = sema.typeOf(rhs);13283 const rhs_ty = sema.typeOf(rhs);
1386213284
...@@ -13875,8 +13297,8 @@ fn zirShr(...@@ -13875,8 +13297,8 @@ fn zirShr(
13875 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13297 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13876 const scalar_ty = lhs_ty.scalarType(zcu);13298 const scalar_ty = lhs_ty.scalarType(zcu);
1387713299
13878 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);13300 const maybe_lhs_val = sema.resolveValue(lhs);
13879 const maybe_rhs_val = try sema.resolveValueResolveLazy(rhs);13301 const maybe_rhs_val = sema.resolveValue(rhs);
1388013302
13881 const runtime_src = rs: {13303 const runtime_src = rs: {
13882 if (maybe_rhs_val) |rhs_val| {13304 if (maybe_rhs_val) |rhs_val| {
...@@ -13893,10 +13315,10 @@ fn zirShr(...@@ -13893,10 +13315,10 @@ fn zirShr(
13893 const bits = scalar_ty.intInfo(zcu).bits;13315 const bits = scalar_ty.intInfo(zcu).bits;
13894 switch (rhs_ty.zigTypeTag(zcu)) {13316 switch (rhs_ty.zigTypeTag(zcu)) {
13895 .int, .comptime_int => {13317 .int, .comptime_int => {
13896 switch (try rhs_val.orderAgainstZeroSema(pt)) {13318 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
13897 .gt => {13319 .gt => {
13898 var rhs_space: Value.BigIntSpace = undefined;13320 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);
13900 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {13322 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
13901 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);13323 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
13902 }13324 }
...@@ -13912,10 +13334,10 @@ fn zirShr(...@@ -13912,10 +13334,10 @@ fn zirShr(
13912 if (rhs_elem.isUndef(zcu)) {13334 if (rhs_elem.isUndef(zcu)) {
13913 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);13335 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);
13914 }13336 }
13915 switch (try rhs_elem.orderAgainstZeroSema(pt)) {13337 switch (Value.order(rhs_elem, .zero_comptime_int, zcu)) {
13916 .gt => {13338 .gt => {
13917 var rhs_elem_space: Value.BigIntSpace = undefined;13339 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);
13919 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {13341 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
13920 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);13342 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
13921 }13343 }
...@@ -13936,7 +13358,7 @@ fn zirShr(...@@ -13936,7 +13358,7 @@ fn zirShr(
13936 }13358 }
13937 if (maybe_lhs_val) |lhs_val| {13359 if (maybe_lhs_val) |lhs_val| {
13938 try sema.checkAllScalarsDefined(block, lhs_src, lhs_val);13360 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;
13940 }13362 }
13941 }13363 }
13942 break :rs rhs_src;13364 break :rs rhs_src;
...@@ -13988,8 +13410,8 @@ fn zirBitwise(...@@ -13988,8 +13410,8 @@ fn zirBitwise(
13988 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });13410 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
13989 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });13411 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
13990 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13412 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13991 const lhs = try sema.resolveInst(extra.lhs);13413 const lhs = sema.resolveInst(extra.lhs);
13992 const rhs = try sema.resolveInst(extra.rhs);13414 const rhs = sema.resolveInst(extra.rhs);
13993 const lhs_ty = sema.typeOf(lhs);13415 const lhs_ty = sema.typeOf(lhs);
13994 const rhs_ty = sema.typeOf(rhs);13416 const rhs_ty = sema.typeOf(rhs);
13995 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13417 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
...@@ -14011,8 +13433,8 @@ fn zirBitwise(...@@ -14011,8 +13433,8 @@ fn zirBitwise(
14011 const runtime_src = runtime: {13433 const runtime_src = runtime: {
14012 // TODO: ask the linker what kind of relocations are available, and13434 // TODO: ask the linker what kind of relocations are available, and
14013 // in some cases emit a Value that means "this decl's address AND'd with this operand".13435 // 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| {13436 if (sema.resolveValue(casted_lhs)) |lhs_val| {
14015 if (try sema.resolveValueResolveLazy(casted_rhs)) |rhs_val| {13437 if (sema.resolveValue(casted_rhs)) |rhs_val| {
14016 const result_val = switch (air_tag) {13438 const result_val = switch (air_tag) {
14017 // zig fmt: off13439 // zig fmt: off
14018 .bit_and => try arith.bitwiseBin(sema, resolved_type, lhs_val, rhs_val, .@"and"),13440 .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....@@ -14040,7 +13462,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14040 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;13462 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14041 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });13463 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
14042 const src = block.nodeOffset(inst_data.src_node);13464 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);
14044 const operand_ty = sema.typeOf(operand);13466 const operand_ty = sema.typeOf(operand);
14045 const scalar_ty = operand_ty.scalarType(zcu);13467 const scalar_ty = operand_ty.scalarType(zcu);
14046 const scalar_tag = scalar_ty.zigTypeTag(zcu);13468 const scalar_tag = scalar_ty.zigTypeTag(zcu);
...@@ -14058,7 +13480,7 @@ fn analyzeBitNot(...@@ -14058,7 +13480,7 @@ fn analyzeBitNot(
14058 src: LazySrcLoc,13480 src: LazySrcLoc,
14059) CompileError!Air.Inst.Ref {13481) CompileError!Air.Inst.Ref {
14060 const operand_ty = sema.typeOf(operand);13482 const operand_ty = sema.typeOf(operand);
14061 if (try sema.resolveValue(operand)) |operand_val| {13483 if (sema.resolveValue(operand)) |operand_val| {
14062 const result_val = try arith.bitwiseNot(sema, operand_ty, operand_val);13484 const result_val = try arith.bitwiseNot(sema, operand_ty, operand_val);
14063 return Air.internedToRef(result_val.toIntern());13485 return Air.internedToRef(result_val.toIntern());
14064 }13486 }
...@@ -14106,13 +13528,13 @@ fn analyzeTupleCat(...@@ -14106,13 +13528,13 @@ fn analyzeTupleCat(
14106 var i: u32 = 0;13528 var i: u32 = 0;
14107 while (i < lhs_len) : (i += 1) {13529 while (i < lhs_len) : (i += 1) {
14108 types[i] = lhs_ty.fieldType(i, zcu).toIntern();13530 types[i] = lhs_ty.fieldType(i, zcu).toIntern();
14109 const default_val = lhs_ty.structFieldDefaultValue(i, zcu);
14110 values[i] = default_val.toIntern();
14111 const operand_src = block.src(.{ .array_cat_lhs = .{13531 const operand_src = block.src(.{ .array_cat_lhs = .{
14112 .array_cat_offset = src_node,13532 .array_cat_offset = src_node,
14113 .elem_index = i,13533 .elem_index = i,
14114 } });13534 } });
14115 if (default_val.toIntern() == .unreachable_value) {13535 if (lhs_ty.structFieldDefaultValue(i, zcu)) |default_val| {
13536 values[i] = default_val.toIntern();
13537 } else {
14116 runtime_src = operand_src;13538 runtime_src = operand_src;
14117 values[i] = .none;13539 values[i] = .none;
14118 }13540 }
...@@ -14120,13 +13542,13 @@ fn analyzeTupleCat(...@@ -14120,13 +13542,13 @@ fn analyzeTupleCat(
14120 i = 0;13542 i = 0;
14121 while (i < rhs_len) : (i += 1) {13543 while (i < rhs_len) : (i += 1) {
14122 types[i + lhs_len] = rhs_ty.fieldType(i, zcu).toIntern();13544 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();
14125 const operand_src = block.src(.{ .array_cat_rhs = .{13545 const operand_src = block.src(.{ .array_cat_rhs = .{
14126 .array_cat_offset = src_node,13546 .array_cat_offset = src_node,
14127 .elem_index = i,13547 .elem_index = i,
14128 } });13548 } });
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 {
14130 runtime_src = operand_src;13552 runtime_src = operand_src;
14131 values[i + lhs_len] = .none;13553 values[i + lhs_len] = .none;
14132 }13554 }
...@@ -14168,8 +13590,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14168,8 +13590,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14168 const zcu = pt.zcu;13590 const zcu = pt.zcu;
14169 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13591 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14170 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13592 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14171 const lhs = try sema.resolveInst(extra.lhs);13593 const lhs = sema.resolveInst(extra.lhs);
14172 const rhs = try sema.resolveInst(extra.rhs);13594 const rhs = sema.resolveInst(extra.rhs);
14173 const lhs_ty = sema.typeOf(lhs);13595 const lhs_ty = sema.typeOf(lhs);
14174 const rhs_ty = sema.typeOf(rhs);13596 const rhs_ty = sema.typeOf(rhs);
14175 const src = block.nodeOffset(inst_data.src_node);13597 const src = block.nodeOffset(inst_data.src_node);
...@@ -14263,12 +13685,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14263,12 +13685,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14263 };13685 };
1426413686
14265 const runtime_src = if (switch (lhs_ty.zigTypeTag(zcu)) {13687 const runtime_src = if (switch (lhs_ty.zigTypeTag(zcu)) {
14266 .array, .@"struct" => try sema.resolveValue(lhs),13688 .array, .@"struct" => sema.resolveValue(lhs),
14267 .pointer => try sema.resolveDefinedValue(block, lhs_src, lhs),13689 .pointer => try sema.resolveDefinedValue(block, lhs_src, lhs),
14268 else => unreachable,13690 else => unreachable,
14269 }) |lhs_val| rs: {13691 }) |lhs_val| rs: {
14270 if (switch (rhs_ty.zigTypeTag(zcu)) {13692 if (switch (rhs_ty.zigTypeTag(zcu)) {
14271 .array, .@"struct" => try sema.resolveValue(rhs),13693 .array, .@"struct" => sema.resolveValue(rhs),
14272 .pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),13694 .pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
14273 else => unreachable,13695 else => unreachable,
14274 }) |rhs_val| {13696 }) |rhs_val| {
...@@ -14290,32 +13712,30 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14290,32 +13712,30 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14290 var elem_i: u32 = 0;13712 var elem_i: u32 = 0;
14291 while (elem_i < lhs_len) : (elem_i += 1) {13713 while (elem_i < lhs_len) : (elem_i += 1) {
14292 const lhs_elem_i = elem_i;13714 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";13715 const elem_default_val: ?Value = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, zcu) else null;
14294 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(pt, lhs_elem_i) else elem_default_val;13716 const elem_val = elem_default_val orelse try lhs_sub_val.elemValue(pt, lhs_elem_i);
14295 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
14296 const operand_src = block.src(.{ .array_cat_lhs = .{13717 const operand_src = block.src(.{ .array_cat_lhs = .{
14297 .array_cat_offset = inst_data.src_node,13718 .array_cat_offset = inst_data.src_node,
14298 .elem_index = elem_i,13719 .elem_index = elem_i,
14299 } });13720 } });
14300 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);13721 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, .fromValue(elem_val), operand_src);
14301 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);13722 const coerced_elem_val = sema.resolveValue(coerced_elem_val_inst).?;
14302 element_vals[elem_i] = coerced_elem_val.toIntern();13723 element_vals[elem_i] = coerced_elem_val.toIntern();
14303 }13724 }
14304 while (elem_i < result_len) : (elem_i += 1) {13725 while (elem_i < result_len) : (elem_i += 1) {
14305 const rhs_elem_i = elem_i - lhs_len;13726 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";13727 const elem_default_val: ?Value = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, zcu) else null;
14307 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(pt, rhs_elem_i) else elem_default_val;13728 const elem_val = elem_default_val orelse try rhs_sub_val.elemValue(pt, rhs_elem_i);
14308 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
14309 const operand_src = block.src(.{ .array_cat_rhs = .{13729 const operand_src = block.src(.{ .array_cat_rhs = .{
14310 .array_cat_offset = inst_data.src_node,13730 .array_cat_offset = inst_data.src_node,
14311 .elem_index = @intCast(rhs_elem_i),13731 .elem_index = @intCast(rhs_elem_i),
14312 } });13732 } });
14313 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);13733 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, .fromValue(elem_val), operand_src);
14314 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);13734 const coerced_elem_val = sema.resolveValue(coerced_elem_val_inst).?;
14315 element_vals[elem_i] = coerced_elem_val.toIntern();13735 element_vals[elem_i] = coerced_elem_val.toIntern();
14316 }13736 }
14317 return sema.addConstantMaybeRef(13737 return sema.addConstantMaybeRef(
14318 (try pt.aggregateValue(result_ty, element_vals)).toIntern(),13738 try pt.aggregateValue(result_ty, element_vals),
14319 ptr_addrspace != null,13739 ptr_addrspace != null,
14320 );13740 );
14321 } else break :rs rhs_src;13741 } else break :rs rhs_src;
...@@ -14324,18 +13744,18 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14324,18 +13744,18 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14324 try sema.requireRuntimeBlock(block, src, runtime_src);13744 try sema.requireRuntimeBlock(block, src, runtime_src);
1432513745
14326 if (ptr_addrspace) |ptr_as| {13746 if (ptr_addrspace) |ptr_as| {
14327 const constant_alloc_ty = try pt.ptrTypeSema(.{13747 const constant_alloc_ty = try pt.ptrType(.{
14328 .child = result_ty.toIntern(),13748 .child = result_ty.toIntern(),
14329 .flags = .{13749 .flags = .{
14330 .address_space = ptr_as,13750 .address_space = ptr_as,
14331 .is_const = true,13751 .is_const = true,
14332 },13752 },
14333 });13753 });
14334 const alloc_ty = try pt.ptrTypeSema(.{13754 const alloc_ty = try pt.ptrType(.{
14335 .child = result_ty.toIntern(),13755 .child = result_ty.toIntern(),
14336 .flags = .{ .address_space = ptr_as },13756 .flags = .{ .address_space = ptr_as },
14337 });13757 });
14338 const elem_ptr_ty = try pt.ptrTypeSema(.{13758 const elem_ptr_ty = try pt.ptrType(.{
14339 .child = resolved_elem_ty.toIntern(),13759 .child = resolved_elem_ty.toIntern(),
14340 .flags = .{ .address_space = ptr_as },13760 .flags = .{ .address_space = ptr_as },
14341 });13761 });
...@@ -14347,7 +13767,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14347,7 +13767,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14347 if (lhs_ty.zigTypeTag(zcu) == .pointer and13767 if (lhs_ty.zigTypeTag(zcu) == .pointer and
14348 rhs_ty.zigTypeTag(zcu) == .pointer)13768 rhs_ty.zigTypeTag(zcu) == .pointer)
14349 {13769 {
14350 const slice_ty = try pt.ptrTypeSema(.{13770 const slice_ty = try pt.ptrType(.{
14351 .child = resolved_elem_ty.toIntern(),13771 .child = resolved_elem_ty.toIntern(),
14352 .flags = .{13772 .flags = .{
14353 .size = .slice,13773 .size = .slice,
...@@ -14359,45 +13779,44 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14359,45 +13779,44 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14359 const many_alloc = try block.addBitCast(many_ty, mutable_alloc);13779 const many_alloc = try block.addBitCast(many_ty, mutable_alloc);
1436013780
14361 // lhs_dest_slice = dest[0..lhs.len]13781 // lhs_dest_slice = dest[0..lhs.len]
14362 const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());13782 if (lhs_len > 0) {
14363 const lhs_len_ref = try pt.intRef(.usize, lhs_len);13783 const lhs_dest_slice = try block.addInst(.{
14364 const lhs_dest_slice = try block.addInst(.{13784 .tag = .slice,
14365 .tag = .slice,13785 .data = .{ .ty_pl = .{
14366 .data = .{ .ty_pl = .{13786 .ty = .fromType(slice_ty),
14367 .ty = slice_ty_ref,13787 .payload = try sema.addExtra(Air.Bin{
14368 .payload = try sema.addExtra(Air.Bin{13788 .lhs = many_alloc,
14369 .lhs = many_alloc,13789 .rhs = try pt.intRef(.usize, lhs_len),
14370 .rhs = lhs_len_ref,13790 }),
14371 }),13791 } },
14372 } },13792 });
14373 });13793 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
1437413794 }
14375 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
1437613795
14377 // rhs_dest_slice = dest[lhs.len..][0..rhs.len]13796 // rhs_dest_slice = dest[lhs.len..][0..rhs.len]
14378 const rhs_len_ref = try pt.intRef(.usize, rhs_len);13797 if (rhs_len > 0) {
14379 const rhs_dest_offset = try block.addInst(.{13798 const rhs_dest_offset = try block.addInst(.{
14380 .tag = .ptr_add,13799 .tag = .ptr_add,
14381 .data = .{ .ty_pl = .{13800 .data = .{ .ty_pl = .{
14382 .ty = Air.internedToRef(many_ty.toIntern()),13801 .ty = Air.internedToRef(many_ty.toIntern()),
14383 .payload = try sema.addExtra(Air.Bin{13802 .payload = try sema.addExtra(Air.Bin{
14384 .lhs = many_alloc,13803 .lhs = many_alloc,
14385 .rhs = lhs_len_ref,13804 .rhs = try pt.intRef(.usize, lhs_len),
14386 }),13805 }),
14387 } },13806 } },
14388 });13807 });
14389 const rhs_dest_slice = try block.addInst(.{13808 const rhs_dest_slice = try block.addInst(.{
14390 .tag = .slice,13809 .tag = .slice,
14391 .data = .{ .ty_pl = .{13810 .data = .{ .ty_pl = .{
14392 .ty = slice_ty_ref,13811 .ty = .fromType(slice_ty),
14393 .payload = try sema.addExtra(Air.Bin{13812 .payload = try sema.addExtra(Air.Bin{
14394 .lhs = rhs_dest_offset,13813 .lhs = rhs_dest_offset,
14395 .rhs = rhs_len_ref,13814 .rhs = try pt.intRef(.usize, rhs_len),
14396 }),13815 }),
14397 } },13816 } },
14398 });13817 });
1439913818 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
14400 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);13819 }
1440113820
14402 if (res_sent_val) |sent_val| {13821 if (res_sent_val) |sent_val| {
14403 const elem_index = try pt.intRef(.usize, result_len);13822 const elem_index = try pt.intRef(.usize, result_len);
...@@ -14486,7 +13905,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -14486,7 +13905,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
14486 .none => null,13905 .none => null,
14487 else => Value.fromInterned(ptr_info.sentinel),13906 else => Value.fromInterned(ptr_info.sentinel),
14488 },13907 },
14489 .len = try val.sliceLen(pt),13908 .len = val.sliceLen(zcu),
14490 };13909 };
14491 },13910 },
14492 .one => {13911 .one => {
...@@ -14500,8 +13919,20 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -14500,8 +13919,20 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
14500 .@"struct" => {13919 .@"struct" => {
14501 if (operand_ty.isTuple(zcu) and peer_ty.isIndexable(zcu)) {13920 if (operand_ty.isTuple(zcu) and peer_ty.isIndexable(zcu)) {
14502 assert(!peer_ty.isTuple(zcu));13921 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 };
14503 return .{13934 return .{
14504 .elem_type = peer_ty.elemType2(zcu),13935 .elem_type = peer_elem_ty,
14505 .sentinel = null,13936 .sentinel = null,
14506 .len = operand_ty.arrayLen(zcu),13937 .len = operand_ty.arrayLen(zcu),
14507 };13938 };
...@@ -14543,12 +13974,13 @@ fn analyzeTupleMul(...@@ -14543,12 +13974,13 @@ fn analyzeTupleMul(
14543 var runtime_src: ?LazySrcLoc = null;13974 var runtime_src: ?LazySrcLoc = null;
14544 for (0..tuple_len) |i| {13975 for (0..tuple_len) |i| {
14545 types[i] = operand_ty.fieldType(i, zcu).toIntern();13976 types[i] = operand_ty.fieldType(i, zcu).toIntern();
14546 values[i] = operand_ty.structFieldDefaultValue(i, zcu).toIntern();
14547 const operand_src = block.src(.{ .array_cat_lhs = .{13977 const operand_src = block.src(.{ .array_cat_lhs = .{
14548 .array_cat_offset = src_node,13978 .array_cat_offset = src_node,
14549 .elem_index = @intCast(i),13979 .elem_index = @intCast(i),
14550 } });13980 } });
14551 if (values[i] == .unreachable_value) {13981 if (operand_ty.structFieldDefaultValue(i, zcu)) |default_val| {
13982 values[i] = default_val.toIntern();
13983 } else {
14552 runtime_src = operand_src;13984 runtime_src = operand_src;
14553 values[i] = .none; // TODO don't treat unreachable_value as special13985 values[i] = .none; // TODO don't treat unreachable_value as special
14554 }13986 }
...@@ -14593,7 +14025,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14593,7 +14025,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14593 const zcu = pt.zcu;14025 const zcu = pt.zcu;
14594 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14026 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14595 const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;14027 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);
14597 const uncoerced_lhs_ty = sema.typeOf(uncoerced_lhs);14029 const uncoerced_lhs_ty = sema.typeOf(uncoerced_lhs);
14598 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);14030 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
14599 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14031 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...@@ -14672,7 +14104,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14672 const ptr_addrspace = if (lhs_ty.zigTypeTag(zcu) == .pointer) lhs_ty.ptrAddressSpace(zcu) else null;14104 const ptr_addrspace = if (lhs_ty.zigTypeTag(zcu) == .pointer) lhs_ty.ptrAddressSpace(zcu) else null;
14673 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);14105 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: {
14676 const lhs_sub_val = if (lhs_ty.isSinglePointer(zcu))14108 const lhs_sub_val = if (lhs_ty.isSinglePointer(zcu))
14677 try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :ct14109 try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :ct
14678 else if (lhs_ty.isSlice(zcu))14110 else if (lhs_ty.isSlice(zcu))
...@@ -14700,7 +14132,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14700,7 +14132,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14700 }14132 }
14701 break :v try pt.aggregateValue(result_ty, element_vals);14133 break :v try pt.aggregateValue(result_ty, element_vals);
14702 };14134 };
14703 return sema.addConstantMaybeRef(val.toIntern(), ptr_addrspace != null);14135 return sema.addConstantMaybeRef(val, ptr_addrspace != null);
14704 }14136 }
1470514137
14706 try sema.requireRuntimeBlock(block, src, lhs_src);14138 try sema.requireRuntimeBlock(block, src, lhs_src);
...@@ -14714,7 +14146,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14714,7 +14146,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14714 }14146 }
1471514147
14716 if (ptr_addrspace) |ptr_as| {14148 if (ptr_addrspace) |ptr_as| {
14717 const alloc_ty = try pt.ptrTypeSema(.{14149 const alloc_ty = try pt.ptrType(.{
14718 .child = result_ty.toIntern(),14150 .child = result_ty.toIntern(),
14719 .flags = .{14151 .flags = .{
14720 .address_space = ptr_as,14152 .address_space = ptr_as,
...@@ -14722,7 +14154,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14722,7 +14154,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14722 },14154 },
14723 });14155 });
14724 const alloc = try block.addTy(.alloc, alloc_ty);14156 const alloc = try block.addTy(.alloc, alloc_ty);
14725 const elem_ptr_ty = try pt.ptrTypeSema(.{14157 const elem_ptr_ty = try pt.ptrType(.{
14726 .child = lhs_info.elem_type.toIntern(),14158 .child = lhs_info.elem_type.toIntern(),
14727 .flags = .{ .address_space = ptr_as },14159 .flags = .{ .address_space = ptr_as },
14728 });14160 });
...@@ -14761,7 +14193,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14761,7 +14193,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14761 const lhs_src = src;14193 const lhs_src = src;
14762 const rhs_src = block.src(.{ .node_offset_un_op = inst_data.src_node });14194 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);
14765 const rhs_ty = sema.typeOf(rhs);14197 const rhs_ty = sema.typeOf(rhs);
14766 const rhs_scalar_ty = rhs_ty.scalarType(zcu);14198 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....@@ -14774,7 +14206,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1477414206
14775 if (rhs_scalar_ty.isAnyFloat()) {14207 if (rhs_scalar_ty.isAnyFloat()) {
14776 // We handle float negation here to ensure negative zero is represented in the bits.14208 // 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| {
14778 const result = try arith.negateFloat(sema, rhs_ty, rhs_val);14210 const result = try arith.negateFloat(sema, rhs_ty, rhs_val);
14779 return Air.internedToRef(result.toIntern());14211 return Air.internedToRef(result.toIntern());
14780 }14212 }
...@@ -14794,7 +14226,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14794,7 +14226,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
14794 const lhs_src = src;14226 const lhs_src = src;
14795 const rhs_src = block.src(.{ .node_offset_un_op = inst_data.src_node });14227 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);
14798 const rhs_ty = sema.typeOf(rhs);14230 const rhs_ty = sema.typeOf(rhs);
14799 const rhs_scalar_ty = rhs_ty.scalarType(zcu);14231 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
1480014232
...@@ -14822,8 +14254,8 @@ fn zirArithmetic(...@@ -14822,8 +14254,8 @@ fn zirArithmetic(
14822 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14254 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
14823 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });14255 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
14824 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14256 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14825 const lhs = try sema.resolveInst(extra.lhs);14257 const lhs = sema.resolveInst(extra.lhs);
14826 const rhs = try sema.resolveInst(extra.rhs);14258 const rhs = sema.resolveInst(extra.rhs);
1482714259
14828 return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, src, lhs_src, rhs_src, safety);14260 return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, src, lhs_src, rhs_src, safety);
14829}14261}
...@@ -14836,8 +14268,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14836,8 +14268,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14836 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14268 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
14837 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });14269 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
14838 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14270 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14839 const lhs = try sema.resolveInst(extra.lhs);14271 const lhs = sema.resolveInst(extra.lhs);
14840 const rhs = try sema.resolveInst(extra.rhs);14272 const rhs = sema.resolveInst(extra.rhs);
14841 const lhs_ty = sema.typeOf(lhs);14273 const lhs_ty = sema.typeOf(lhs);
14842 const rhs_ty = sema.typeOf(rhs);14274 const rhs_ty = sema.typeOf(rhs);
14843 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14275 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...@@ -14859,8 +14291,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1485914291
14860 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div);14292 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);14294 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14863 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14295 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1486414296
14865 if ((lhs_ty.zigTypeTag(zcu) == .comptime_float and rhs_ty.zigTypeTag(zcu) == .comptime_int) or14297 if ((lhs_ty.zigTypeTag(zcu) == .comptime_float and rhs_ty.zigTypeTag(zcu) == .comptime_int) or
14866 (lhs_ty.zigTypeTag(zcu) == .comptime_int and rhs_ty.zigTypeTag(zcu) == .comptime_float))14298 (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...@@ -14945,8 +14377,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14945 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);14377 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
14946 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);14378 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
14947 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14379 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14948 const lhs = try sema.resolveInst(extra.lhs);14380 const lhs = sema.resolveInst(extra.lhs);
14949 const rhs = try sema.resolveInst(extra.rhs);14381 const rhs = sema.resolveInst(extra.rhs);
14950 const lhs_ty = sema.typeOf(lhs);14382 const lhs_ty = sema.typeOf(lhs);
14951 const rhs_ty = sema.typeOf(rhs);14383 const rhs_ty = sema.typeOf(rhs);
14952 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14384 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...@@ -14968,8 +14400,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1496814400
14969 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_exact);14401 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);14403 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14972 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14404 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1497314405
14974 // Because `@divExact` can trigger Illegal Behavior, undefined operands trigger Illegal Behavior.14406 // 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...@@ -15041,8 +14473,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15041 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);14473 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
15042 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);14474 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
15043 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14475 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15044 const lhs = try sema.resolveInst(extra.lhs);14476 const lhs = sema.resolveInst(extra.lhs);
15045 const rhs = try sema.resolveInst(extra.rhs);14477 const rhs = sema.resolveInst(extra.rhs);
15046 const lhs_ty = sema.typeOf(lhs);14478 const lhs_ty = sema.typeOf(lhs);
15047 const rhs_ty = sema.typeOf(rhs);14479 const rhs_ty = sema.typeOf(rhs);
15048 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14480 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...@@ -15064,8 +14496,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1506414496
15065 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_floor);14497 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);14499 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15068 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14500 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1506914501
15070 const allow_div_zero = !is_int and14502 const allow_div_zero = !is_int and
15071 resolved_type.toIntern() != .comptime_float_type and14503 resolved_type.toIntern() != .comptime_float_type and
...@@ -15106,8 +14538,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15106,8 +14538,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15106 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);14538 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
15107 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);14539 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
15108 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14540 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15109 const lhs = try sema.resolveInst(extra.lhs);14541 const lhs = sema.resolveInst(extra.lhs);
15110 const rhs = try sema.resolveInst(extra.rhs);14542 const rhs = sema.resolveInst(extra.rhs);
15111 const lhs_ty = sema.typeOf(lhs);14543 const lhs_ty = sema.typeOf(lhs);
15112 const rhs_ty = sema.typeOf(rhs);14544 const rhs_ty = sema.typeOf(rhs);
15113 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14545 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...@@ -15129,8 +14561,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1512914561
15130 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_trunc);14562 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);14564 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15133 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14565 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1513414566
15135 const allow_div_zero = !is_int and14567 const allow_div_zero = !is_int and
15136 resolved_type.toIntern() != .comptime_float_type and14568 resolved_type.toIntern() != .comptime_float_type and
...@@ -15317,8 +14749,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15317,8 +14749,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15317 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14749 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
15318 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });14750 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
15319 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14751 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15320 const lhs = try sema.resolveInst(extra.lhs);14752 const lhs = sema.resolveInst(extra.lhs);
15321 const rhs = try sema.resolveInst(extra.rhs);14753 const rhs = sema.resolveInst(extra.rhs);
15322 const lhs_ty = sema.typeOf(lhs);14754 const lhs_ty = sema.typeOf(lhs);
15323 const rhs_ty = sema.typeOf(rhs);14755 const rhs_ty = sema.typeOf(rhs);
15324 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14756 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....@@ -15341,8 +14773,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1534114773
15342 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod_rem);14774 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);14776 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15345 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14777 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1534614778
15347 const lhs_maybe_negative = a: {14779 const lhs_maybe_negative = a: {
15348 if (lhs_scalar_ty.isUnsignedInt(zcu)) break :a false;14780 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...@@ -15418,8 +14850,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15418 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);14850 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
15419 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);14851 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
15420 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14852 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15421 const lhs = try sema.resolveInst(extra.lhs);14853 const lhs = sema.resolveInst(extra.lhs);
15422 const rhs = try sema.resolveInst(extra.rhs);14854 const rhs = sema.resolveInst(extra.rhs);
15423 const lhs_ty = sema.typeOf(lhs);14855 const lhs_ty = sema.typeOf(lhs);
15424 const rhs_ty = sema.typeOf(rhs);14856 const rhs_ty = sema.typeOf(rhs);
15425 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14857 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...@@ -15440,8 +14872,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1544014872
15441 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod);14873 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);14875 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15444 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14876 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1544514877
15446 const allow_div_zero = !is_int and14878 const allow_div_zero = !is_int and
15447 resolved_type.toIntern() != .comptime_float_type and14879 resolved_type.toIntern() != .comptime_float_type and
...@@ -15482,8 +14914,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15482,8 +14914,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15482 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);14914 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
15483 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);14915 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
15484 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14916 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15485 const lhs = try sema.resolveInst(extra.lhs);14917 const lhs = sema.resolveInst(extra.lhs);
15486 const rhs = try sema.resolveInst(extra.rhs);14918 const rhs = sema.resolveInst(extra.rhs);
15487 const lhs_ty = sema.typeOf(lhs);14919 const lhs_ty = sema.typeOf(lhs);
15488 const rhs_ty = sema.typeOf(rhs);14920 const rhs_ty = sema.typeOf(rhs);
15489 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);14921 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...@@ -15504,8 +14936,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1550414936
15505 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .rem);14937 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);14939 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15508 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);14940 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1550914941
15510 const allow_div_zero = !is_int and14942 const allow_div_zero = !is_int and
15511 resolved_type.toIntern() != .comptime_float_type and14943 resolved_type.toIntern() != .comptime_float_type and
...@@ -15553,8 +14985,8 @@ fn zirOverflowArithmetic(...@@ -15553,8 +14985,8 @@ fn zirOverflowArithmetic(
15553 const lhs_src = block.builtinCallArgSrc(extra.node, 0);14985 const lhs_src = block.builtinCallArgSrc(extra.node, 0);
15554 const rhs_src = block.builtinCallArgSrc(extra.node, 1);14986 const rhs_src = block.builtinCallArgSrc(extra.node, 1);
1555514987
15556 const uncasted_lhs = try sema.resolveInst(extra.lhs);14988 const uncasted_lhs = sema.resolveInst(extra.lhs);
15557 const uncasted_rhs = try sema.resolveInst(extra.rhs);14989 const uncasted_rhs = sema.resolveInst(extra.rhs);
1555814990
15559 const lhs_ty = sema.typeOf(uncasted_lhs);14991 const lhs_ty = sema.typeOf(uncasted_lhs);
15560 const rhs_ty = sema.typeOf(uncasted_rhs);14992 const rhs_ty = sema.typeOf(uncasted_rhs);
...@@ -15584,8 +15016,8 @@ fn zirOverflowArithmetic(...@@ -15584,8 +15016,8 @@ fn zirOverflowArithmetic(
15584 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{f}'", .{dest_ty.fmt(pt)});15016 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{f}'", .{dest_ty.fmt(pt)});
15585 }15017 }
1558615018
15587 const maybe_lhs_val = try sema.resolveValue(lhs);15019 const maybe_lhs_val = sema.resolveValue(lhs);
15588 const maybe_rhs_val = try sema.resolveValue(rhs);15020 const maybe_rhs_val = sema.resolveValue(rhs);
1558915021
15590 const tuple_ty = try pt.overflowArithmeticTupleType(dest_ty);15022 const tuple_ty = try pt.overflowArithmeticTupleType(dest_ty);
15591 const overflow_ty: Type = .fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]);15023 const overflow_ty: Type = .fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]);
...@@ -15601,12 +15033,12 @@ fn zirOverflowArithmetic(...@@ -15601,12 +15033,12 @@ fn zirOverflowArithmetic(
15601 // to the result, even if it is undefined..15033 // to the result, even if it is undefined..
15602 // Otherwise, if either of the argument is undefined, undefined is returned.15034 // Otherwise, if either of the argument is undefined, undefined is returned.
15603 if (maybe_lhs_val) |lhs_val| {15035 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)) {
15605 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs };15037 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs };
15606 }15038 }
15607 }15039 }
15608 if (maybe_rhs_val) |rhs_val| {15040 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)) {
15610 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };15042 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
15611 }15043 }
15612 }15044 }
...@@ -15627,7 +15059,7 @@ fn zirOverflowArithmetic(...@@ -15627,7 +15059,7 @@ fn zirOverflowArithmetic(
15627 if (maybe_rhs_val) |rhs_val| {15059 if (maybe_rhs_val) |rhs_val| {
15628 if (rhs_val.isUndef(zcu)) {15060 if (rhs_val.isUndef(zcu)) {
15629 break :result .{ .overflow_bit = .undef, .wrapped = .undef };15061 break :result .{ .overflow_bit = .undef, .wrapped = .undef };
15630 } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {15062 } else if (rhs_val.compareAllWithZero(.eq, zcu)) {
15631 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };15063 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
15632 } else if (maybe_lhs_val) |lhs_val| {15064 } else if (maybe_lhs_val) |lhs_val| {
15633 if (lhs_val.isUndef(zcu)) {15065 if (lhs_val.isUndef(zcu)) {
...@@ -15642,12 +15074,12 @@ fn zirOverflowArithmetic(...@@ -15642,12 +15074,12 @@ fn zirOverflowArithmetic(
15642 .mul_with_overflow => {15074 .mul_with_overflow => {
15643 // If either of the arguments is zero, the result is zero and no overflow occured.15075 // If either of the arguments is zero, the result is zero and no overflow occured.
15644 if (maybe_lhs_val) |lhs_val| {15076 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)) {
15646 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };15078 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
15647 }15079 }
15648 }15080 }
15649 if (maybe_rhs_val) |rhs_val| {15081 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)) {
15651 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs };15083 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs };
15652 }15084 }
15653 }15085 }
...@@ -15694,10 +15126,10 @@ fn zirOverflowArithmetic(...@@ -15694,10 +15126,10 @@ fn zirOverflowArithmetic(
15694 const bits = scalar_ty.intInfo(zcu).bits;15126 const bits = scalar_ty.intInfo(zcu).bits;
15695 switch (rhs_ty.zigTypeTag(zcu)) {15127 switch (rhs_ty.zigTypeTag(zcu)) {
15696 .int, .comptime_int => {15128 .int, .comptime_int => {
15697 switch (try rhs_val.orderAgainstZeroSema(pt)) {15129 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
15698 .gt => {15130 .gt => {
15699 var rhs_space: Value.BigIntSpace = undefined;15131 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);
15701 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {15133 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
15702 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);15134 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
15703 }15135 }
...@@ -15711,10 +15143,10 @@ fn zirOverflowArithmetic(...@@ -15711,10 +15143,10 @@ fn zirOverflowArithmetic(
15711 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {15143 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {
15712 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);15144 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
15713 if (rhs_elem.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, elem_idx);15145 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)) {
15715 .gt => {15147 .gt => {
15716 var rhs_elem_space: Value.BigIntSpace = undefined;15148 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);
15718 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {15150 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
15719 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);15151 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
15720 }15152 }
...@@ -15728,7 +15160,7 @@ fn zirOverflowArithmetic(...@@ -15728,7 +15160,7 @@ fn zirOverflowArithmetic(
15728 },15160 },
15729 else => unreachable,15161 else => unreachable,
15730 }15162 }
15731 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {15163 if (rhs_val.compareAllWithZero(.eq, zcu)) {
15732 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };15164 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
15733 }15165 }
15734 } else {15166 } else {
...@@ -15737,7 +15169,7 @@ fn zirOverflowArithmetic(...@@ -15737,7 +15169,7 @@ fn zirOverflowArithmetic(
15737 }15169 }
15738 if (maybe_lhs_val) |lhs_val| {15170 if (maybe_lhs_val) |lhs_val| {
15739 try sema.checkAllScalarsDefined(block, lhs_src, lhs_val);15171 try sema.checkAllScalarsDefined(block, lhs_src, lhs_val);
15740 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {15172 if (lhs_val.compareAllWithZero(.eq, zcu)) {
15741 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };15173 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
15742 }15174 }
15743 }15175 }
...@@ -15767,7 +15199,7 @@ fn zirOverflowArithmetic(...@@ -15767,7 +15199,7 @@ fn zirOverflowArithmetic(
15767 };15199 };
1576815200
15769 if (result.inst != .none) {15201 if (result.inst != .none) {
15770 if (try sema.resolveValue(result.inst)) |some| {15202 if (sema.resolveValue(result.inst)) |some| {
15771 result.wrapped = some;15203 result.wrapped = some;
15772 result.inst = .none;15204 result.inst = .none;
15773 }15205 }
...@@ -15817,22 +15249,45 @@ fn analyzeArithmetic(...@@ -15817,22 +15249,45 @@ fn analyzeArithmetic(
15817 if (zir_tag != .sub) {15249 if (zir_tag != .sub) {
15818 return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction");15250 return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction");
15819 }15251 }
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()) {
15821 return sema.fail(block, src, "incompatible pointer arithmetic operands '{f}' and '{f}'", .{15275 return sema.fail(block, src, "incompatible pointer arithmetic operands '{f}' and '{f}'", .{
15822 lhs_ty.fmt(pt), rhs_ty.fmt(pt),15276 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
15823 });15277 });
15824 }15278 }
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);
15827 if (elem_size == 0) {15282 if (elem_size == 0) {
15828 return sema.fail(block, src, "pointer arithmetic requires element type '{f}' to have runtime bits", .{15283 return sema.fail(block, src, "pointer subtraction requires element type '{f}' to have runtime bits", .{
15829 lhs_ty.elemType2(zcu).fmt(pt),15284 lhs_elem_ty.fmt(pt),
15830 });15285 });
15831 }15286 }
1583215287
15833 const runtime_src = runtime_src: {15288 const runtime_src = runtime_src: {
15834 if (try sema.resolveValue(lhs)) |lhs_value| {15289 if (sema.resolveValue(lhs)) |lhs_value| {
15835 if (try sema.resolveValue(rhs)) |rhs_value| {15290 if (sema.resolveValue(rhs)) |rhs_value| {
15836 const lhs_ptr = switch (zcu.intern_pool.indexToKey(lhs_value.toIntern())) {15291 const lhs_ptr = switch (zcu.intern_pool.indexToKey(lhs_value.toIntern())) {
15837 .undef => return sema.failWithUseOfUndef(block, lhs_src, null),15292 .undef => return sema.failWithUseOfUndef(block, lhs_src, null),
15838 .ptr => |ptr| ptr,15293 .ptr => |ptr| ptr,
...@@ -15875,12 +15330,8 @@ fn analyzeArithmetic(...@@ -15875,12 +15330,8 @@ fn analyzeArithmetic(
15875 else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"),15330 else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"),
15876 };15331 };
1587715332
15878 if (!try lhs_ty.elemType2(zcu).hasRuntimeBitsSema(pt)) {15333 try sema.ensureLayoutResolved(lhs_ty.childType(zcu), src, .ptr_offset);
15879 return sema.fail(block, src, "pointer arithmetic requires element type '{f}' to have runtime bits", .{15334 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, rhs_src);
15880 lhs_ty.elemType2(zcu).fmt(pt),
15881 });
15882 }
15883 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, lhs_src, rhs_src);
15884 },15335 },
15885 }15336 }
15886 }15337 }
...@@ -15915,8 +15366,8 @@ fn analyzeArithmetic(...@@ -15915,8 +15366,8 @@ fn analyzeArithmetic(
15915 else => unreachable,15366 else => unreachable,
15916 };15367 };
1591715368
15918 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);15369 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15919 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);15370 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1592015371
15921 if (maybe_lhs_val) |lhs_val| {15372 if (maybe_lhs_val) |lhs_val| {
15922 if (maybe_rhs_val) |rhs_val| {15373 if (maybe_rhs_val) |rhs_val| {
...@@ -15972,6 +15423,7 @@ fn analyzeArithmetic(...@@ -15972,6 +15423,7 @@ fn analyzeArithmetic(
15972 return block.addBinOp(air_tag, casted_lhs, casted_rhs);15423 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
15973}15424}
1597415425
15426/// Asserts that the layout of the pointer child type is already resolved.
15975fn analyzePtrArithmetic(15427fn analyzePtrArithmetic(
15976 sema: *Sema,15428 sema: *Sema,
15977 block: *Block,15429 block: *Block,
...@@ -15979,7 +15431,6 @@ fn analyzePtrArithmetic(...@@ -15979,7 +15431,6 @@ fn analyzePtrArithmetic(
15979 ptr: Air.Inst.Ref,15431 ptr: Air.Inst.Ref,
15980 uncasted_offset: Air.Inst.Ref,15432 uncasted_offset: Air.Inst.Ref,
15981 air_tag: Air.Inst.Tag,15433 air_tag: Air.Inst.Tag,
15982 ptr_src: LazySrcLoc,
15983 offset_src: LazySrcLoc,15434 offset_src: LazySrcLoc,
15984) CompileError!Air.Inst.Ref {15435) CompileError!Air.Inst.Ref {
15985 // TODO if the operand is comptime-known to be negative, or is a negative int,15436 // TODO if the operand is comptime-known to be negative, or is a negative int,
...@@ -15987,81 +15438,55 @@ fn analyzePtrArithmetic(...@@ -15987,81 +15438,55 @@ fn analyzePtrArithmetic(
15987 const offset = try sema.coerce(block, .usize, uncasted_offset, offset_src);15438 const offset = try sema.coerce(block, .usize, uncasted_offset, offset_src);
15988 const pt = sema.pt;15439 const pt = sema.pt;
15989 const zcu = pt.zcu;15440 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);
15992 const ptr_ty = sema.typeOf(ptr);15441 const ptr_ty = sema.typeOf(ptr);
15993 const ptr_info = ptr_ty.ptrInfo(zcu);15442 const ptr_info = ptr_ty.ptrInfo(zcu);
15994 assert(ptr_info.flags.size == .many or ptr_info.flags.size == .c);15443 assert(ptr_info.flags.size == .many or ptr_info.flags.size == .c);
1599515444
15996 if ((try sema.typeHasOnePossibleValue(.fromInterned(ptr_info.child))) != null) {15445 const maybe_index: ?u64 = if (try sema.resolveDefinedValue(block, offset_src, offset)) |val| off: {
15997 // Offset will be multiplied by zero, so result is the same as the base pointer.15446 break :off val.toUnsignedInt(zcu);
15998 return ptr;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 => {},
15999 }15458 }
1600015459
16001 const new_ptr_ty = t: {15460 const elem_ptr_ty = try ptr_ty.elemPtrType(maybe_index, pt);
16002 // Calculate the new pointer alignment.15461 // `elem_ptr_ty` is a single-item pointer, but we want a many-item or C pointer, and to preserve
16003 // This code is duplicated in `Type.elemPtrType`.15462 // any input sentinel.
16004 if (ptr_info.flags.alignment == .none) {15463 const new_ptr_ty = try pt.ptrType(info: {
16005 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.15464 var info = elem_ptr_ty.ptrInfo(zcu);
16006 break :t ptr_ty;15465 info.flags.size = ptr_info.flags.size;
16007 }15466 info.sentinel = ptr_info.sentinel;
16008 // If the addend is not a comptime-known value we can still count on15467 break :info info;
16009 // it being a multiple of the type size.15468 });
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 };
1603815469
16039 const runtime_src = rs: {15470 ct: {
16040 if (opt_ptr_val) |ptr_val| {15471 const ptr_val = sema.resolveValue(ptr) orelse break :ct;
16041 if (opt_off_val) |offset_val| {15472 if (ptr_val.isUndef(zcu)) return pt.undefRef(new_ptr_ty);
16042 if (ptr_val.isUndef(zcu)) return pt.undefRef(new_ptr_ty);15473 const index = maybe_index orelse break :ct;
1604315474
16044 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(pt));15475 if (index == 0) return ptr;
16045 if (offset_int == 0) return ptr;15476 if (air_tag == .ptr_sub) {
16046 if (air_tag == .ptr_sub) {15477 const elem_size = elem_ty.abiSize(zcu);
16047 const elem_size = try Type.fromInterned(ptr_info.child).abiSizeSema(pt);15478 return .fromValue(try sema.ptrSubtract(block, op_src, ptr_val, index * elem_size, new_ptr_ty));
16048 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);15479 } else {
16049 return Air.internedToRef(new_ptr_val.toIntern());15480 return .fromValue(try pt.getCoerced(try ptr_val.ptrElem(index, pt), new_ptr_ty));
16050 } else {15481 }
16051 const new_ptr_val = try pt.getCoerced(try ptr_val.ptrElem(offset_int, pt), new_ptr_ty);15482 }
16052 return Air.internedToRef(new_ptr_val.toIntern());
16053 }
16054 } else break :rs offset_src;
16055 } else break :rs ptr_src;
16056 };
1605715483
16058 try sema.requireRuntimeBlock(block, op_src, runtime_src);
16059 try sema.checkLogicalPtrOperation(block, op_src, ptr_ty);15484 try sema.checkLogicalPtrOperation(block, op_src, ptr_ty);
1606015485
16061 return block.addInst(.{15486 return block.addInst(.{
16062 .tag = air_tag,15487 .tag = air_tag,
16063 .data = .{ .ty_pl = .{15488 .data = .{ .ty_pl = .{
16064 .ty = Air.internedToRef(new_ptr_ty.toIntern()),15489 .ty = .fromType(new_ptr_ty),
16065 .payload = try sema.addExtra(Air.Bin{15490 .payload = try sema.addExtra(Air.Bin{
16066 .lhs = ptr,15491 .lhs = ptr,
16067 .rhs = offset,15492 .rhs = offset,
...@@ -16077,7 +15502,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In...@@ -16077,7 +15502,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In
16077 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;15502 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
16078 const src = block.nodeOffset(inst_data.src_node);15503 const src = block.nodeOffset(inst_data.src_node);
16079 const ptr_src = src; // TODO better source location15504 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);
16081 return sema.analyzeLoad(block, src, ptr, ptr_src);15506 return sema.analyzeLoad(block, src, ptr, ptr_src);
16082}15507}
1608315508
...@@ -16151,7 +15576,7 @@ fn zirAsm(...@@ -16151,7 +15576,7 @@ fn zirAsm(
16151 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);15576 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
16152 expr_ty = Air.internedToRef(out_ty.toIntern());15577 expr_ty = Air.internedToRef(out_ty.toIntern());
16153 } else {15578 } else {
16154 const inst = try sema.resolveInst(output.data.operand);15579 const inst = sema.resolveInst(output.data.operand);
16155 if (!sema.checkRuntimeValue(inst)) {15580 if (!sema.checkRuntimeValue(inst)) {
16156 const output_name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);15581 const output_name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
16157 return sema.failWithContainsReferenceToComptimeVar(block, output_src, output_name, "assembly output", .fromInterned(inst.toInterned().?));15582 return sema.failWithContainsReferenceToComptimeVar(block, output_src, output_name, "assembly output", .fromInterned(inst.toInterned().?));
...@@ -16181,7 +15606,7 @@ fn zirAsm(...@@ -16181,7 +15606,7 @@ fn zirAsm(
16181 } });15606 } });
16182 extra_i = input.end;15607 extra_i = input.end;
1618315608
16184 const uncasted_arg = try sema.resolveInst(input.data.operand);15609 const uncasted_arg = sema.resolveInst(input.data.operand);
16185 const name = sema.code.nullTerminatedString(input.data.name);15610 const name = sema.code.nullTerminatedString(input.data.name);
16186 if (!sema.checkRuntimeValue(uncasted_arg)) {15611 if (!sema.checkRuntimeValue(uncasted_arg)) {
16187 const input_name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);15612 const input_name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
...@@ -16204,7 +15629,7 @@ fn zirAsm(...@@ -16204,7 +15629,7 @@ fn zirAsm(
16204 const clobbers = if (extra.data.clobbers == .none) empty: {15629 const clobbers = if (extra.data.clobbers == .none) empty: {
16205 const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers");15630 const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers");
16206 break :empty try sema.structInitEmpty(block, clobbers_ty, src, src);15631 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.
16208 const clobbers_val = try sema.resolveConstDefinedValue(block, src, clobbers, .{ .simple = .clobber });15633 const clobbers_val = try sema.resolveConstDefinedValue(block, src, clobbers, .{ .simple = .clobber });
16209 needed_capacity += asm_source.len / 4 + 1;15634 needed_capacity += asm_source.len / 4 + 1;
1621015635
...@@ -16248,6 +15673,7 @@ fn zirAsm(...@@ -16248,6 +15673,7 @@ fn zirAsm(
16248 buffer[input.c.len + 1 + input.n.len] = 0;15673 buffer[input.c.len + 1 + input.n.len] = 0;
16249 sema.air_extra.items.len += (input.c.len + input.n.len + (2 + 3)) / 4;15674 sema.air_extra.items.len += (input.c.len + input.n.len + (2 + 3)) / 4;
16250 }15675 }
15676 if (try expr_ty.toType().onePossibleValue(pt)) |opv| return .fromValue(opv);
16251 return asm_air;15677 return asm_air;
16252}15678}
1625315679
...@@ -16269,8 +15695,8 @@ fn zirCmpEq(...@@ -16269,8 +15695,8 @@ fn zirCmpEq(
16269 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);15695 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
16270 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15696 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
16271 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });15697 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
16272 const lhs = try sema.resolveInst(extra.lhs);15698 const lhs = sema.resolveInst(extra.lhs);
16273 const rhs = try sema.resolveInst(extra.rhs);15699 const rhs = sema.resolveInst(extra.rhs);
1627415700
16275 const lhs_ty = sema.typeOf(lhs);15701 const lhs_ty = sema.typeOf(lhs);
16276 const rhs_ty = sema.typeOf(rhs);15702 const rhs_ty = sema.typeOf(rhs);
...@@ -16283,10 +15709,10 @@ fn zirCmpEq(...@@ -16283,10 +15709,10 @@ fn zirCmpEq(
1628315709
16284 // comparing null with optionals15710 // comparing null with optionals
16285 if (lhs_ty_tag == .null and (rhs_ty_tag == .optional or rhs_ty.isCPtr(zcu))) {15711 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);
16287 }15713 }
16288 if (rhs_ty_tag == .null and (lhs_ty_tag == .optional or lhs_ty.isCPtr(zcu))) {15714 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);
16290 }15716 }
1629115717
16292 if (lhs_ty_tag == .null or rhs_ty_tag == .null) {15718 if (lhs_ty_tag == .null or rhs_ty_tag == .null) {
...@@ -16303,8 +15729,8 @@ fn zirCmpEq(...@@ -16303,8 +15729,8 @@ fn zirCmpEq(
1630315729
16304 if (lhs_ty_tag == .error_set and rhs_ty_tag == .error_set) {15730 if (lhs_ty_tag == .error_set and rhs_ty_tag == .error_set) {
16305 const runtime_src: LazySrcLoc = src: {15731 const runtime_src: LazySrcLoc = src: {
16306 if (try sema.resolveValue(lhs)) |lval| {15732 if (sema.resolveValue(lhs)) |lval| {
16307 if (try sema.resolveValue(rhs)) |rval| {15733 if (sema.resolveValue(rhs)) |rval| {
16308 if (lval.isUndef(zcu) or rval.isUndef(zcu)) return .undef_bool;15734 if (lval.isUndef(zcu) or rval.isUndef(zcu)) return .undef_bool;
16309 const lkey = zcu.intern_pool.indexToKey(lval.toIntern());15735 const lkey = zcu.intern_pool.indexToKey(lval.toIntern());
16310 const rkey = zcu.intern_pool.indexToKey(rval.toIntern());15736 const rkey = zcu.intern_pool.indexToKey(rval.toIntern());
...@@ -16323,8 +15749,8 @@ fn zirCmpEq(...@@ -16323,8 +15749,8 @@ fn zirCmpEq(
16323 return block.addBinOp(air_tag, lhs, rhs);15749 return block.addBinOp(air_tag, lhs, rhs);
16324 }15750 }
16325 if (lhs_ty_tag == .type and rhs_ty_tag == .type) {15751 if (lhs_ty_tag == .type and rhs_ty_tag == .type) {
16326 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);15752 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, .type, lhs);
16327 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);15753 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, .type, rhs);
16328 return if (lhs_as_type.eql(rhs_as_type, zcu) == (op == .eq)) .bool_true else .bool_false;15754 return if (lhs_as_type.eql(rhs_as_type, zcu) == (op == .eq)) .bool_true else .bool_false;
16329 }15755 }
16330 return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, true);15756 return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, true);
...@@ -16343,7 +15769,6 @@ fn analyzeCmpUnionTag(...@@ -16343,7 +15769,6 @@ fn analyzeCmpUnionTag(
16343 const pt = sema.pt;15769 const pt = sema.pt;
16344 const zcu = pt.zcu;15770 const zcu = pt.zcu;
16345 const union_ty = sema.typeOf(un);15771 const union_ty = sema.typeOf(un);
16346 try union_ty.resolveFields(pt);
16347 const union_tag_ty = union_ty.unionTagType(zcu) orelse {15772 const union_tag_ty = union_ty.unionTagType(zcu) orelse {
16348 const msg = msg: {15773 const msg = msg: {
16349 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});15774 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(...@@ -16358,10 +15783,10 @@ fn analyzeCmpUnionTag(
16358 const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src);15783 const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src);
16359 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);15784 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| {
16362 if (enum_val.isUndef(zcu)) return .undef_bool;15787 if (enum_val.isUndef(zcu)) return .undef_bool;
16363 const field_ty = union_ty.unionFieldType(enum_val, zcu).?;15788 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) {
16365 return .bool_false;15790 return .bool_false;
16366 }15791 }
16367 }15792 }
...@@ -16384,8 +15809,8 @@ fn zirCmp(...@@ -16384,8 +15809,8 @@ fn zirCmp(
16384 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);15809 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
16385 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15810 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
16386 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });15811 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
16387 const lhs = try sema.resolveInst(extra.lhs);15812 const lhs = sema.resolveInst(extra.lhs);
16388 const rhs = try sema.resolveInst(extra.rhs);15813 const rhs = sema.resolveInst(extra.rhs);
16389 return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, false);15814 return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, false);
16390}15815}
1639115816
...@@ -16468,8 +15893,8 @@ fn cmpSelf(...@@ -16468,8 +15893,8 @@ fn cmpSelf(
16468 const zcu = pt.zcu;15893 const zcu = pt.zcu;
16469 const resolved_type = sema.typeOf(casted_lhs);15894 const resolved_type = sema.typeOf(casted_lhs);
1647015895
16471 const maybe_lhs_val = try sema.resolveValue(casted_lhs);15896 const maybe_lhs_val = sema.resolveValue(casted_lhs);
16472 const maybe_rhs_val = try sema.resolveValue(casted_rhs);15897 const maybe_rhs_val = sema.resolveValue(casted_rhs);
16473 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;15898 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
16474 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;15899 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
1647515900
...@@ -16534,42 +15959,26 @@ fn runtimeBoolCmp(...@@ -16534,42 +15959,26 @@ fn runtimeBoolCmp(
1653415959
16535fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15960fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
16536 const pt = sema.pt;15961 const pt = sema.pt;
15962 const zcu = pt.zcu;
16537 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;15963 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
16538 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);15964 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
16539 const ty = try sema.resolveType(block, operand_src, inst_data.operand);15965 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
16540 switch (ty.zigTypeTag(pt.zcu)) {15966 try sema.ensureLayoutResolved(ty, operand_src, .size_of);
16541 .@"fn",15967 switch (ty.classify(zcu)) {
16542 .noreturn,15968 .no_possible_value,
16543 .undefined,15969 => return sema.fail(block, operand_src, "no size available for uninstantiable type '{f}'", .{ty.fmt(pt)}),
16544 .null,
16545 .@"opaque",
16546 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{ty.fmt(pt)}),
1654715970
16548 .type,15971 .partially_comptime,
16549 .enum_literal,15972 .fully_comptime,
16550 .comptime_float,15973 => return sema.fail(block, operand_src, "no size available for comptime-only type '{f}'", .{ty.fmt(pt)}),
16551 .comptime_int,
16552 .void,
16553 => return .zero,
1655415974
16555 .bool,15975 .one_possible_value => {
16556 .int,15976 assert(ty.abiSize(zcu) == 0);
16557 .float,15977 return .zero;
16558 .pointer,15978 },
16559 .array,15979
16560 .@"struct",15980 .runtime => return .fromValue(try pt.intValue(.comptime_int, ty.abiSize(zcu))),
16561 .optional,
16562 .error_union,
16563 .error_set,
16564 .@"enum",
16565 .@"union",
16566 .vector,
16567 .frame,
16568 .@"anyframe",
16569 => {},
16570 }15981 }
16571 const val = try ty.abiSizeLazy(pt);
16572 return Air.internedToRef(val.toIntern());
16573}15982}
1657415983
16575fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15984fn 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...@@ -16584,12 +15993,12 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
16584 .undefined,15993 .undefined,
16585 .null,15994 .null,
16586 .@"opaque",15995 .@"opaque",
16587 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{operand_ty.fmt(pt)}),
16588
16589 .type,15996 .type,
16590 .enum_literal,15997 .enum_literal,
16591 .comptime_float,15998 .comptime_float,
16592 .comptime_int,15999 .comptime_int,
16000 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{operand_ty.fmt(pt)}),
16001
16593 .void,16002 .void,
16594 => return .zero,16003 => return .zero,
1659516004
...@@ -16609,8 +16018,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -16609,8 +16018,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
16609 .@"anyframe",16018 .@"anyframe",
16610 => {},16019 => {},
16611 }16020 }
16612 const bit_size = try operand_ty.bitSizeSema(pt);16021 try sema.ensureLayoutResolved(operand_ty, operand_src, .size_of);
16613 return pt.intRef(.comptime_int, bit_size);16022 return .fromValue(try pt.intValue(.comptime_int, operand_ty.bitSize(zcu)));
16614}16023}
1661516024
16616fn zirThis(16025fn zirThis(
...@@ -16619,34 +16028,7 @@ fn zirThis(...@@ -16619,34 +16028,7 @@ fn zirThis(
16619 extended: Zir.Inst.Extended.InstData,16028 extended: Zir.Inst.Extended.InstData,
16620) CompileError!Air.Inst.Ref {16029) CompileError!Air.Inst.Ref {
16621 _ = extended;16030 _ = extended;
16622 const pt = sema.pt;16031 return .fromIntern(sema.pt.zcu.namespacePtr(block.namespace).owner_type);
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 }
16650}16032}
1665116033
16652fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {16034fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
...@@ -16739,7 +16121,7 @@ fn zirRetAddr(...@@ -16739,7 +16121,7 @@ fn zirRetAddr(
16739 _ = sema;16121 _ = sema;
16740 _ = extended;16122 _ = extended;
16741 if (block.isComptime()) {16123 if (block.isComptime()) {
16742 // TODO: we could give a meaningful lazy value here. #1493816124 // TODO: we could give a meaningful value here. #14938
16743 return .zero_usize;16125 return .zero_usize;
16744 } else {16126 } else {
16745 return block.addNoOp(.ret_addr);16127 return block.addNoOp(.ret_addr);
...@@ -16882,6 +16264,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16882,6 +16264,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16882 const type_info_ty = try sema.getBuiltinType(src, .Type);16264 const type_info_ty = try sema.getBuiltinType(src, .Type);
16883 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;16265 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1688416266
16267 try sema.ensureLayoutResolved(ty, src, .type_info);
16268
16885 if (ty.typeDeclInst(zcu)) |type_decl_inst| {16269 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
16886 try sema.declareDependency(.{ .namespace = type_decl_inst });16270 try sema.declareDependency(.{ .namespace = type_decl_inst });
16887 }16271 }
...@@ -16896,7 +16280,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16896,7 +16280,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16896 .undefined,16280 .undefined,
16897 .null,16281 .null,
16898 .enum_literal,16282 .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
16901 .@"fn" => {16292 .@"fn" => {
16902 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");16293 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...@@ -16904,19 +16295,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1690416295
16905 const func_ty_info = zcu.typeToFunc(ty).?;16296 const func_ty_info = zcu.typeToFunc(ty).?;
16906 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);16297 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
16907 for (param_vals, 0..) |*param_val, i| {16298 var func_is_generic = false;
16908 const param_ty = func_ty_info.param_types.get(ip)[i];16299
16300 for (param_vals, 0..) |*param_val, param_index| {
16301 const param_ty = func_ty_info.param_types.get(ip)[param_index];
16909 const is_generic = param_ty == .generic_poison_type;16302 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
16910 const param_ty_val = try pt.intern(.{ .opt = .{16312 const param_ty_val = try pt.intern(.{ .opt = .{
16911 .ty = try pt.intern(.{ .opt_type = .type_type }),16313 .ty = try pt.intern(.{ .opt_type = .type_type }),
16912 .val = if (is_generic) .none else param_ty,16314 .val = if (is_generic) .none else param_ty,
16913 } });16315 } });
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
16920 const param_fields = .{16317 const param_fields = .{
16921 // is_generic: bool,16318 // is_generic: bool,
16922 Value.makeBool(is_generic).toIntern(),16319 Value.makeBool(is_generic).toIntern(),
...@@ -16934,7 +16331,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16934,7 +16331,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16934 .child = param_info_ty.toIntern(),16331 .child = param_info_ty.toIntern(),
16935 });16332 });
16936 const new_decl_val = (try pt.aggregateValue(new_decl_ty, param_vals)).toIntern();16333 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(.{
16938 .child = param_info_ty.toIntern(),16335 .child = param_info_ty.toIntern(),
16939 .flags = .{16336 .flags = .{
16940 .size = .slice,16337 .size = .slice,
...@@ -16956,18 +16353,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16956,18 +16353,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16956 } });16353 } });
16957 };16354 };
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
16959 const ret_ty_opt = try pt.intern(.{ .opt = .{16370 const ret_ty_opt = try pt.intern(.{ .opt = .{
16960 .ty = try pt.intern(.{ .opt_type = .type_type }),16371 .ty = try pt.intern(.{ .opt_type = .type_type }),
16961 .val = opt_val: {16372 .val = if (ret_ty_is_generic) .none else func_ty_info.return_type,
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 },
16971 } });16373 } });
1697216374
16973 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);16375 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
...@@ -16980,7 +16382,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16980,7 +16382,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16980 // calling_convention: CallingConvention,16382 // calling_convention: CallingConvention,
16981 callconv_val.toIntern(),16383 callconv_val.toIntern(),
16982 // is_generic: bool,16384 // is_generic: bool,
16983 Value.makeBool(func_ty_info.is_generic).toIntern(),16385 Value.makeBool(func_is_generic).toIntern(),
16984 // is_var_args: bool,16386 // is_var_args: bool,
16985 Value.makeBool(func_ty_info.is_var_args).toIntern(),16387 Value.makeBool(func_ty_info.is_var_args).toIntern(),
16986 // return_type: ?type,16388 // return_type: ?type,
...@@ -17015,7 +16417,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17015,7 +16417,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1701516417
17016 const field_vals = .{16418 const field_vals = .{
17017 // bits: u16,16419 // bits: u16,
17018 (try pt.intValue(.u16, ty.bitSize(zcu))).toIntern(),16420 (try pt.intValue(.u16, ty.floatBits(zcu.getTarget()))).toIntern(),
17019 };16421 };
17020 return Air.internedToRef((try pt.internUnion(.{16422 return Air.internedToRef((try pt.internUnion(.{
17021 .ty = type_info_ty.toIntern(),16423 .ty = type_info_ty.toIntern(),
...@@ -17025,10 +16427,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17025,10 +16427,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17025 },16427 },
17026 .pointer => {16428 .pointer => {
17027 const info = ty.ptrInfo(zcu);16429 const info = ty.ptrInfo(zcu);
17028 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|16430 const alignment_ty = try pt.optionalType(.usize_type);
17029 try pt.intValue(.comptime_int, alignment)16431 const alignment_val: Value = val: {
17030 else16432 const bytes = info.flags.alignment.toByteUnits() orelse {
17031 try Type.fromInterned(info.child).lazyAbiAlignment(pt);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
17033 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);16442 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
17034 const pointer_ty = try sema.getBuiltinType(src, .@"Type.Pointer");16443 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...@@ -17041,8 +16450,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17041 Value.makeBool(info.flags.is_const).toIntern(),16450 Value.makeBool(info.flags.is_const).toIntern(),
17042 // is_volatile: bool,16451 // is_volatile: bool,
17043 Value.makeBool(info.flags.is_volatile).toIntern(),16452 Value.makeBool(info.flags.is_volatile).toIntern(),
17044 // alignment: comptime_int,16453 // alignment: ?usize,
17045 alignment.toIntern(),16454 alignment_val.toIntern(),
17046 // address_space: AddressSpace16455 // address_space: AddressSpace
17047 (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),16456 (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),
17048 // child: type,16457 // child: type,
...@@ -17159,7 +16568,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17159,7 +16568,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17159 };16568 };
1716016569
17161 // Build our ?[]const Error value16570 // Build our ?[]const Error value
17162 const slice_errors_ty = try pt.ptrTypeSema(.{16571 const slice_errors_ty = try pt.ptrType(.{
17163 .child = error_field_ty.toIntern(),16572 .child = error_field_ty.toIntern(),
17164 .flags = .{16573 .flags = .{
17165 .size = .slice,16574 .size = .slice,
...@@ -17215,19 +16624,19 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17215,19 +16624,19 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17215 })));16624 })));
17216 },16625 },
17217 .@"enum" => {16626 .@"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
17220 const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField");16630 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);
17223 for (enum_field_vals, 0..) |*field_val, tag_index| {16633 for (enum_field_vals, 0..) |*field_val, tag_index| {
17224 const enum_type = ip.loadEnumType(ty.toIntern());16634 const value_val = if (enum_obj.field_values.len > 0)
17225 const value_val = if (enum_type.values.len > 0)
17226 try ip.getCoercedInts(16635 try ip.getCoercedInts(
17227 gpa,16636 gpa,
17228 io,16637 io,
17229 pt.tid,16638 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,
17231 .comptime_int_type,16640 .comptime_int_type,
17232 )16641 )
17233 else16642 else
...@@ -17235,7 +16644,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17235,7 +16644,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1723516644
17236 // TODO: write something like getCoercedInts to avoid needing to dupe16645 // TODO: write something like getCoercedInts to avoid needing to dupe
17237 const name_val = v: {16646 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];
17239 const tag_name_len = tag_name.length(ip);16648 const tag_name_len = tag_name.length(ip);
17240 const new_decl_ty = try pt.arrayType(.{16649 const new_decl_ty = try pt.arrayType(.{
17241 .len = tag_name_len,16650 .len = tag_name_len,
...@@ -17275,7 +16684,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17275,7 +16684,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17275 .child = enum_field_ty.toIntern(),16684 .child = enum_field_ty.toIntern(),
17276 });16685 });
17277 const new_decl_val = (try pt.aggregateValue(fields_array_ty, enum_field_vals)).toIntern();16686 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(.{
17279 .child = enum_field_ty.toIntern(),16688 .child = enum_field_ty.toIntern(),
17280 .flags = .{16689 .flags = .{
17281 .size = .slice,16690 .size = .slice,
...@@ -17303,7 +16712,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17303,7 +16712,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1730316712
17304 const field_values = .{16713 const field_values = .{
17305 // tag_type: type,16714 // tag_type: type,
17306 ip.loadEnumType(ty.toIntern()).tag_ty,16715 ip.loadEnumType(ty.toIntern()).int_tag_type,
17307 // fields: []const EnumField,16716 // fields: []const EnumField,
17308 fields_val,16717 fields_val,
17309 // decls: []const Declaration,16718 // decls: []const Declaration,
...@@ -17321,17 +16730,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17321,17 +16730,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17321 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");16730 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");
17322 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");16731 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");
1732316732
17324 try ty.resolveLayout(pt); // Getting alignment requires type layout16733 const union_obj = ip.loadUnionType(ty.toIntern());
17325 const union_obj = zcu.typeToUnion(ty).?;16734 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
17326 const tag_type = union_obj.loadTagType(ip);16735 const layout = union_obj.layout;
17327 const layout = union_obj.flagsUnordered(ip).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);
17330 defer gpa.free(union_field_vals);16738 defer gpa.free(union_field_vals);
1733116739
17332 for (union_field_vals, 0..) |*field_val, field_index| {16740 for (union_field_vals, 0..) |*field_val, field_index| {
17333 const name_val = v: {16741 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];
17335 const field_name_len = field_name.length(ip);16743 const field_name_len = field_name.length(ip);
17336 const new_decl_ty = try pt.arrayType(.{16744 const new_decl_ty = try pt.arrayType(.{
17337 .len = field_name_len,16745 .len = field_name_len,
...@@ -17356,19 +16764,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17356,19 +16764,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17356 } });16764 } });
17357 };16765 };
1735816766
17359 const alignment = switch (layout) {16767 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
17360 .auto, .@"extern" => try ty.fieldAlignmentSema(field_index, pt),16768
17361 .@"packed" => .none,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 } }));
17362 };16783 };
1736316784
17364 const field_ty = union_obj.field_types.get(ip)[field_index];
17365 const union_field_fields = .{16785 const union_field_fields = .{
17366 // name: [:0]const u8,16786 // name: [:0]const u8,
17367 name_val,16787 name_val,
17368 // type: type,16788 // type: type,
17369 field_ty,16789 field_ty.toIntern(),
17370 // alignment: comptime_int,16790 // alignment: ?usize,
17371 (try pt.intValue(.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),16791 alignment_val.toIntern(),
17372 };16792 };
17373 field_val.* = (try pt.aggregateValue(union_field_ty, &union_field_fields)).toIntern();16793 field_val.* = (try pt.aggregateValue(union_field_ty, &union_field_fields)).toIntern();
17374 }16794 }
...@@ -17379,7 +16799,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17379,7 +16799,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17379 .child = union_field_ty.toIntern(),16799 .child = union_field_ty.toIntern(),
17380 });16800 });
17381 const new_decl_val = (try pt.aggregateValue(array_fields_ty, union_field_vals)).toIntern();16801 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(.{
17383 .child = union_field_ty.toIntern(),16803 .child = union_field_ty.toIntern(),
17384 .flags = .{16804 .flags = .{
17385 .size = .slice,16805 .size = .slice,
...@@ -17431,8 +16851,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17431,8 +16851,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17431 const type_struct_ty = try sema.getBuiltinType(src, .@"Type.Struct");16851 const type_struct_ty = try sema.getBuiltinType(src, .@"Type.Struct");
17432 const struct_field_ty = try sema.getBuiltinType(src, .@"Type.StructField");16852 const struct_field_ty = try sema.getBuiltinType(src, .@"Type.StructField");
1743316853
17434 try ty.resolveLayout(pt); // Getting alignment requires type layout
17435
17436 var struct_field_vals: []InternPool.Index = &.{};16854 var struct_field_vals: []InternPool.Index = &.{};
17437 defer gpa.free(struct_field_vals);16855 defer gpa.free(struct_field_vals);
17438 fv: {16856 fv: {
...@@ -17468,11 +16886,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17468,11 +16886,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17468 } });16886 } });
17469 };16887 };
1747016888
17471 try Type.fromInterned(field_ty).resolveLayout(pt);
17472
17473 const is_comptime = field_val != .none;16889 const is_comptime = field_val != .none;
17474 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;16890 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;
17475 const default_val_ptr = try sema.optRefValue(opt_default_val);16891 const default_val_ptr = try sema.optRefValue(opt_default_val);
16892
17476 const struct_field_fields = .{16893 const struct_field_fields = .{
17477 // name: [:0]const u8,16894 // name: [:0]const u8,
17478 name_val,16895 name_val,
...@@ -17482,8 +16899,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17482,8 +16899,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17482 default_val_ptr.toIntern(),16899 default_val_ptr.toIntern(),
17483 // is_comptime: bool,16900 // is_comptime: bool,
17484 Value.makeBool(is_comptime).toIntern(),16901 Value.makeBool(is_comptime).toIntern(),
17485 // alignment: comptime_int,16902 // alignment: ?usize,
17486 (try pt.intValue(.comptime_int, Type.fromInterned(field_ty).abiAlignment(zcu).toByteUnits() orelse 0)).toIntern(),16903 (try pt.nullValue(try pt.optionalType(.usize_type))).toIntern(),
17487 };16904 };
17488 struct_field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern();16905 struct_field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern();
17489 }16906 }
...@@ -17492,16 +16909,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17492,16 +16909,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17492 .struct_type => ip.loadStructType(ty.toIntern()),16909 .struct_type => ip.loadStructType(ty.toIntern()),
17493 else => unreachable,16910 else => unreachable,
17494 };16911 };
16912 try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples
17495 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);16913 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1749616914
17497 try ty.resolveStructFieldInits(pt);
17498
17499 for (struct_field_vals, 0..) |*field_val, field_index| {16915 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];
17501 const field_name_len = field_name.length(ip);16917 const field_name_len = field_name.length(ip);
17502 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);16918 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
17503 const field_init = struct_type.fieldInit(ip, field_index);16919 const field_default: InternPool.Index = if (struct_type.field_defaults.len > 0) d: {
17504 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);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);
17505 const name_val = v: {16923 const name_val = v: {
17506 const new_decl_ty = try pt.arrayType(.{16924 const new_decl_ty = try pt.arrayType(.{
17507 .len = field_name_len,16925 .len = field_name_len,
...@@ -17526,15 +16944,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17526,15 +16944,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17526 } });16944 } });
17527 };16945 };
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);
17530 const default_val_ptr = try sema.optRefValue(opt_default_val);16948 const default_val_ptr = try sema.optRefValue(opt_default_val);
17531 const alignment = switch (struct_type.layout) {16949
17532 .@"packed" => .none,16950 const alignment_ty = try pt.optionalType(.usize_type);
17533 else => try field_ty.structFieldAlignmentSema(16951 const alignment_val: Value = val: {
17534 struct_type.fieldAlign(ip, field_index),16952 const a: Alignment = switch (struct_type.layout) {
17535 struct_type.layout,16953 .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu),
17536 pt,16954 .@"packed" => .none,
17537 ),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 } }));
17538 };16964 };
1753916965
17540 const struct_field_fields = .{16966 const struct_field_fields = .{
...@@ -17546,8 +16972,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17546,8 +16972,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17546 default_val_ptr.toIntern(),16972 default_val_ptr.toIntern(),
17547 // is_comptime: bool,16973 // is_comptime: bool,
17548 Value.makeBool(field_is_comptime).toIntern(),16974 Value.makeBool(field_is_comptime).toIntern(),
17549 // alignment: comptime_int,16975 // alignment: ?usize,
17550 (try pt.intValue(.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),16976 alignment_val.toIntern(),
17551 };16977 };
17552 field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern();16978 field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern();
17553 }16979 }
...@@ -17559,7 +16985,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17559,7 +16985,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17559 .child = struct_field_ty.toIntern(),16985 .child = struct_field_ty.toIntern(),
17560 });16986 });
17561 const new_decl_val = (try pt.aggregateValue(array_fields_ty, struct_field_vals)).toIntern();16987 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(.{
17563 .child = struct_field_ty.toIntern(),16989 .child = struct_field_ty.toIntern(),
17564 .flags = .{16990 .flags = .{
17565 .size = .slice,16991 .size = .slice,
...@@ -17585,9 +17011,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17585,9 +17011,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1758517011
17586 const backing_integer_val = try pt.intern(.{ .opt = .{17012 const backing_integer_val = try pt.intern(.{ .opt = .{
17587 .ty = (try pt.optionalType(.type_type)).toIntern(),17013 .ty = (try pt.optionalType(.type_type)).toIntern(),
17588 .val = if (zcu.typeToPackedStruct(ty)) |packed_struct| val: {17014 .val = if (zcu.typeToPackedStruct(ty)) |struct_obj| val: {
17589 assert(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)).isInt(zcu));17015 assert(Type.fromInterned(struct_obj.packed_backing_int_type).isInt(zcu));
17590 break :val packed_struct.backingIntTypeUnordered(ip);17016 break :val struct_obj.packed_backing_int_type;
17591 } else .none,17017 } else .none,
17592 } });17018 } });
1759317019
...@@ -17616,7 +17042,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17616,7 +17042,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17616 .@"opaque" => {17042 .@"opaque" => {
17617 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");17043 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1761817044
17619 try ty.resolveFields(pt);
17620 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));17045 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));
1762117046
17622 const field_values = .{17047 const field_values = .{
...@@ -17658,7 +17083,7 @@ fn typeInfoDecls(...@@ -17658,7 +17083,7 @@ fn typeInfoDecls(
17658 .child = declaration_ty.toIntern(),17083 .child = declaration_ty.toIntern(),
17659 });17084 });
17660 const new_decl_val = (try pt.aggregateValue(array_decl_ty, decl_vals.items)).toIntern();17085 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(.{
17662 .child = declaration_ty.toIntern(),17087 .child = declaration_ty.toIntern(),
17663 .flags = .{17088 .flags = .{
17664 .size = .slice,17089 .size = .slice,
...@@ -17740,7 +17165,7 @@ fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -17740,7 +17165,7 @@ fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
17740 _ = block;17165 _ = block;
17741 const zir_datas = sema.code.instructions.items(.data);17166 const zir_datas = sema.code.instructions.items(.data);
17742 const inst_data = zir_datas[@intFromEnum(inst)].un_node;17167 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);
17744 const operand_ty = sema.typeOf(operand);17169 const operand_ty = sema.typeOf(operand);
17745 return Air.internedToRef(operand_ty.toIntern());17170 return Air.internedToRef(operand_ty.toIntern());
17746}17171}
...@@ -17754,7 +17179,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -17754,7 +17179,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
17754 .parent = block,17179 .parent = block,
17755 .sema = sema,17180 .sema = sema,
17756 .namespace = block.namespace,17181 .namespace = block.namespace,
17757 .instructions = .{},17182 .instructions = .empty,
17758 .inlining = block.inlining,17183 .inlining = block.inlining,
17759 .comptime_reason = null,17184 .comptime_reason = null,
17760 .is_typeof = true,17185 .is_typeof = true,
...@@ -17772,7 +17197,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -17772,7 +17197,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
17772fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17197fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17773 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17198 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17774 const src = block.nodeOffset(inst_data.src_node);17199 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);
17776 const operand_ty = sema.typeOf(operand);17201 const operand_ty = sema.typeOf(operand);
17777 const res_ty = try sema.log2IntType(block, operand_ty, src);17202 const res_ty = try sema.log2IntType(block, operand_ty, src);
17778 return Air.internedToRef(res_ty.toIntern());17203 return Air.internedToRef(res_ty.toIntern());
...@@ -17783,22 +17208,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -17783,22 +17208,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
17783 const zcu = pt.zcu;17208 const zcu = pt.zcu;
17784 switch (operand.zigTypeTag(zcu)) {17209 switch (operand.zigTypeTag(zcu)) {
17785 .comptime_int => return .comptime_int,17210 .comptime_int => return .comptime_int,
17786 .int => {17211 .int => return pt.intType(.unsigned, switch (operand.intInfo(zcu).bits) {
17787 const bits = operand.bitSize(zcu);17212 0 => 0,
17788 const count = if (bits == 0)17213 else => |b| std.math.log2_int_ceil(u16, b),
17789 017214 }),
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 },
17800 .vector => {17215 .vector => {
17801 const elem_ty = operand.elemType2(zcu);17216 const elem_ty = operand.childType(zcu);
17802 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);17217 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
17803 return pt.vectorType(.{17218 return pt.vectorType(.{
17804 .len = operand.vectorLen(zcu),17219 .len = operand.vectorLen(zcu),
...@@ -17832,7 +17247,7 @@ fn zirTypeofPeer(...@@ -17832,7 +17247,7 @@ fn zirTypeofPeer(
17832 .parent = block,17247 .parent = block,
17833 .sema = sema,17248 .sema = sema,
17834 .namespace = block.namespace,17249 .namespace = block.namespace,
17835 .instructions = .{},17250 .instructions = .empty,
17836 .inlining = block.inlining,17251 .inlining = block.inlining,
17837 .comptime_reason = null,17252 .comptime_reason = null,
17838 .is_typeof = true,17253 .is_typeof = true,
...@@ -17852,7 +17267,7 @@ fn zirTypeofPeer(...@@ -17852,7 +17267,7 @@ fn zirTypeofPeer(
17852 defer sema.gpa.free(inst_list);17267 defer sema.gpa.free(inst_list);
1785317268
17854 for (args, 0..) |arg_ref, i| {17269 for (args, 0..) |arg_ref, i| {
17855 inst_list[i] = try sema.resolveInst(arg_ref);17270 inst_list[i] = sema.resolveInst(arg_ref);
17856 }17271 }
1785717272
17858 const result_type = try sema.resolvePeerTypes(block, src, inst_list, .{ .typeof_builtin_call_node_offset = extra.data.src_node });17273 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...@@ -17865,7 +17280,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17865 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17280 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17866 const src = block.nodeOffset(inst_data.src_node);17281 const src = block.nodeOffset(inst_data.src_node);
17867 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });17282 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);
17869 const uncasted_ty = sema.typeOf(uncasted_operand);17284 const uncasted_ty = sema.typeOf(uncasted_operand);
17870 if (uncasted_ty.isVector(zcu)) {17285 if (uncasted_ty.isVector(zcu)) {
17871 if (uncasted_ty.scalarType(zcu).zigTypeTag(zcu) != .bool) {17286 if (uncasted_ty.scalarType(zcu).zigTypeTag(zcu) != .bool) {
...@@ -17876,7 +17291,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17876,7 +17291,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17876 return analyzeBitNot(sema, block, uncasted_operand, src);17291 return analyzeBitNot(sema, block, uncasted_operand, src);
17877 }17292 }
17878 const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src);17293 const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src);
17879 if (try sema.resolveValue(operand)) |val| {17294 if (sema.resolveValue(operand)) |val| {
17880 return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true;17295 return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true;
17881 }17296 }
17882 try sema.requireRuntimeBlock(block, src, null);17297 try sema.requireRuntimeBlock(block, src, null);
...@@ -17900,7 +17315,7 @@ fn zirBoolBr(...@@ -17900,7 +17315,7 @@ fn zirBoolBr(
17900 const inst_data = datas[@intFromEnum(inst)].pl_node;17315 const inst_data = datas[@intFromEnum(inst)].pl_node;
17901 const extra = sema.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index);17316 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);
17904 const body = sema.code.bodySlice(extra.end, extra.data.body_len);17319 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
17905 const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });17320 const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
17906 const rhs_src = parent_block.src(.{ .node_offset_bin_rhs = inst_data.src_node });17321 const rhs_src = parent_block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
...@@ -18063,9 +17478,9 @@ fn zirIsNonNull(...@@ -18063,9 +17478,9 @@ fn zirIsNonNull(
1806317478
18064 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17479 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18065 const src = block.nodeOffset(inst_data.src_node);17480 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);
18067 try sema.checkNullableType(block, src, sema.typeOf(operand));17482 try sema.checkNullableType(block, src, sema.typeOf(operand));
18068 return sema.analyzeIsNull(block, operand, true);17483 return sema.analyzeIsNull(block, src, operand, true);
18069}17484}
1807017485
18071fn zirIsNonNullPtr(17486fn zirIsNonNullPtr(
...@@ -18080,17 +17495,23 @@ fn zirIsNonNullPtr(...@@ -18080,17 +17495,23 @@ fn zirIsNonNullPtr(
18080 const zcu = pt.zcu;17495 const zcu = pt.zcu;
18081 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17496 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18082 const src = block.nodeOffset(inst_data.src_node);17497 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);
18084 const ptr_ty = sema.typeOf(ptr);17499 const ptr_ty = sema.typeOf(ptr);
18085 try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2(zcu));17500 assert(ptr_ty.zigTypeTag(zcu) == .pointer);
18086 if (try sema.resolveValue(ptr)) |ptr_val| {17501 const nullable_ty = ptr_ty.childType(zcu);
18087 if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |loaded_val| {17502
18088 return sema.analyzeIsNull(block, Air.internedToRef(loaded_val.toIntern()), true);17503 try sema.checkNullableType(block, src, nullable_ty);
18089 }17504
17505 if (try sema.resolveIsNullFromType(block, src, nullable_ty)) |is_null| {
17506 return .fromValue(.makeBool(!is_null));
18090 }17507 }
18091 if (ptr_ty.childType(zcu).isNullFromType(zcu)) |is_null| {17508
18092 return if (is_null) .bool_false else .bool_true;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 }
18093 }17513 }
17514
18094 return block.addUnOp(.is_non_null_ptr, ptr);17515 return block.addUnOp(.is_non_null_ptr, ptr);
18095}17516}
1809617517
...@@ -18111,7 +17532,7 @@ fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18111,7 +17532,7 @@ fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1811117532
18112 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17533 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18113 const src = block.nodeOffset(inst_data.src_node);17534 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);
18115 try sema.checkErrorType(block, src, sema.typeOf(operand));17536 try sema.checkErrorType(block, src, sema.typeOf(operand));
18116 return sema.analyzeIsNonErr(block, src, operand);17537 return sema.analyzeIsNonErr(block, src, operand);
18117}17538}
...@@ -18124,8 +17545,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -18124,8 +17545,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
18124 const zcu = pt.zcu;17545 const zcu = pt.zcu;
18125 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17546 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18126 const src = block.nodeOffset(inst_data.src_node);17547 const src = block.nodeOffset(inst_data.src_node);
18127 const ptr = try sema.resolveInst(inst_data.operand);17548 const ptr = sema.resolveInst(inst_data.operand);
18128 try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2(zcu));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);
18129 const loaded = try sema.analyzeLoad(block, src, ptr, src);17553 const loaded = try sema.analyzeLoad(block, src, ptr, src);
18130 return sema.analyzeIsNonErr(block, src, loaded);17554 return sema.analyzeIsNonErr(block, src, loaded);
18131}17555}
...@@ -18136,7 +17560,7 @@ fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -18136,7 +17560,7 @@ fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1813617560
18137 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17561 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18138 const src = block.nodeOffset(inst_data.src_node);17562 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);
18140 return sema.analyzeIsNonErr(block, src, operand);17564 return sema.analyzeIsNonErr(block, src, operand);
18141}17565}
1814217566
...@@ -18157,7 +17581,7 @@ fn zirCondbr(...@@ -18157,7 +17581,7 @@ fn zirCondbr(
18157 const then_body = sema.code.bodySlice(extra.end, extra.data.then_body_len);17581 const then_body = sema.code.bodySlice(extra.end, extra.data.then_body_len);
18158 const else_body = sema.code.bodySlice(extra.end + then_body.len, extra.data.else_body_len);17582 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);
18161 const cond = try sema.coerce(parent_block, .bool, uncasted_cond, cond_src);17585 const cond = try sema.coerce(parent_block, .bool, uncasted_cond, cond_src);
1816217586
18163 if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| {17587 if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| {
...@@ -18193,7 +17617,7 @@ fn zirCondbr(...@@ -18193,7 +17617,7 @@ fn zirCondbr(
18193 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) break :blk null;17617 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) break :blk null;
1819417618
18195 const err_inst_data = sema.code.instructions.items(.data)[@intFromEnum(index)].un_node;17619 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);
18197 const operand_ty = sema.typeOf(err_operand);17621 const operand_ty = sema.typeOf(err_operand);
18198 assert(operand_ty.zigTypeTag(zcu) == .error_union);17622 assert(operand_ty.zigTypeTag(zcu) == .error_union);
18199 const result_ty = operand_ty.errorUnionSet(zcu);17623 const result_ty = operand_ty.errorUnionSet(zcu);
...@@ -18241,7 +17665,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -18241,7 +17665,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
18241 const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node });17665 const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node });
18242 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);17666 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
18243 const body = sema.code.bodySlice(extra.end, extra.data.body_len);17667 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);
18245 const err_union_ty = sema.typeOf(err_union);17669 const err_union_ty = sema.typeOf(err_union);
18246 const pt = sema.pt;17670 const pt = sema.pt;
18247 const zcu = pt.zcu;17671 const zcu = pt.zcu;
...@@ -18294,6 +17718,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -18294,6 +17718,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
18294 } },17718 } },
18295 });17719 });
18296 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));17720 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
18297 return try_inst;17726 return try_inst;
18298}17727}
1829917728
...@@ -18303,7 +17732,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -18303,7 +17732,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
18303 const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node });17732 const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node });
18304 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);17733 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
18305 const body = sema.code.bodySlice(extra.end, extra.data.body_len);17734 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);
18307 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);17736 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);
18308 const err_union_ty = sema.typeOf(err_union);17737 const err_union_ty = sema.typeOf(err_union);
18309 const pt = sema.pt;17738 const pt = sema.pt;
...@@ -18347,7 +17776,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -18347,7 +17776,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1834717776
18348 const operand_ty = sema.typeOf(operand);17777 const operand_ty = sema.typeOf(operand);
18349 const ptr_info = operand_ty.ptrInfo(zcu);17778 const ptr_info = operand_ty.ptrInfo(zcu);
18350 const res_ty = try pt.ptrTypeSema(.{17779 const res_ty = try pt.ptrType(.{
18351 .child = err_union_ty.errorUnionPayload(zcu).toIntern(),17780 .child = err_union_ty.errorUnionPayload(zcu).toIntern(),
18352 .flags = .{17781 .flags = .{
18353 .is_const = ptr_info.flags.is_const,17782 .is_const = ptr_info.flags.is_const,
...@@ -18396,9 +17825,9 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label...@@ -18396,9 +17825,9 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
18396 .label = .{17825 .label = .{
18397 .zir_block = dest_block,17826 .zir_block = dest_block,
18398 .merges = .{17827 .merges = .{
18399 .src_locs = .{},17828 .src_locs = .empty,
18400 .results = .{},17829 .results = .empty,
18401 .br_list = .{},17830 .br_list = .empty,
18402 .block_inst = new_block_inst,17831 .block_inst = new_block_inst,
18403 },17832 },
18404 },17833 },
...@@ -18406,7 +17835,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label...@@ -18406,7 +17835,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
18406 .parent = block,17835 .parent = block,
18407 .sema = sema,17836 .sema = sema,
18408 .namespace = block.namespace,17837 .namespace = block.namespace,
18409 .instructions = .{},17838 .instructions = .empty,
18410 .label = &labeled_block.label,17839 .label = &labeled_block.label,
18411 .inlining = block.inlining,17840 .inlining = block.inlining,
18412 .comptime_reason = block.comptime_reason,17841 .comptime_reason = block.comptime_reason,
...@@ -18424,7 +17853,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label...@@ -18424,7 +17853,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
18424fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void {17853fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void {
18425 const labeled_block = try sema.ensurePostHoc(child_block, block_inst);17854 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);
18428 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);17857 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);
1842917858
18430 try labeled_block.label.merges.results.append(sema.gpa, operand);17859 try labeled_block.label.merges.results.append(sema.gpa, operand);
...@@ -18510,9 +17939,9 @@ fn zirRetImplicit(...@@ -18510,9 +17939,9 @@ fn zirRetImplicit(
18510 return;17939 return;
18511 }17940 }
1851217941
18513 const operand = try sema.resolveInst(inst_data.operand);17942 const operand = sema.resolveInst(inst_data.operand);
18514 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = .zero });17943 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);
18516 if (base_tag == .noreturn) {17945 if (base_tag == .noreturn) {
18517 const msg = msg: {17946 const msg = msg: {
18518 const msg = try sema.errMsg(ret_ty_src, "function declared '{f}' implicitly returns", .{17947 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...@@ -18543,7 +17972,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
18543 defer tracy.end();17972 defer tracy.end();
1854417973
18545 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17974 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);
18547 const src = block.nodeOffset(inst_data.src_node);17976 const src = block.nodeOffset(inst_data.src_node);
1854817977
18549 return sema.analyzeRet(block, operand, src, block.src(.{ .node_offset_return_operand = inst_data.src_node }));17978 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...@@ -18555,7 +17984,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
1855517984
18556 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17985 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18557 const src = block.nodeOffset(inst_data.src_node);17986 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
18560 if (block.isComptime() or block.inlining != null or sema.func_is_naked) {17989 if (block.isComptime() or block.inlining != null or sema.func_is_naked) {
18561 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);17990 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...@@ -18652,7 +18081,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
18652 if (block.isComptime() or block.is_typeof) return;18081 if (block.isComptime() or block.is_typeof) return;
1865318082
18654 const save_index = inst_data.operand == .none or b: {18083 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);
18656 const operand_ty = sema.typeOf(operand);18085 const operand_ty = sema.typeOf(operand);
18657 break :b operand_ty.isError(zcu);18086 break :b operand_ty.isError(zcu);
18658 };18087 };
...@@ -18701,7 +18130,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -18701,7 +18130,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
18701 return; // No need to restore18130 return; // No need to restore
18702 };18131 };
1870318132
18704 const operand = try sema.resolveInstAllowNone(operand_zir);18133 const operand = sema.resolveInstAllowNone(operand_zir);
1870518134
18706 if (start_block.isComptime() or start_block.is_typeof) {18135 if (start_block.isComptime() or start_block.is_typeof) {
18707 const is_non_error = if (operand != .none) blk: {18136 const is_non_error = if (operand != .none) blk: {
...@@ -18809,8 +18238,6 @@ fn analyzeRet(...@@ -18809,8 +18238,6 @@ fn analyzeRet(
18809 return sema.failWithOwnedErrorMsg(block, msg);18238 return sema.failWithOwnedErrorMsg(block, msg);
18810 }18239 }
1881118240
18812 try sema.fn_ret_ty.resolveLayout(pt);
18813
18814 try sema.validateRuntimeValue(block, operand_src, operand);18241 try sema.validateRuntimeValue(block, operand_src, operand);
1881518242
18816 const air_tag: Air.Inst.Tag = if (block.wantSafety()) .ret_safe else .ret;18243 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...@@ -18853,8 +18280,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18853 const hostsize_src = block.src(.{ .node_offset_ptr_hostsize = extra.data.src_node });18280 const hostsize_src = block.src(.{ .node_offset_ptr_hostsize = extra.data.src_node });
1885418281
18855 const elem_ty = blk: {18282 const elem_ty = blk: {
18856 const air_inst = try sema.resolveInst(extra.data.elem_type);18283 const air_inst = sema.resolveInst(extra.data.elem_type);
18857 const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {18284 const ty = sema.analyzeAsType(block, elem_ty_src, .type, air_inst) catch |err| {
18858 if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(zcu)) {18285 if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(zcu)) {
18859 try sema.errNote(elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});18286 try sema.errNote(elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
18860 }18287 }
...@@ -18874,7 +18301,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18874,7 +18301,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18874 const sentinel = if (inst_data.flags.has_sentinel) blk: {18301 const sentinel = if (inst_data.flags.has_sentinel) blk: {
18875 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);18302 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
18876 extra_i += 1;18303 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);
18878 const val = try sema.resolveConstDefinedValue(block, sentinel_src, coerced, .{ .simple = .pointer_sentinel });18305 const val = try sema.resolveConstDefinedValue(block, sentinel_src, coerced, .{ .simple = .pointer_sentinel });
18879 try checkSentinelType(sema, block, sentinel_src, elem_ty);18306 try checkSentinelType(sema, block, sentinel_src, elem_ty);
18880 if (val.canMutateComptimeVarState(zcu)) {18307 if (val.canMutateComptimeVarState(zcu)) {
...@@ -18887,18 +18314,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18887,18 +18314,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18887 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {18314 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
18888 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);18315 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
18889 extra_i += 1;18316 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);
18891 const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" });18318 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, in18319 const align_bytes = val.toUnsignedInt(zcu);
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)).?;
18902 break :blk try sema.validateAlign(block, align_src, align_bytes);18320 break :blk try sema.validateAlign(block, align_src, align_bytes);
18903 } else .none;18321 } else .none;
1890418322
...@@ -18928,7 +18346,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18928,7 +18346,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18928 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,18346 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
18929 });18347 });
18930 }18348 }
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);
18932 if (elem_bit_size > host_size * 8 - bit_offset) {18351 if (elem_bit_size > host_size * 8 - bit_offset) {
18933 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", .{18352 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", .{
18934 elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,18353 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...@@ -18942,31 +18361,18 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18942 }18361 }
18943 } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") {18362 } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") {
18944 return sema.fail(block, elem_ty_src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)});18363 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 }
18958 }18364 }
1895918365
18960 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {18366 if (host_size != 0) {
18961 return sema.failWithOwnedErrorMsg(block, msg: {18367 if (elem_ty.unpackable(zcu)) |reason| return sema.failWithOwnedErrorMsg(block, msg: {
18962 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{f}'", .{elem_ty.fmt(pt)});18368 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{f}'", .{elem_ty.fmt(pt)});
18963 errdefer msg.destroy(sema.gpa);18369 errdefer msg.destroy(sema.gpa);
18964 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);18370 try sema.explainWhyTypeIsUnpackable(msg, elem_ty_src, reason);
18965 break :msg msg;18371 break :msg msg;
18966 });18372 });
18967 }18373 }
1896818374
18969 const ty = try pt.ptrTypeSema(.{18375 const ty = try pt.ptrType(.{
18970 .child = elem_ty.toIntern(),18376 .child = elem_ty.toIntern(),
18971 .sentinel = sentinel,18377 .sentinel = sentinel,
18972 .flags = .{18378 .flags = .{
...@@ -18996,6 +18402,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -18996,6 +18402,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
18996 const pt = sema.pt;18402 const pt = sema.pt;
18997 const zcu = pt.zcu;18403 const zcu = pt.zcu;
1899818404
18405 try sema.ensureLayoutResolved(obj_ty, ty_src, .init);
18406
18999 switch (obj_ty.zigTypeTag(zcu)) {18407 switch (obj_ty.zigTypeTag(zcu)) {
19000 .@"struct" => return sema.structInitEmpty(block, obj_ty, src, src),18408 .@"struct" => return sema.structInitEmpty(block, obj_ty, src, src),
19001 .array, .vector => return sema.arrayInitEmpty(block, src, obj_ty),18409 .array, .vector => return sema.arrayInitEmpty(block, src, obj_ty),
...@@ -19058,6 +18466,9 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19058,6 +18466,9 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
19058 .child = ptr_ty.childType(zcu).toIntern(),18466 .child = ptr_ty.childType(zcu).toIntern(),
19059 });18467 });
19060 } else ty_operand;18468 } else ty_operand;
18469
18470 try sema.ensureLayoutResolved(init_ty, src, .init);
18471
19061 const obj_ty = init_ty.optEuBaseType(zcu);18472 const obj_ty = init_ty.optEuBaseType(zcu);
1906218473
19063 const empty_ref = switch (obj_ty.zigTypeTag(zcu)) {18474 const empty_ref = switch (obj_ty.zigTypeTag(zcu)) {
...@@ -19069,13 +18480,13 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19069,13 +18480,13 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
19069 const init_ref = try sema.coerce(block, init_ty, empty_ref, src);18480 const init_ref = try sema.coerce(block, init_ty, empty_ref, src);
1907018481
19071 if (is_byref) {18482 if (is_byref) {
19072 const init_val = (try sema.resolveValue(init_ref)).?;18483 return sema.uavRef(sema.resolveValue(init_ref).?);
19073 return sema.uavRef(init_val.toIntern());
19074 } else {18484 } else {
19075 return init_ref;18485 return init_ref;
19076 }18486 }
19077}18487}
1907818488
18489/// Asserts that the layout of `struct_ty` is already resolved.
19079fn structInitEmpty(18490fn structInitEmpty(
19080 sema: *Sema,18491 sema: *Sema,
19081 block: *Block,18492 block: *Block,
...@@ -19087,7 +18498,7 @@ fn structInitEmpty(...@@ -19087,7 +18498,7 @@ fn structInitEmpty(
19087 const zcu = pt.zcu;18498 const zcu = pt.zcu;
19088 const gpa = sema.gpa;18499 const gpa = sema.gpa;
19089 // This logic must be synchronized with that in `zirStructInit`.18500 // This logic must be synchronized with that in `zirStructInit`.
19090 try struct_ty.resolveFields(pt);18501 struct_ty.assertHasLayout(zcu);
1909118502
19092 // The init values to use for the struct instance.18503 // The init values to use for the struct instance.
19093 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(zcu));18504 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...@@ -19118,63 +18529,36 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com
1911818529
19119fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {18530fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19120 const pt = sema.pt;18531 const pt = sema.pt;
18532 const zcu = pt.zcu;
18533 const ip = &zcu.intern_pool;
19121 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;18534 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
19122 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);18535 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
19123 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);18536 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);
19125 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;18538 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
19126 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);18539 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
19127 if (union_ty.zigTypeTag(pt.zcu) != .@"union") {18540 if (union_ty.zigTypeTag(pt.zcu) != .@"union") {
19128 return sema.fail(block, ty_src, "expected union type, found '{f}'", .{union_ty.fmt(pt)});18541 return sema.fail(block, ty_src, "expected union type, found '{f}'", .{union_ty.fmt(pt)});
19129 }18542 }
18543 union_ty.assertHasLayout(zcu); // from a previous `field_type_ref` instruction
19130 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .union_field_names });18544 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;
19148 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);18545 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
19149 const field_ty: Type = .fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);18546 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(18548 const payload = try sema.coerce(block, field_ty, sema.resolveInst(extra.init), payload_src);
19156 sema: *Sema,18549
19157 block: *Block,18550 if (union_ty.containerLayout(zcu) == .@"packed") {
19158 init_src: LazySrcLoc,18551 return sema.bitCast(block, union_ty, payload, block.nodeOffset(inst_data.src_node), payload_src);
19159 union_ty: Type,18552 }
19160 field_index: u32,
19161 init: Air.Inst.Ref,
19162) !Air.Inst.Ref {
19163 const pt = sema.pt;
19164 const zcu = pt.zcu;
1916518553
19166 if (try sema.resolveValue(init)) |init_val| {18554 if (sema.resolveValue(payload)) |payload_val| {
19167 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);18555 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
19168 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);18556 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
19169 return Air.internedToRef((try pt.internUnion(.{18557 return .fromValue(try pt.unionValue(union_ty, tag_val, payload_val));
19170 .ty = union_ty.toIntern(),
19171 .tag = tag_val.toIntern(),
19172 .val = init_val.toIntern(),
19173 })));
19174 }18558 }
1917518559
19176 try sema.requireRuntimeBlock(block, init_src, null);18560 try sema.requireRuntimeBlock(block, payload_src, null);
19177 return block.addUnionInit(union_ty, field_index, init);18561 return block.addUnionInit(union_ty, field_index, payload);
19178}18562}
1917918563
19180fn zirStructInit(18564fn zirStructInit(
...@@ -19202,8 +18586,8 @@ fn zirStructInit(...@@ -19202,8 +18586,8 @@ fn zirStructInit(
19202 // The type wasn't actually known, so treat this as an anon struct init.18586 // The type wasn't actually known, so treat this as an anon struct init.
19203 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);18587 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);
19204 };18588 };
18589 try sema.ensureLayoutResolved(result_ty, src, .init);
19205 const resolved_ty = result_ty.optEuBaseType(zcu);18590 const resolved_ty = result_ty.optEuBaseType(zcu);
19206 try resolved_ty.resolveLayout(pt);
1920718591
19208 if (resolved_ty.zigTypeTag(zcu) == .@"struct") {18592 if (resolved_ty.zigTypeTag(zcu) == .@"struct") {
19209 // This logic must be synchronized with that in `zirStructInitEmpty`.18593 // This logic must be synchronized with that in `zirStructInitEmpty`.
...@@ -19226,7 +18610,6 @@ fn zirStructInit(...@@ -19226,7 +18610,6 @@ fn zirStructInit(
19226 var field_i: u32 = 0;18610 var field_i: u32 = 0;
19227 var extra_index = extra.end;18611 var extra_index = extra.end;
1922818612
19229 const is_packed = resolved_ty.containerLayout(zcu) == .@"packed";
19230 while (field_i < extra.data.fields_len) : (field_i += 1) {18613 while (field_i < extra.data.fields_len) : (field_i += 1) {
19231 const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra_index);18614 const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra_index);
19232 extra_index = item.end;18615 extra_index = item.end;
...@@ -19248,19 +18631,16 @@ fn zirStructInit(...@@ -19248,19 +18631,16 @@ fn zirStructInit(
19248 assert(field_inits[field_index] == .none);18631 assert(field_inits[field_index] == .none);
19249 field_assign_idxs[field_index] = field_i;18632 field_assign_idxs[field_index] = field_i;
19250 found_fields[field_index] = item.data.field_type;18633 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);
19252 const field_ty = resolved_ty.fieldType(field_index, zcu);18635 const field_ty = resolved_ty.fieldType(field_index, zcu);
19253 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);18636 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
19254 if (!is_packed) {18637 if (resolved_ty.structFieldIsComptime(field_index, zcu)) {
19255 try resolved_ty.resolveStructFieldInits(pt);18638 const default_value = (try resolved_ty.structFieldValueComptime(pt, field_index)).?;
19256 if (try resolved_ty.structFieldValueComptime(pt, field_index)) |default_value| {18639 const init_val = sema.resolveValue(field_inits[field_index]) orelse {
19257 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {18640 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
19258 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });18641 };
19259 };18642 if (!init_val.eql(default_value, resolved_ty.fieldType(field_index, zcu), zcu)) {
1926018643 return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index);
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 }
19264 }18644 }
19265 }18645 }
19266 }18646 }
...@@ -19288,9 +18668,9 @@ fn zirStructInit(...@@ -19288,9 +18668,9 @@ fn zirStructInit(
19288 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);18668 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
19289 const field_ty: Type = .fromInterned(zcu.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]);18669 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) {
19292 return sema.failWithOwnedErrorMsg(block, msg: {18672 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)});
19294 errdefer msg.destroy(sema.gpa);18674 errdefer msg.destroy(sema.gpa);
1929518675
19296 try sema.addFieldErrNote(resolved_ty, field_index, msg, "field '{f}' declared here", .{18676 try sema.addFieldErrNote(resolved_ty, field_index, msg, "field '{f}' declared here", .{
...@@ -19301,21 +18681,31 @@ fn zirStructInit(...@@ -19301,21 +18681,31 @@ fn zirStructInit(
19301 });18681 });
19302 }18682 }
1930318683
19304 const uncoerced_init_inst = try sema.resolveInst(item.data.init);18684 const uncoerced_init_inst = sema.resolveInst(item.data.init);
19305 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);18685 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| {
19308 const struct_val = Value.fromInterned(try pt.internUnion(.{18698 const struct_val = Value.fromInterned(try pt.internUnion(.{
19309 .ty = resolved_ty.toIntern(),18699 .ty = resolved_ty.toIntern(),
19310 .tag = tag_val.toIntern(),18700 .tag = tag_val.toIntern(),
19311 .val = val.toIntern(),18701 .val = val.toIntern(),
19312 }));18702 }));
19313 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);18703 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)).?;18704 const final_val = sema.resolveValue(final_val_inst).?;
19315 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);18705 return sema.addConstantMaybeRef(final_val, is_ref);
19316 }18706 }
1931718707
19318 if (try resolved_ty.comptimeOnlySema(pt)) {18708 if (resolved_ty.comptimeOnly(zcu)) {
19319 return sema.failWithNeededComptime(block, field_src, .{ .comptime_only = .{18709 return sema.failWithNeededComptime(block, field_src, .{ .comptime_only = .{
19320 .ty = resolved_ty,18710 .ty = resolved_ty,
19321 .msg = .union_init,18711 .msg = .union_init,
...@@ -19326,7 +18716,7 @@ fn zirStructInit(...@@ -19326,7 +18716,7 @@ fn zirStructInit(
1932618716
19327 if (is_ref) {18717 if (is_ref) {
19328 const target = zcu.getTarget();18718 const target = zcu.getTarget();
19329 const alloc_ty = try pt.ptrTypeSema(.{18719 const alloc_ty = try pt.ptrType(.{
19330 .child = result_ty.toIntern(),18720 .child = result_ty.toIntern(),
19331 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },18721 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19332 });18722 });
...@@ -19334,10 +18724,6 @@ fn zirStructInit(...@@ -19334,10 +18724,6 @@ fn zirStructInit(
19334 const base_ptr = try sema.optEuBasePtrInit(block, alloc, src);18724 const base_ptr = try sema.optEuBasePtrInit(block, alloc, src);
19335 const field_ptr = try sema.unionFieldPtr(block, field_src, base_ptr, field_name, field_src, resolved_ty, true);18725 const field_ptr = try sema.unionFieldPtr(block, field_src, base_ptr, field_name, field_src, resolved_ty, true);
19336 try sema.storePtr(block, src, field_ptr, init_inst);18726 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 }
19341 return sema.makePtrConst(block, alloc);18727 return sema.makePtrConst(block, alloc);
19342 }18728 }
1934318729
...@@ -19409,20 +18795,29 @@ fn finishStructInit(...@@ -19409,20 +18795,29 @@ fn finishStructInit(
19409 continue;18795 continue;
19410 }18796 }
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);18805 const field_default: InternPool.Index = d: {
19415 if (field_init == .none) {18806 if (struct_type.field_defaults.len == 0) break :d .none;
19416 const field_name = struct_type.field_names.get(ip)[i];18807 break :d struct_type.field_defaults.get(ip)[i];
19417 const template = "missing struct field: {f}";18808 };
19418 const args = .{field_name.fmt(ip)};18809 if (field_default != .none) {
19419 if (root_msg) |msg| {18810 field_inits[i] = .fromIntern(field_default);
19420 try sema.errNote(init_src, msg, template, args);18811 continue;
19421 } else {18812 }
19422 root_msg = try sema.errMsg(init_src, template, args);18813
19423 }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);
19424 } else {18819 } else {
19425 field_inits[i] = Air.internedToRef(field_init);18820 root_msg = try sema.errMsg(init_src, template, args);
19426 }18821 }
19427 }18822 }
19428 },18823 },
...@@ -19442,18 +18837,38 @@ fn finishStructInit(...@@ -19442,18 +18837,38 @@ fn finishStructInit(
19442 }18837 }
19443 } else null;18838 } else null;
1944418839
19445 const runtime_index = opt_runtime_index orelse {18840 const runtime_index = opt_runtime_index orelse switch (struct_ty.containerLayout(zcu)) {
19446 const elems = try sema.arena.alloc(InternPool.Index, field_inits.len);18841 .auto, .@"extern" => {
19447 for (elems, field_inits) |*elem, field_init| {18842 const elems = try sema.arena.alloc(InternPool.Index, field_inits.len);
19448 elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern();18843 for (elems, field_inits) |*elem, field_init| {
19449 }18844 elem.* = sema.resolveValue(field_init).?.toIntern();
19450 const struct_val = try pt.aggregateValue(struct_ty, elems);18845 }
19451 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), init_src);18846 const struct_val = try pt.aggregateValue(struct_ty, elems);
19452 const final_val = (try sema.resolveValue(final_val_inst)).?;18847 const final_val_ref = try sema.coerce(block, result_ty, .fromValue(struct_val), init_src);
19453 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);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 },
19454 };18869 };
1945518870
19456 if (try struct_ty.comptimeOnlySema(pt)) {18871 if (struct_ty.comptimeOnly(zcu)) {
19457 return sema.failWithNeededComptime(block, block.src(.{ .init_elem = .{18872 return sema.failWithNeededComptime(block, block.src(.{ .init_elem = .{
19458 .init_node_offset = init_src.offset.node_offset.x,18873 .init_node_offset = init_src.offset.node_offset.x,
19459 .elem_index = @intCast(runtime_index),18874 .elem_index = @intCast(runtime_index),
...@@ -19468,9 +18883,8 @@ fn finishStructInit(...@@ -19468,9 +18883,8 @@ fn finishStructInit(
19468 }18883 }
1946918884
19470 if (is_ref) {18885 if (is_ref) {
19471 try struct_ty.resolveLayout(pt);
19472 const target = zcu.getTarget();18886 const target = zcu.getTarget();
19473 const alloc_ty = try pt.ptrTypeSema(.{18887 const alloc_ty = try pt.ptrType(.{
19474 .child = result_ty.toIntern(),18888 .child = result_ty.toIntern(),
19475 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },18889 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19476 });18890 });
...@@ -19489,7 +18903,6 @@ fn finishStructInit(...@@ -19489,7 +18903,6 @@ fn finishStructInit(
19489 .init_node_offset = init_src.offset.node_offset.x,18903 .init_node_offset = init_src.offset.node_offset.x,
19490 .elem_index = @intCast(runtime_index),18904 .elem_index = @intCast(runtime_index),
19491 } }));18905 } }));
19492 try struct_ty.resolveStructFieldInits(pt);
19493 const struct_val = try block.addAggregateInit(struct_ty, field_inits);18906 const struct_val = try block.addAggregateInit(struct_ty, field_inits);
19494 return sema.coerce(block, result_ty, struct_val, init_src);18907 return sema.coerce(block, result_ty, struct_val, init_src);
19495}18908}
...@@ -19558,7 +18971,7 @@ fn structInitAnon(...@@ -19558,7 +18971,7 @@ fn structInitAnon(
1955818971
19559 field_name.* = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);18972 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);
19562 field_ty.* = sema.typeOf(init).toIntern();18975 field_ty.* = sema.typeOf(init).toIntern();
19563 if (Type.fromInterned(field_ty.*).zigTypeTag(zcu) == .@"opaque") {18976 if (Type.fromInterned(field_ty.*).zigTypeTag(zcu) == .@"opaque") {
19564 const msg = msg: {18977 const msg = msg: {
...@@ -19574,7 +18987,7 @@ fn structInitAnon(...@@ -19574,7 +18987,7 @@ fn structInitAnon(
19574 };18987 };
19575 return sema.failWithOwnedErrorMsg(block, msg);18988 return sema.failWithOwnedErrorMsg(block, msg);
19576 }18989 }
19577 if (try sema.resolveValue(init)) |init_val| {18990 if (sema.resolveValue(init)) |init_val| {
19578 field_val.* = init_val.toIntern();18991 field_val.* = init_val.toIntern();
19579 any_values = true;18992 any_values = true;
19580 } else {18993 } else {
...@@ -19585,12 +18998,11 @@ fn structInitAnon(...@@ -19585,12 +18998,11 @@ fn structInitAnon(
19585 break :rs runtime_index;18998 break :rs runtime_index;
19586 };18999 };
1958719000
19588 // We treat anonymous struct types as reified types, because there are similarities:19001 // We treat anonymous struct types as reified types, because there are similarities: they have
19589 // * They use a form of structural equivalence, which we can easily model using a custom hash19002 // no captures, and instead use a form of structural equivalence which we can easy represent by
19590 // * They do not have captures19003 // hashing the field names/types/values. They also perform layout resolution immediately. These
19591 // * They immediately have their fields resolved19004 // similarities mean that other code should actually treat anon struct types and reified struct
19592 // In general, other code should treat anon struct types and reified struct types identically,19005 // types identically anyway, so sharing the representation makes everything simpler.
19593 // so there's no point having a separate `InternPool.NamespaceType` field for them.
19594 const type_hash: u64 = hash: {19006 const type_hash: u64 = hash: {
19595 var hasher = std.hash.Wyhash.init(0);19007 var hasher = std.hash.Wyhash.init(0);
19596 hasher.update(std.mem.sliceAsBytes(types));19008 hasher.update(std.mem.sliceAsBytes(types));
...@@ -19599,35 +19011,33 @@ fn structInitAnon(...@@ -19599,35 +19011,33 @@ fn structInitAnon(
19599 break :hash hasher.final();19011 break :hash hasher.final();
19600 };19012 };
19601 const tracked_inst = try block.trackZir(inst);19013 const tracked_inst = try block.trackZir(inst);
19602 const struct_ty = switch (try ip.getStructType(gpa, io, pt.tid, .{19014 const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
19603 .layout = .auto,19015 .zir_index = tracked_inst,
19016 .type_hash = type_hash,
19604 .fields_len = extra_data.fields_len,19017 .fields_len = extra_data.fields_len,
19605 .known_non_opv = false,19018 .layout = .auto,
19606 .requires_comptime = .unknown,
19607 .any_comptime_fields = any_values,19019 .any_comptime_fields = any_values,
19608 .any_default_inits = any_values,19020 .any_field_defaults = any_values,
19609 .inits_resolved = true,19021 .any_field_aligns = false,
19610 .any_aligned_fields = false,19022 .packed_backing_int_type = .none,
19611 .key = .{ .reified = .{19023 })) {
19612 .zir_index = tracked_inst,19024 .existing => |ty| .fromInterned(ty),
19613 .type_hash = type_hash,
19614 } },
19615 }, false)) {
19616 .wip => |wip| ty: {19025 .wip => |wip| ty: {
19617 errdefer wip.cancel(ip, pt.tid);19026 errdefer wip.cancel(ip, pt.tid);
19618 const type_name = try sema.createTypeName(block, .anon, "struct", inst, wip.index);19027 try sema.setTypeName(block, &wip, .anon, "struct", inst);
19619 wip.setName(ip, type_name.name, type_name.nav);
19620
19621 const struct_type = ip.loadStructType(wip.index);
1962219028
19623 for (names, values, 0..) |name, init_val, field_idx| {19029 // Reified structs have field information populated immediately.
19624 assert(struct_type.addFieldName(ip, name) == null);19030 @memcpy(wip.field_names.get(ip), names);
19625 if (init_val != .none) struct_type.setFieldComptime(ip, field_idx);19031 @memcpy(wip.field_types.get(ip), types);
19626 }
19627
19628 @memcpy(struct_type.field_types.get(ip), types);
19629 if (any_values) {19032 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 }
19631 }19041 }
1963219042
19633 const new_namespace_index = try pt.createNamespace(.{19043 const new_namespace_index = try pt.createNamespace(.{
...@@ -19636,30 +19046,24 @@ fn structInitAnon(...@@ -19636,30 +19046,24 @@ fn structInitAnon(
19636 .file_scope = block.getFileScopeIndex(zcu),19046 .file_scope = block.getFileScopeIndex(zcu),
19637 .generation = zcu.generation,19047 .generation = zcu.generation,
19638 });19048 });
19639 try zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });19049 errdefer pt.destroyNamespace(new_namespace_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 }
19646 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);19050 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));
19648 },19052 },
19649 .existing => |ty| ty,
19650 };19053 };
19651 try sema.declareDependency(.{ .interned = struct_ty });
19652 try sema.addTypeReferenceEntry(src, struct_ty);19054 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
19654 _ = opt_runtime_index orelse {19058 _ = opt_runtime_index orelse {
19655 const struct_val = try pt.aggregateValue(.fromInterned(struct_ty), values);19059 const struct_val = try pt.aggregateValue(struct_ty, values);
19656 return sema.addConstantMaybeRef(struct_val.toIntern(), is_ref);19060 return sema.addConstantMaybeRef(struct_val, is_ref);
19657 };19061 };
1965819062
19659 if (is_ref) {19063 if (is_ref) {
19660 const target = zcu.getTarget();19064 const target = zcu.getTarget();
19661 const alloc_ty = try pt.ptrTypeSema(.{19065 const alloc_ty = try pt.ptrType(.{
19662 .child = struct_ty,19066 .child = struct_ty.toIntern(),
19663 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19067 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19664 });19068 });
19665 const alloc = try block.addTy(.alloc, alloc_ty);19069 const alloc = try block.addTy(.alloc, alloc_ty);
...@@ -19672,12 +19076,12 @@ fn structInitAnon(...@@ -19672,12 +19076,12 @@ fn structInitAnon(
19672 };19076 };
19673 extra_index = item.end;19077 extra_index = item.end;
1967419078
19675 const field_ptr_ty = try pt.ptrTypeSema(.{19079 const field_ptr_ty = try pt.ptrType(.{
19676 .child = field_ty,19080 .child = field_ty,
19677 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19081 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19678 });19082 });
19679 if (values[i] == .none) {19083 if (values[i] == .none) {
19680 const init = try sema.resolveInst(item.data.init);19084 const init = sema.resolveInst(item.data.init);
19681 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);19085 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
19682 _ = try block.addBinOp(.store, field_ptr, init);19086 _ = try block.addBinOp(.store, field_ptr, init);
19683 }19087 }
...@@ -19694,10 +19098,10 @@ fn structInitAnon(...@@ -19694,10 +19098,10 @@ fn structInitAnon(
19694 .typed_init => sema.code.extraData(Zir.Inst.StructInit.Item, extra_index),19098 .typed_init => sema.code.extraData(Zir.Inst.StructInit.Item, extra_index),
19695 };19099 };
19696 extra_index = item.end;19100 extra_index = item.end;
19697 element_refs[i] = try sema.resolveInst(item.data.init);19101 element_refs[i] = sema.resolveInst(item.data.init);
19698 }19102 }
1969919103
19700 return block.addAggregateInit(.fromInterned(struct_ty), element_refs);19104 return block.addAggregateInit(struct_ty, element_refs);
19701}19105}
1970219106
19703fn zirArrayInit(19107fn zirArrayInit(
...@@ -19737,17 +19141,16 @@ fn zirArrayInit(...@@ -19737,17 +19141,16 @@ fn zirArrayInit(
19737 } });19141 } });
19738 // Less inits than needed.19142 // Less inits than needed.
19739 if (i + 2 > args.len) if (is_tuple) {19143 if (i + 2 > args.len) if (is_tuple) {
19740 const default_val = array_ty.structFieldDefaultValue(i, zcu).toIntern();19144 const default_val = array_ty.structFieldDefaultValue(i, zcu) orelse {
19741 if (default_val == .unreachable_value) {
19742 const template = "missing tuple field with index {d}";19145 const template = "missing tuple field with index {d}";
19743 if (root_msg) |msg| {19146 if (root_msg) |msg| {
19744 try sema.errNote(src, msg, template, .{i});19147 try sema.errNote(src, msg, template, .{i});
19745 } else {19148 } else {
19746 root_msg = try sema.errMsg(src, template, .{i});19149 root_msg = try sema.errMsg(src, template, .{i});
19747 }19150 }
19748 } else {19151 continue;
19749 dest.* = Air.internedToRef(default_val);19152 };
19750 }19153 dest.* = .fromValue(default_val);
19751 continue;19154 continue;
19752 } else {19155 } else {
19753 dest.* = Air.internedToRef(sentinel_val.?.toIntern());19156 dest.* = Air.internedToRef(sentinel_val.?.toIntern());
...@@ -19755,15 +19158,13 @@ fn zirArrayInit(...@@ -19755,15 +19158,13 @@ fn zirArrayInit(
19755 };19158 };
1975619159
19757 const arg = args[i + 1];19160 const arg = args[i + 1];
19758 const resolved_arg = try sema.resolveInst(arg);19161 const resolved_arg = sema.resolveInst(arg);
19759 const elem_ty = if (is_tuple)19162 const elem_ty = if (is_tuple)
19760 array_ty.fieldType(i, zcu)19163 array_ty.fieldType(i, zcu)
19761 else19164 else
19762 array_ty.elemType2(zcu);19165 array_ty.childType(zcu);
19763 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);19166 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
19764 if (is_tuple) {19167 if (is_tuple) {
19765 if (array_ty.structFieldIsComptime(i, zcu))
19766 try array_ty.resolveStructFieldInits(pt);
19767 if (try array_ty.structFieldValueComptime(pt, i)) |field_val| {19168 if (try array_ty.structFieldValueComptime(pt, i)) |field_val| {
19768 const init_val = try sema.resolveConstValue(block, elem_src, dest.*, .{ .simple = .stored_to_comptime_field });19169 const init_val = try sema.resolveConstValue(block, elem_src, dest.*, .{ .simple = .stored_to_comptime_field });
19769 if (!field_val.eql(init_val, elem_ty, zcu)) {19170 if (!field_val.eql(init_val, elem_ty, zcu)) {
...@@ -19788,17 +19189,17 @@ fn zirArrayInit(...@@ -19788,17 +19189,17 @@ fn zirArrayInit(
19788 const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len);19189 const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len);
19789 for (elem_vals, resolved_args) |*val, arg| {19190 for (elem_vals, resolved_args) |*val, arg| {
19790 // We checked that all args are comptime above.19191 // We checked that all args are comptime above.
19791 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();19192 val.* = sema.resolveValue(arg).?.toIntern();
19792 }19193 }
19793 const arr_val = try pt.aggregateValue(array_ty, elem_vals);19194 const arr_val = try pt.aggregateValue(array_ty, elem_vals);
19794 const result_ref = try sema.coerce(block, result_ty, Air.internedToRef(arr_val.toIntern()), src);19195 const result_ref = try sema.coerce(block, result_ty, Air.internedToRef(arr_val.toIntern()), src);
19795 const result_val = (try sema.resolveValue(result_ref)).?;19196 const result_val = (sema.resolveValue(result_ref)).?;
19796 return sema.addConstantMaybeRef(result_val.toIntern(), is_ref);19197 return sema.addConstantMaybeRef(result_val, is_ref);
19797 };19198 };
1979819199
19799 if (is_ref) {19200 if (is_ref) {
19800 const target = zcu.getTarget();19201 const target = zcu.getTarget();
19801 const alloc_ty = try pt.ptrTypeSema(.{19202 const alloc_ty = try pt.ptrType(.{
19802 .child = result_ty.toIntern(),19203 .child = result_ty.toIntern(),
19803 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19204 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19804 });19205 });
...@@ -19807,7 +19208,7 @@ fn zirArrayInit(...@@ -19807,7 +19208,7 @@ fn zirArrayInit(
1980719208
19808 if (is_tuple) {19209 if (is_tuple) {
19809 for (resolved_args, 0..) |arg, i| {19210 for (resolved_args, 0..) |arg, i| {
19810 const elem_ptr_ty = try pt.ptrTypeSema(.{19211 const elem_ptr_ty = try pt.ptrType(.{
19811 .child = array_ty.fieldType(i, zcu).toIntern(),19212 .child = array_ty.fieldType(i, zcu).toIntern(),
19812 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19213 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19813 });19214 });
...@@ -19820,8 +19221,8 @@ fn zirArrayInit(...@@ -19820,8 +19221,8 @@ fn zirArrayInit(
19820 return sema.makePtrConst(block, alloc);19221 return sema.makePtrConst(block, alloc);
19821 }19222 }
1982219223
19823 const elem_ptr_ty = try pt.ptrTypeSema(.{19224 const elem_ptr_ty = try pt.ptrType(.{
19824 .child = array_ty.elemType2(zcu).toIntern(),19225 .child = array_ty.childType(zcu).toIntern(),
19825 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19226 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19826 });19227 });
19827 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());19228 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
...@@ -19875,7 +19276,7 @@ fn arrayInitAnon(...@@ -19875,7 +19276,7 @@ fn arrayInitAnon(
19875 .init_node_offset = src.offset.node_offset.x,19276 .init_node_offset = src.offset.node_offset.x,
19876 .elem_index = @intCast(i),19277 .elem_index = @intCast(i),
19877 } });19278 } });
19878 const elem = try sema.resolveInst(operand);19279 const elem = sema.resolveInst(operand);
19879 types[i] = sema.typeOf(elem).toIntern();19280 types[i] = sema.typeOf(elem).toIntern();
19880 if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {19281 if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {
19881 const msg = msg: {19282 const msg = msg: {
...@@ -19887,7 +19288,7 @@ fn arrayInitAnon(...@@ -19887,7 +19288,7 @@ fn arrayInitAnon(
19887 };19288 };
19888 return sema.failWithOwnedErrorMsg(block, msg);19289 return sema.failWithOwnedErrorMsg(block, msg);
19889 }19290 }
19890 if (try sema.resolveValue(elem)) |val| {19291 if (sema.resolveValue(elem)) |val| {
19891 values[i] = val.toIntern();19292 values[i] = val.toIntern();
19892 any_comptime = true;19293 any_comptime = true;
19893 } else {19294 } else {
...@@ -19917,7 +19318,7 @@ fn arrayInitAnon(...@@ -19917,7 +19318,7 @@ fn arrayInitAnon(
1991719318
19918 const runtime_src = opt_runtime_src orelse {19319 const runtime_src = opt_runtime_src orelse {
19919 const tuple_val = try pt.aggregateValue(tuple_ty, values);19320 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);
19921 };19322 };
1992219323
19923 try sema.requireRuntimeBlock(block, src, runtime_src);19324 try sema.requireRuntimeBlock(block, src, runtime_src);
...@@ -19927,25 +19328,25 @@ fn arrayInitAnon(...@@ -19927,25 +19328,25 @@ fn arrayInitAnon(
19927 .init_node_offset = src.offset.node_offset.x,19328 .init_node_offset = src.offset.node_offset.x,
19928 .elem_index = @intCast(i),19329 .elem_index = @intCast(i),
19929 } });19330 } });
19930 try sema.validateRuntimeValue(block, operand_src, try sema.resolveInst(operand));19331 try sema.validateRuntimeValue(block, operand_src, sema.resolveInst(operand));
19931 }19332 }
1993219333
19933 if (is_ref) {19334 if (is_ref) {
19934 const target = sema.pt.zcu.getTarget();19335 const target = sema.pt.zcu.getTarget();
19935 const alloc_ty = try pt.ptrTypeSema(.{19336 const alloc_ty = try pt.ptrType(.{
19936 .child = tuple_ty.toIntern(),19337 .child = tuple_ty.toIntern(),
19937 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19338 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19938 });19339 });
19939 const alloc = try block.addTy(.alloc, alloc_ty);19340 const alloc = try block.addTy(.alloc, alloc_ty);
19940 for (operands, 0..) |operand, i_usize| {19341 for (operands, 0..) |operand, i_usize| {
19941 const i: u32 = @intCast(i_usize);19342 const i: u32 = @intCast(i_usize);
19942 const field_ptr_ty = try pt.ptrTypeSema(.{19343 const field_ptr_ty = try pt.ptrType(.{
19943 .child = types[i],19344 .child = types[i],
19944 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },19345 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19945 });19346 });
19946 if (values[i] == .none) {19347 if (values[i] == .none) {
19947 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);19348 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));
19949 }19350 }
19950 }19351 }
1995119352
...@@ -19954,14 +19355,14 @@ fn arrayInitAnon(...@@ -19954,14 +19355,14 @@ fn arrayInitAnon(
1995419355
19955 const element_refs = try sema.arena.alloc(Air.Inst.Ref, operands.len);19356 const element_refs = try sema.arena.alloc(Air.Inst.Ref, operands.len);
19956 for (operands, 0..) |operand, i| {19357 for (operands, 0..) |operand, i| {
19957 element_refs[i] = try sema.resolveInst(operand);19358 element_refs[i] = sema.resolveInst(operand);
19958 }19359 }
1995919360
19960 return block.addAggregateInit(tuple_ty, element_refs);19361 return block.addAggregateInit(tuple_ty, element_refs);
19961}19362}
1996219363
19963fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {19364fn addConstantMaybeRef(sema: *Sema, val: Value, is_ref: bool) !Air.Inst.Ref {
19964 return if (is_ref) sema.uavRef(val) else Air.internedToRef(val);19365 return if (is_ref) sema.uavRef(val) else .fromValue(val);
19965}19366}
1996619367
19967fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19368fn 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...@@ -19971,6 +19372,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
19971 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);19372 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
19972 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);19373 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
19973 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .field_name });19374 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);
19974 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);19376 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
19975}19377}
1997619378
...@@ -19990,9 +19392,11 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -19990,9 +19392,11 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
19990 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu);19392 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu);
19991 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);19393 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
19992 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_field_name, .no_embedded_nulls);19394 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);
19993 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);19396 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
19994}19397}
1999519398
19399/// Asserts that the layout of `aggregate_ty` is resolved.
19996fn fieldType(19400fn fieldType(
19997 sema: *Sema,19401 sema: *Sema,
19998 block: *Block,19402 block: *Block,
...@@ -20004,9 +19408,9 @@ fn fieldType(...@@ -20004,9 +19408,9 @@ fn fieldType(
20004 const pt = sema.pt;19408 const pt = sema.pt;
20005 const zcu = pt.zcu;19409 const zcu = pt.zcu;
20006 const ip = &zcu.intern_pool;19410 const ip = &zcu.intern_pool;
19411 aggregate_ty.assertHasLayout(zcu);
20007 var cur_ty = aggregate_ty;19412 var cur_ty = aggregate_ty;
20008 while (true) {19413 while (true) {
20009 try cur_ty.resolveFields(pt);
20010 switch (cur_ty.zigTypeTag(zcu)) {19414 switch (cur_ty.zigTypeTag(zcu)) {
20011 .@"struct" => switch (ip.indexToKey(cur_ty.toIntern())) {19415 .@"struct" => switch (ip.indexToKey(cur_ty.toIntern())) {
20012 .tuple_type => |tuple| {19416 .tuple_type => |tuple| {
...@@ -20024,10 +19428,11 @@ fn fieldType(...@@ -20024,10 +19428,11 @@ fn fieldType(
20024 },19428 },
20025 .@"union" => {19429 .@"union" => {
20026 const union_obj = zcu.typeToUnion(cur_ty).?;19430 const union_obj = zcu.typeToUnion(cur_ty).?;
20027 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse19431 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
19432 const field_index = enum_obj.nameIndex(ip, field_name) orelse
20028 return sema.failWithBadUnionFieldAccess(block, cur_ty, union_obj, field_src, field_name);19433 return sema.failWithBadUnionFieldAccess(block, cur_ty, union_obj, field_src, field_name);
20029 const field_ty = union_obj.field_types.get(ip)[field_index];19434 const field_ty = union_obj.field_types.get(ip)[field_index];
20030 return Air.internedToRef(field_ty);19435 return .fromIntern(field_ty);
20031 },19436 },
20032 .optional => {19437 .optional => {
20033 // Struct/array init through optional requires the child type to not be a pointer.19438 // 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 {...@@ -20056,7 +19461,6 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20056 const zcu = pt.zcu;19461 const zcu = pt.zcu;
20057 const ip = &zcu.intern_pool;19462 const ip = &zcu.intern_pool;
20058 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);19463 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);
20059 try stack_trace_ty.resolveFields(pt);
20060 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);19464 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
20061 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());19465 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 {...@@ -20064,7 +19468,14 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20064 .func => |func| if (ip.funcAnalysisUnordered(func).has_error_trace and block.ownerModule().error_tracing) {19468 .func => |func| if (ip.funcAnalysisUnordered(func).has_error_trace and block.ownerModule().error_tracing) {
20065 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);19469 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
20066 },19470 },
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 => {},
20068 }19479 }
20069 return Air.internedToRef(try pt.intern(.{ .opt = .{19480 return Air.internedToRef(try pt.intern(.{ .opt = .{
20070 .ty = opt_ptr_stack_trace_ty.toIntern(),19481 .ty = opt_ptr_stack_trace_ty.toIntern(),
...@@ -20083,15 +19494,16 @@ fn zirFrame(...@@ -20083,15 +19494,16 @@ fn zirFrame(
20083}19494}
2008419495
20085fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19496fn 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;
20087 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19499 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20088 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);19500 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20089 const ty = try sema.resolveType(block, operand_src, inst_data.operand);19501 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
19502 try sema.ensureLayoutResolved(ty, operand_src, .align_of);
20090 if (ty.isNoReturn(zcu)) {19503 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)});
20092 }19505 }
20093 const val = try ty.lazyAbiAlignment(sema.pt);19506 return .fromValue(try pt.intValue(.comptime_int, ty.abiAlignment(zcu).toByteUnits().?));
20094 return Air.internedToRef(val.toIntern());
20095}19507}
2009619508
20097fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19509fn 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...@@ -20099,7 +19511,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20099 const zcu = pt.zcu;19511 const zcu = pt.zcu;
20100 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19512 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20101 const src = block.nodeOffset(inst_data.src_node);19513 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);
20103 const operand_ty = sema.typeOf(operand);19515 const operand_ty = sema.typeOf(operand);
20104 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;19516 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
20105 const operand_scalar_ty = operand_ty.scalarType(zcu);19517 const operand_scalar_ty = operand_ty.scalarType(zcu);
...@@ -20108,7 +19520,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20108,7 +19520,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20108 }19520 }
20109 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;19521 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;
20110 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .u1_type, .len = len }) else .u1;19522 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| {
20112 if (!is_vector) {19524 if (!is_vector) {
20113 return if (val.isUndef(zcu)) .undef_u1 else if (val.toBool()) .one_u1 else .zero_u1;19525 return if (val.isUndef(zcu)) .undef_u1 else if (val.toBool()) .one_u1 else .zero_u1;
20114 }19526 }
...@@ -20131,7 +19543,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20131,7 +19543,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20131fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19543fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20132 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19544 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20133 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);19545 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);
20135 const operand = try sema.coerce(block, .anyerror, uncoerced_operand, operand_src);19547 const operand = try sema.coerce(block, .anyerror, uncoerced_operand, operand_src);
2013619548
20137 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {19549 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
...@@ -20152,7 +19564,7 @@ fn zirAbs(...@@ -20152,7 +19564,7 @@ fn zirAbs(
20152 const pt = sema.pt;19564 const pt = sema.pt;
20153 const zcu = pt.zcu;19565 const zcu = pt.zcu;
20154 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19566 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);
20156 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);19568 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20157 const operand_ty = sema.typeOf(operand);19569 const operand_ty = sema.typeOf(operand);
20158 const scalar_ty = operand_ty.scalarType(zcu);19570 const scalar_ty = operand_ty.scalarType(zcu);
...@@ -20183,7 +19595,7 @@ fn maybeConstantUnaryMath(...@@ -20183,7 +19595,7 @@ fn maybeConstantUnaryMath(
20183 const pt = sema.pt;19595 const pt = sema.pt;
20184 const zcu = pt.zcu;19596 const zcu = pt.zcu;
20185 switch (result_ty.zigTypeTag(zcu)) {19597 switch (result_ty.zigTypeTag(zcu)) {
20186 .vector => if (try sema.resolveValue(operand)) |val| {19598 .vector => if (sema.resolveValue(operand)) |val| {
20187 const scalar_ty = result_ty.scalarType(zcu);19599 const scalar_ty = result_ty.scalarType(zcu);
20188 const vec_len = result_ty.vectorLen(zcu);19600 const vec_len = result_ty.vectorLen(zcu);
20189 if (val.isUndef(zcu))19601 if (val.isUndef(zcu))
...@@ -20196,7 +19608,7 @@ fn maybeConstantUnaryMath(...@@ -20196,7 +19608,7 @@ fn maybeConstantUnaryMath(
20196 }19608 }
20197 return Air.internedToRef((try pt.aggregateValue(result_ty, elems)).toIntern());19609 return Air.internedToRef((try pt.aggregateValue(result_ty, elems)).toIntern());
20198 },19610 },
20199 else => if (try sema.resolveValue(operand)) |operand_val| {19611 else => if (sema.resolveValue(operand)) |operand_val| {
20200 if (operand_val.isUndef(zcu))19612 if (operand_val.isUndef(zcu))
20201 return try pt.undefRef(result_ty);19613 return try pt.undefRef(result_ty);
20202 const result_val = try eval(operand_val, result_ty, sema.arena, pt);19614 const result_val = try eval(operand_val, result_ty, sema.arena, pt);
...@@ -20219,7 +19631,7 @@ fn zirUnaryMath(...@@ -20219,7 +19631,7 @@ fn zirUnaryMath(
20219 const pt = sema.pt;19631 const pt = sema.pt;
20220 const zcu = pt.zcu;19632 const zcu = pt.zcu;
20221 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19633 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);
20223 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);19635 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20224 const operand_ty = sema.typeOf(operand);19636 const operand_ty = sema.typeOf(operand);
20225 const scalar_ty = operand_ty.scalarType(zcu);19637 const scalar_ty = operand_ty.scalarType(zcu);
...@@ -20244,12 +19656,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20244,12 +19656,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20244 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19656 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20245 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);19657 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20246 const src = block.nodeOffset(inst_data.src_node);19658 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);
20248 const operand_ty = sema.typeOf(operand);19660 const operand_ty = sema.typeOf(operand);
20249 const pt = sema.pt;19661 const pt = sema.pt;
20250 const zcu = pt.zcu;19662 const zcu = pt.zcu;
20251 const ip = &zcu.intern_pool;19663 const ip = &zcu.intern_pool;
20252 try operand_ty.resolveLayout(pt);
20253 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {19664 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
20254 .enum_literal => {19665 .enum_literal => {
20255 const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?;19666 const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?;
...@@ -20332,17 +19743,17 @@ fn zirReifySliceArgTy(...@@ -20332,17 +19743,17 @@ fn zirReifySliceArgTy(
20332 // zig fmt: on19743 // zig fmt: on
20333 };19744 };
2033419745
20335 const operand_ty = try pt.ptrTypeSema(.{19746 const operand_ty = try pt.ptrType(.{
20336 .child = in_scalar_ty.toIntern(),19747 .child = in_scalar_ty.toIntern(),
20337 .flags = .{ .size = .slice, .is_const = true },19748 .flags = .{ .size = .slice, .is_const = true },
20338 });19749 });
2033919750
20340 const operand_uncoerced = try sema.resolveInst(extra.operand);19751 const operand_uncoerced = sema.resolveInst(extra.operand);
20341 const operand_coerced = try sema.coerce(block, operand_ty, operand_uncoerced, src);19752 const operand_coerced = try sema.coerce(block, operand_ty, operand_uncoerced, src);
20342 const operand_val = try sema.resolveConstDefinedValue(block, src, operand_coerced, .{ .simple = comptime_reason });19753 const operand_val = try sema.resolveConstDefinedValue(block, src, operand_coerced, .{ .simple = comptime_reason });
20343 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);19754 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);
20344 if (len_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);19755 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
20347 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{19758 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{
20348 .len = len,19759 .len = len,
...@@ -20365,12 +19776,12 @@ fn zirReifyEnumValueSliceTy(...@@ -20365,12 +19776,12 @@ fn zirReifyEnumValueSliceTy(
2036519776
20366 const int_tag_ty = try sema.resolveType(block, int_tag_ty_src, extra.lhs);19777 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);
20369 const operand_coerced = try sema.coerce(block, .slice_const_slice_const_u8, operand_uncoerced, field_names_src);19780 const operand_coerced = try sema.coerce(block, .slice_const_slice_const_u8, operand_uncoerced, field_names_src);
20370 const operand_val = try sema.resolveConstDefinedValue(block, field_names_src, operand_coerced, .{ .simple = .enum_field_names });19781 const operand_val = try sema.resolveConstDefinedValue(block, field_names_src, operand_coerced, .{ .simple = .enum_field_names });
20371 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);19782 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);
20372 if (len_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, field_names_src, null);19783 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
20375 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{19786 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{
20376 .len = len,19787 .len = len,
...@@ -20410,7 +19821,7 @@ fn zirReifyTuple(...@@ -20410,7 +19821,7 @@ fn zirReifyTuple(
20410 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;19821 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
20411 const operand_src = block.builtinCallArgSrc(extra.node, 0);19822 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);
20414 const types_coerced = try sema.coerce(block, .slice_const_type, types_uncoerced, operand_src);19825 const types_coerced = try sema.coerce(block, .slice_const_type, types_uncoerced, operand_src);
20415 const types_slice_val = try sema.resolveConstDefinedValue(block, operand_src, types_coerced, .{ .simple = .tuple_field_types });19826 const types_slice_val = try sema.resolveConstDefinedValue(block, operand_src, types_coerced, .{ .simple = .tuple_field_types });
20416 const types_array_val = try sema.derefSliceAsArray(block, operand_src, types_slice_val, .{ .simple = .tuple_field_types });19827 const types_array_val = try sema.derefSliceAsArray(block, operand_src, types_slice_val, .{ .simple = .tuple_field_types });
...@@ -20422,6 +19833,7 @@ fn zirReifyTuple(...@@ -20422,6 +19833,7 @@ fn zirReifyTuple(
20422 if (field_ty_val.isUndef(zcu)) {19833 if (field_ty_val.isUndef(zcu)) {
20423 return sema.failWithUseOfUndef(block, operand_src, null);19834 return sema.failWithUseOfUndef(block, operand_src, null);
20424 }19835 }
19836 try sema.validateTupleFieldType(block, field_ty_val.toType(), operand_src);
20425 field_ty.* = field_ty_val.toIntern();19837 field_ty.* = field_ty_val.toIntern();
20426 }19838 }
2042719839
...@@ -20456,12 +19868,12 @@ fn zirReifyPointer(...@@ -20456,12 +19868,12 @@ fn zirReifyPointer(
20456 const size_ty = try sema.getBuiltinType(size_src, .@"Type.Pointer.Size");19868 const size_ty = try sema.getBuiltinType(size_src, .@"Type.Pointer.Size");
20457 const attrs_ty = try sema.getBuiltinType(attrs_src, .@"Type.Pointer.Attributes");19869 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);
20460 const size_coerced = try sema.coerce(block, size_ty, size_uncoerced, size_src);19872 const size_coerced = try sema.coerce(block, size_ty, size_uncoerced, size_src);
20461 const size_val = try sema.resolveConstDefinedValue(block, size_src, size_coerced, .{ .simple = .pointer_size });19873 const size_val = try sema.resolveConstDefinedValue(block, size_src, size_coerced, .{ .simple = .pointer_size });
20462 const size = try sema.interpretBuiltinType(block, size_src, size_val, std.builtin.Type.Pointer.Size);19874 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);
20465 const attrs_coerced = try sema.coerce(block, attrs_ty, attrs_uncoerced, attrs_src);19877 const attrs_coerced = try sema.coerce(block, attrs_ty, attrs_uncoerced, attrs_src);
20466 const attrs_val = try sema.resolveConstDefinedValue(block, attrs_src, attrs_coerced, .{ .simple = .pointer_attrs });19878 const attrs_val = try sema.resolveConstDefinedValue(block, attrs_src, attrs_coerced, .{ .simple = .pointer_attrs });
20467 const attrs = try sema.interpretBuiltinType(block, attrs_src, attrs_val, std.builtin.Type.Pointer.Attributes);19879 const attrs = try sema.interpretBuiltinType(block, attrs_src, attrs_val, std.builtin.Type.Pointer.Attributes);
...@@ -20489,18 +19901,8 @@ fn zirReifyPointer(...@@ -20489,18 +19901,8 @@ fn zirReifyPointer(
20489 else => {},19901 else => {},
20490 }19902 }
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
20502 const sentinel_ty = try pt.optionalType(elem_ty.toIntern());19904 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);
20504 const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src);19906 const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src);
20505 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel_coerced, .{ .simple = .pointer_sentinel });19907 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel_coerced, .{ .simple = .pointer_sentinel });
20506 const opt_sentinel = sentinel_val.optionalValue(zcu);19908 const opt_sentinel = sentinel_val.optionalValue(zcu);
...@@ -20516,7 +19918,7 @@ fn zirReifyPointer(...@@ -20516,7 +19918,7 @@ fn zirReifyPointer(
20516 }19918 }
20517 }19919 }
2051819920
20519 return .fromType(try pt.ptrTypeSema(.{19921 return .fromType(try pt.ptrType(.{
20520 .child = elem_ty.toIntern(),19922 .child = elem_ty.toIntern(),
20521 .sentinel = if (opt_sentinel) |s| s.toIntern() else .none,19923 .sentinel = if (opt_sentinel) |s| s.toIntern() else .none,
20522 .flags = .{19924 .flags = .{
...@@ -20554,7 +19956,7 @@ fn zirReifyFn(...@@ -20554,7 +19956,7 @@ fn zirReifyFn(
20554 const single_param_attrs_ty = try sema.getBuiltinType(param_attrs_src, .@"Type.Fn.Param.Attributes");19956 const single_param_attrs_ty = try sema.getBuiltinType(param_attrs_src, .@"Type.Fn.Param.Attributes");
20555 const fn_attrs_ty = try sema.getBuiltinType(fn_attrs_src, .@"Type.Fn.Attributes");19957 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);
20558 const param_types_coerced = try sema.coerce(block, .slice_const_type, param_types_uncoerced, param_types_src);19960 const param_types_coerced = try sema.coerce(block, .slice_const_type, param_types_uncoerced, param_types_src);
20559 const param_types_slice = try sema.resolveConstDefinedValue(block, param_types_src, param_types_coerced, .{ .simple = .fn_param_types });19961 const param_types_slice = try sema.resolveConstDefinedValue(block, param_types_src, param_types_coerced, .{ .simple = .fn_param_types });
20560 const param_types_arr = try sema.derefSliceAsArray(block, param_types_src, param_types_slice, .{ .simple = .fn_param_types });19962 const param_types_arr = try sema.derefSliceAsArray(block, param_types_src, param_types_slice, .{ .simple = .fn_param_types });
...@@ -20565,14 +19967,14 @@ fn zirReifyFn(...@@ -20565,14 +19967,14 @@ fn zirReifyFn(
20565 .len = params_len,19967 .len = params_len,
20566 .child = single_param_attrs_ty.toIntern(),19968 .child = single_param_attrs_ty.toIntern(),
20567 }));19969 }));
20568 const param_attrs_uncoerced = try sema.resolveInst(extra.param_attrs);19970 const param_attrs_uncoerced = sema.resolveInst(extra.param_attrs);
20569 const param_attrs_coerced = try sema.coerce(block, param_attrs_ty, param_attrs_uncoerced, param_attrs_src);19971 const param_attrs_coerced = try sema.coerce(block, param_attrs_ty, param_attrs_uncoerced, param_attrs_src);
20570 const param_attrs_slice = try sema.resolveConstDefinedValue(block, param_attrs_src, param_attrs_coerced, .{ .simple = .fn_param_attrs });19972 const param_attrs_slice = try sema.resolveConstDefinedValue(block, param_attrs_src, param_attrs_coerced, .{ .simple = .fn_param_attrs });
20571 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });19973 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });
2057219974
20573 const ret_ty = try sema.resolveType(block, ret_ty_src, extra.ret_ty);19975 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);
20576 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);19978 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);
20577 const fn_attrs_val = try sema.resolveConstDefinedValue(block, fn_attrs_src, fn_attrs_coerced, .{ .simple = .fn_attrs });19979 const fn_attrs_val = try sema.resolveConstDefinedValue(block, fn_attrs_src, fn_attrs_coerced, .{ .simple = .fn_attrs });
20578 const fn_attrs = try sema.interpretBuiltinType(block, fn_attrs_src, fn_attrs_val, std.builtin.Type.Fn.Attributes);19980 const fn_attrs = try sema.interpretBuiltinType(block, fn_attrs_src, fn_attrs_val, std.builtin.Type.Fn.Attributes);
...@@ -20587,17 +19989,15 @@ fn zirReifyFn(...@@ -20587,17 +19989,15 @@ fn zirReifyFn(
20587 try param_attrs_arr.elemValue(pt, param_idx),19989 try param_attrs_arr.elemValue(pt, param_idx),
20588 std.builtin.Type.Fn.Param.Attributes,19990 std.builtin.Type.Fn.Param.Attributes,
20589 );19991 );
20590 try sema.checkParamTypeCommon(19992 try sema.checkParamType(
20591 block,19993 block,
20592 @intCast(param_idx),19994 @intCast(param_idx),
20593 param_ty,19995 param_ty,
19996 false,
20594 param_attrs.@"noalias",19997 param_attrs.@"noalias",
20595 param_types_src,19998 param_types_src,
20596 fn_attrs.@"callconv",19999 fn_attrs.@"callconv",
20597 );20000 );
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 }
20601 if (param_attrs.@"noalias") {20001 if (param_attrs.@"noalias") {
20602 if (param_idx > 31) {20002 if (param_idx > 31) {
20603 return sema.fail(block, param_attrs_src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{});20003 return sema.fail(block, param_attrs_src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{});
...@@ -20611,7 +20011,7 @@ fn zirReifyFn(...@@ -20611,7 +20011,7 @@ fn zirReifyFn(
20611 try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv");20011 try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv");
20612 }20012 }
2061320013
20614 try sema.checkReturnTypeAndCallConvCommon(20014 try sema.checkReturnTypeAndCallConv(
20615 block,20015 block,
20616 ret_ty,20016 ret_ty,
20617 ret_ty_src,20017 ret_ty_src,
...@@ -20621,9 +20021,6 @@ fn zirReifyFn(...@@ -20621,9 +20021,6 @@ fn zirReifyFn(
20621 false,20021 false,
20622 false,20022 false,
20623 );20023 );
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
20628 return .fromIntern(try ip.getFuncType(gpa, io, pt.tid, .{20025 return .fromIntern(try ip.getFuncType(gpa, io, pt.tid, .{
20629 .param_types = param_types_ip,20026 .param_types = param_types_ip,
...@@ -20632,7 +20029,6 @@ fn zirReifyFn(...@@ -20632,7 +20029,6 @@ fn zirReifyFn(
20632 .return_type = ret_ty.toIntern(),20029 .return_type = ret_ty.toIntern(),
20633 .cc = fn_attrs.@"callconv",20030 .cc = fn_attrs.@"callconv",
20634 .is_var_args = fn_attrs.varargs,20031 .is_var_args = fn_attrs.varargs,
20635 .is_generic = false,
20636 .is_noinline = false,20032 .is_noinline = false,
20637 }));20033 }));
20638}20034}
...@@ -20653,6 +20049,7 @@ fn zirReifyStruct(...@@ -20653,6 +20049,7 @@ fn zirReifyStruct(
20653 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);20049 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
20654 const extra = sema.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;20050 const extra = sema.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
20655 const tracked_inst = try block.trackZir(inst);20051 const tracked_inst = try block.trackZir(inst);
20052
20656 const src: LazySrcLoc = .{20053 const src: LazySrcLoc = .{
20657 .base_node_inst = tracked_inst,20054 .base_node_inst = tracked_inst,
20658 .offset = .nodeOffset(.zero),20055 .offset = .nodeOffset(.zero),
...@@ -20697,16 +20094,16 @@ fn zirReifyStruct(...@@ -20697,16 +20094,16 @@ fn zirReifyStruct(
20697 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");20094 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");
20698 const single_field_attrs_ty = try sema.getBuiltinType(field_attrs_src, .@"Type.StructField.Attributes");20095 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);
20701 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);20098 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);
20702 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .struct_layout });20099 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .struct_layout });
20703 const layout = try sema.interpretBuiltinType(block, layout_src, layout_val, std.builtin.Type.ContainerLayout);20100 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);
20706 const backing_int_ty_coerced = try sema.coerce(block, .optional_type, backing_int_ty_uncoerced, backing_ty_src);20103 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);
20710 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);20107 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
20711 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .struct_field_names });20108 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .struct_field_names });
20712 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .struct_field_names });20109 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .struct_field_names });
...@@ -20722,12 +20119,12 @@ fn zirReifyStruct(...@@ -20722,12 +20119,12 @@ fn zirReifyStruct(
20722 .child = single_field_attrs_ty.toIntern(),20119 .child = single_field_attrs_ty.toIntern(),
20723 }));20120 }));
2072420121
20725 const field_types_uncoerced = try sema.resolveInst(extra.field_types);20122 const field_types_uncoerced = sema.resolveInst(extra.field_types);
20726 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);20123 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);
20727 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .struct_field_types });20124 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .struct_field_types });
20728 const field_types_arr = try sema.derefSliceAsArray(block, field_types_src, field_types_slice, .{ .simple = .struct_field_types });20125 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);
20731 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);20128 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);
20732 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .struct_field_attrs });20129 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .struct_field_attrs });
20733 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .struct_field_attrs });20130 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .struct_field_attrs });
...@@ -20744,19 +20141,30 @@ fn zirReifyStruct(...@@ -20744,19 +20141,30 @@ fn zirReifyStruct(
20744 return sema.failWithUseOfUndef(block, backing_ty_src, null);20141 return sema.failWithUseOfUndef(block, backing_ty_src, null);
20745 }20142 }
2074620143
20747 // The validation work here is non-trivial, and it's possible the type already exists.20144 // Most validation of this type happens during type resolution. We basically need to do the work
20748 // So in this first pass, let's just construct a hash to optimize for this case. If the20145 // which AstGen would normally do. An exception is checking for duplicate field names, which is
20749 // inputs turn out to be invalid, we can cancel the WIP type later.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
20751 var any_comptime_fields = false;20151 var any_comptime_fields = false;
20752 var any_default_inits = false;20152 var any_field_defaults = false;
20753 var any_aligned_fields = false;20153 var any_field_aligns = false;
2075420154
20755 // For deduplication purposes, we must create a hash including all details of this type.
20756 // TODO: use a longer hash!20155 // TODO: use a longer hash!
20757 var hasher = std.hash.Wyhash.init(0);20156 var hasher = std.hash.Wyhash.init(0);
20758 std.hash.autoHash(&hasher, layout);20157 std.hash.autoHash(&hasher, layout);
20759 std.hash.autoHash(&hasher, backing_int_ty_val);20158 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
20760 // The field *type* array has already been deduplicated for us thanks to the InternPool!20168 // The field *type* array has already been deduplicated for us thanks to the InternPool!
20761 std.hash.autoHash(&hasher, field_types_arr);20169 std.hash.autoHash(&hasher, field_types_arr);
20762 // However, for field names and attributes, we need to actually iterate the individual fields,20170 // However, for field names and attributes, we need to actually iterate the individual fields,
...@@ -20791,207 +20199,119 @@ fn zirReifyStruct(...@@ -20791,207 +20199,119 @@ fn zirReifyStruct(
20791 field_attrs_src,20199 field_attrs_src,
20792 .{ .simple = .struct_field_default_value },20200 .{ .simple = .struct_field_default_value },
20793 );20201 );
20794 // Resolve the value so that lazy values do not create distinct types.20202 if (deref_val.canMutateComptimeVarState(zcu)) {
20795 break :d (try sema.resolveLazyValue(deref_val)).toIntern();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();
20796 };20207 };
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
20798 std.hash.autoHash(&hasher, .{20228 std.hash.autoHash(&hasher, .{
20799 field_name,20229 field_name,
20800 field_attr_comptime,20230 field_attr_comptime,
20801 field_attr_align,20231 field_attr_align,
20802 field_default,20232 field_default,
20803 });20233 });
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});
20823 }20234 }
2082420235
20825 const wip_ty = switch (try ip.getStructType(gpa, io, pt.tid, .{20236 switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
20826 .layout = layout,20237 .zir_index = tracked_inst,
20238 .type_hash = hasher.final(),
20827 .fields_len = @intCast(fields_len),20239 .fields_len = @intCast(fields_len),
20828 .known_non_opv = false,20240 .layout = layout,
20829 .requires_comptime = .unknown,
20830 .any_comptime_fields = any_comptime_fields,20241 .any_comptime_fields = any_comptime_fields,
20831 .any_default_inits = any_default_inits,20242 .any_field_defaults = any_field_defaults,
20832 .any_aligned_fields = any_aligned_fields,20243 .any_field_aligns = any_field_aligns,
20833 .inits_resolved = true,20244 .packed_backing_int_type = if (backing_int_ty) |ty| ty.toIntern() else .none,
20834 .key = .{ .reified = .{20245 })) {
20835 .zir_index = tracked_inst,
20836 .type_hash = hasher.final(),
20837 } },
20838 }, false)) {
20839 .wip => |wip| wip,
20840 .existing => |ty| {20246 .existing => |ty| {
20841 try sema.declareDependency(.{ .interned = ty });20247 try sema.addTypeReferenceEntry(src, .fromInterned(ty));
20842 try sema.addTypeReferenceEntry(src, ty);20248 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
20843 return Air.internedToRef(ty);20249 return .fromIntern(ty);
20844 },20250 },
20845 };20251 .wip => |wip| {
20846 errdefer wip_ty.cancel(ip, pt.tid);20252 errdefer wip.cancel(ip, pt.tid);
2084720253 try sema.setTypeName(block, &wip, name_strategy, "struct", inst);
20848 const type_name = try sema.createTypeName(20254 for (0..fields_len) |field_idx| {
20849 block,20255 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
20850 name_strategy,20256 const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx);
20851 "struct",20257
20852 inst,20258 // No source location or reason; first loop checked this is valid.
20853 wip_ty.index,20259 const field_name = try sema.sliceToIpString(block, .unneeded, field_name_val, undefined);
20854 );20260 wip.field_names.get(ip)[field_idx] = field_name;
20855 wip_ty.setName(ip, type_name.name, type_name.nav);20261
2085620262 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
20857 const wip_struct_type = ip.loadStructType(wip_ty.index);20263 wip.field_types.get(ip)[field_idx] = field_ty.toIntern();
2085820264
20859 for (0..fields_len) |field_idx| {20265 const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20860 const field_name_val = try field_names_arr.elemValue(pt, field_idx);20266 std.builtin.Type.StructField.Attributes,
20861 const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx);20267 "comptime",
2086220268 ).?);
20863 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();20269 const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
2086420270 std.builtin.Type.StructField.Attributes,
20865 // Don't pass a reason; first loop acts as a check that this is valid.20271 "align",
20866 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);20272 ).?);
20867 if (wip_struct_type.addFieldName(ip, field_name)) |prev_index| {20273 const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20868 _ = prev_index; // TODO: better source location20274 std.builtin.Type.StructField.Attributes,
20869 return sema.fail(block, field_names_src, "duplicate struct field name {f}", .{field_name.fmt(ip)});20275 "default_value_ptr",
20870 }20276 ).?);
2087120277
20872 const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(20278 if (field_attr_comptime.toBool()) {
20873 std.builtin.Type.StructField.Attributes,20279 const bit_bag_index = field_idx / 32;
20874 "comptime",20280 const mask = @as(u32, 1) << @intCast(field_idx % 32);
20875 ).?);20281 wip.field_is_comptime_bits.getAll(ip)[bit_bag_index] |= mask;
20876 const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(20282 }
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 }
2089420283
20895 const field_default: InternPool.Index = d: {20284 if (field_attr_default_value_ptr.optionalValue(zcu)) |ptr_val| {
20896 const ptr_val = field_attr_default_value_ptr.optionalValue(zcu) orelse break :d .none;20285 const ptr_ty = try pt.singleConstPtrType(field_ty);
20897 assert(any_default_inits);20286 // No source location; first loop checked this is valid.
20898 const ptr_ty = try pt.singleConstPtrType(field_ty);20287 const deref_val = (try sema.pointerDeref(block, .unneeded, ptr_val, ptr_ty)).?;
20899 // The first loop checked that this is comptime-dereferencable.20288 wip.field_values.get(ip)[field_idx] = deref_val.toIntern();
20900 const deref_val = (try sema.pointerDeref(block, field_attrs_src, ptr_val, ptr_ty)).?;20289 } else if (any_field_defaults) {
20901 // ...but we've not checked this yet!20290 wip.field_values.get(ip)[field_idx] = .none;
20902 if (deref_val.canMutateComptimeVarState(zcu)) {20291 }
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 };
2090720292
20908 if (field_attr_comptime.toBool()) {20293 if (field_attr_align.optionalValue(zcu)) |field_align_val| {
20909 assert(layout == .auto);20294 const bytes = field_align_val.toUnsignedInt(zcu);
20910 if (field_default == .none) {20295 // No source location; first loop checked this is valid.
20911 return sema.fail(block, field_attrs_src, "comptime field without default initialization value", .{});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 }
20912 }20301 }
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 });20303 const new_namespace_index = try pt.createNamespace(.{
20984 codegen_type: {20304 .parent = block.namespace.toOptional(),
20985 if (zcu.comp.config.use_llvm) break :codegen_type;20305 .owner_type = wip.index,
20986 if (block.ownerModule().strip) break :codegen_type;20306 .file_scope = block.getFileScopeIndex(zcu),
20987 // This job depends on any resolve_type_fully jobs queued up before it.20307 .generation = zcu.generation,
20988 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);20308 });
20989 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });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 },
20990 }20314 }
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));
20995}20315}
2099620316
20997fn zirReifyUnion(20317fn zirReifyUnion(
...@@ -21054,16 +20374,19 @@ fn zirReifyUnion(...@@ -21054,16 +20374,19 @@ fn zirReifyUnion(
21054 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");20374 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");
21055 const single_field_attrs_ty = try sema.getBuiltinType(field_attrs_src, .@"Type.UnionField.Attributes");20375 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);
21058 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);20378 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);
21059 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .union_layout });20379 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .union_layout });
21060 const layout = try sema.interpretBuiltinType(block, layout_src, layout_val, std.builtin.Type.ContainerLayout);20380 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);
21063 const arg_ty_coerced = try sema.coerce(block, .optional_type, arg_ty_uncoerced, arg_ty_src);20383 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);
21067 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);20390 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
21068 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .union_field_names });20391 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .union_field_names });
21069 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .union_field_names });20392 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .union_field_names });
...@@ -21079,12 +20402,12 @@ fn zirReifyUnion(...@@ -21079,12 +20402,12 @@ fn zirReifyUnion(
21079 .child = single_field_attrs_ty.toIntern(),20402 .child = single_field_attrs_ty.toIntern(),
21080 }));20403 }));
2108120404
21082 const field_types_uncoerced = try sema.resolveInst(extra.field_types);20405 const field_types_uncoerced = sema.resolveInst(extra.field_types);
21083 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);20406 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);
21084 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .union_field_types });20407 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .union_field_types });
21085 const field_types_arr = try sema.derefSliceAsArray(block, field_types_src, field_types_slice, .{ .simple = .union_field_types });20408 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);
21088 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);20411 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);
21089 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .union_field_attrs });20412 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .union_field_attrs });
21090 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .union_field_attrs });20413 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .union_field_attrs });
...@@ -21101,17 +20424,29 @@ fn zirReifyUnion(...@@ -21101,17 +20424,29 @@ fn zirReifyUnion(
21101 return sema.failWithUseOfUndef(block, arg_ty_src, null);20424 return sema.failWithUseOfUndef(block, arg_ty_src, null);
21102 }20425 }
2110320426
21104 // The validation work here is non-trivial, and it's possible the type already exists.20427 // Most validation of this type happens during type resolution. We basically need to do the work
21105 // So in this first pass, let's just construct a hash to optimize for this case. If the20428 // which AstGen would normally do. An exception is checking for duplicate field names, which is
21106 // inputs turn out to be invalid, we can cancel the WIP type later.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.
21111 // TODO: use a longer hash!20436 // TODO: use a longer hash!
21112 var hasher = std.hash.Wyhash.init(0);20437 var hasher = std.hash.Wyhash.init(0);
21113 std.hash.autoHash(&hasher, layout);20438 std.hash.autoHash(&hasher, layout);
21114 std.hash.autoHash(&hasher, arg_ty_val);20439 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
21115 // `field_types_arr` and `field_attrs_arr` are already deduplicated by the InternPool!20450 // `field_types_arr` and `field_attrs_arr` are already deduplicated by the InternPool!
21116 std.hash.autoHash(&hasher, field_types_arr);20451 std.hash.autoHash(&hasher, field_types_arr);
21117 std.hash.autoHash(&hasher, field_attrs_arr);20452 std.hash.autoHash(&hasher, field_attrs_arr);
...@@ -21128,203 +20463,76 @@ fn zirReifyUnion(...@@ -21128,203 +20463,76 @@ fn zirReifyUnion(
21128 try field_attrs_arr.elemValue(pt, field_idx),20463 try field_attrs_arr.elemValue(pt, field_idx),
21129 std.builtin.Type.UnionField.Attributes,20464 std.builtin.Type.UnionField.Attributes,
21130 );20465 );
21131 if (field_attrs.@"align" != null) {20466 if (field_attrs.@"align") |bytes| {
21132 any_aligned_fields = true;20467 if (layout == .@"packed") {
21133 }20468 return sema.fail(block, field_attrs_src, "packed union fields cannot be aligned", .{});
21134 }20469 }
2113520470 // Trigger a compile error if the alignment is invalid.
21136 // Some basic validation to avoid a bogus `getUnionType` call...20471 _ = try sema.validateAlign(block, field_attrs_src, bytes);
21137 const explicit_tag_ty: ?Type = if (arg_ty_val.optionalValue(zcu)) |arg_ty| ty: {20472 any_field_aligns = true;
21138 switch (layout) {
21139 .@"extern", .@"packed" => return sema.fail(block, arg_ty_src, "{t} union does not support enum tag type", .{layout}),
21140 .auto => {},
21141 }20473 }
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", .{});
21146 }20474 }
2114720475
21148 const wip_ty = switch (try ip.getUnionType(gpa, io, pt.tid, .{20476 switch (try ip.getReifiedUnionType(gpa, io, pt.tid, .{
21149 .flags = .{20477 .zir_index = tracked_inst,
21150 .layout = layout,20478 .type_hash = hasher.final(),
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 },
21163 .fields_len = @intCast(fields_len),20479 .fields_len = @intCast(fields_len),
21164 .enum_tag_ty = .none, // set later because not yet validated20480 .layout = layout,
21165 .field_types = &.{}, // set later20481 .any_field_aligns = any_field_aligns,
21166 .field_aligns = &.{}, // set later20482 .tag_usage = tag: {
21167 .key = .{ .reified = .{20483 if (explicit_tag_ty != null) break :tag .tagged;
21168 .zir_index = tracked_inst,20484 if (layout == .auto and block.wantSafeTypes()) break :tag .safety;
21169 .type_hash = hasher.final(),20485 break :tag .none;
21170 } },20486 },
21171 }, false)) {20487 .enum_tag_type = if (explicit_tag_ty) |ty| ty.toIntern() else .none,
21172 .wip => |wip| wip,20488 .packed_backing_int_type = if (explicit_packed_backing_type) |ty| ty.toIntern() else .none,
20489 })) {
21173 .existing => |ty| {20490 .existing => |ty| {
21174 try sema.declareDependency(.{ .interned = ty });20491 try sema.addTypeReferenceEntry(src, .fromInterned(ty));
21175 try sema.addTypeReferenceEntry(src, ty);20492 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
21176 return Air.internedToRef(ty);20493 return .fromIntern(ty);
21177 },20494 },
21178 };20495 .wip => |wip| {
21179 errdefer wip_ty.cancel(ip, pt.tid);20496 errdefer wip.cancel(ip, pt.tid);
2118020497 try sema.setTypeName(block, &wip, name_strategy, "union", inst);
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 }
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| {20505 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
21200 const field_name_val = try field_names_arr.elemValue(pt, field_idx);20506 wip.field_types.get(ip)[field_idx] = field_ty.toIntern();
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);
2120320507
21204 if (field_idx >= tag_ty_fields_len) {20508 // No source location; first loop checked this is valid.
21205 return sema.fail(block, field_names_src, "no field named '{f}' in enum '{f}'", .{20509 const field_attrs = try sema.interpretBuiltinType(
21206 field_name.fmt(ip), enum_tag_ty.fmt(pt),20510 block,
21207 });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 }
21208 }20522 }
2120920523
21210 const enum_field_name = enum_tag_ty.enumFieldName(field_idx, zcu);20524 const new_namespace_index = try pt.createNamespace(.{
21211 if (enum_field_name != field_name) {20525 .parent = block.namespace.toOptional(),
21212 return sema.fail(block, field_names_src, "union field name '{f}' does not match enum field name '{f}'", .{20526 .owner_type = wip.index,
21213 field_name.fmt(ip), enum_field_name.fmt(ip),20527 .file_scope = block.getFileScopeIndex(zcu),
21214 });20528 .generation = zcu.generation,
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,
21220 });20529 });
21221 errdefer msg.destroy(gpa);20530 errdefer pt.destroyNamespace(new_namespace_index);
21222 for (fields_len..tag_ty_fields_len) |enum_field_idx| {20531 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
21223 try sema.addFieldErrNote(enum_tag_ty, enum_field_idx, msg, "field '{f}' missing, declared here", .{20532 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
21224 enum_tag_ty.enumFieldName(enum_field_idx, zcu).fmt(ip),20533 return .fromIntern(wip.finish(ip, new_namespace_index));
21225 });20534 },
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 });
21323 }20535 }
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));
21328}20536}
2132920537
21330fn zirReifyEnum(20538fn zirReifyEnum(
...@@ -21379,12 +20587,12 @@ fn zirReifyEnum(...@@ -21379,12 +20587,12 @@ fn zirReifyEnum(
2137920587
21380 const enum_mode_ty = try sema.getBuiltinType(mode_src, .@"Type.Enum.Mode");20588 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);20590 const tag_ty_uncoerced = sema.resolveInst(extra.tag_ty);
21383 if (tag_ty.zigTypeTag(zcu) != .int) {20591 const tag_ty_coerced = try sema.coerce(block, .type, tag_ty_uncoerced, tag_ty_src);
21384 return sema.fail(block, tag_ty_src, "tag type must be an integer type", .{});20592 const tag_ty_val = try sema.resolveConstDefinedValue(block, tag_ty_src, tag_ty_coerced, .{ .simple = .enum_int_tag_type });
21385 }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);
21388 const mode_coerced = try sema.coerce(block, enum_mode_ty, mode_uncoerced, mode_src);20596 const mode_coerced = try sema.coerce(block, enum_mode_ty, mode_uncoerced, mode_src);
21389 const mode_val = try sema.resolveConstDefinedValue(block, mode_src, mode_coerced, .{ .simple = .type });20597 const mode_val = try sema.resolveConstDefinedValue(block, mode_src, mode_coerced, .{ .simple = .type });
21390 const nonexhaustive = switch (try sema.interpretBuiltinType(block, mode_src, mode_val, std.builtin.Type.Enum.Mode)) {20598 const nonexhaustive = switch (try sema.interpretBuiltinType(block, mode_src, mode_val, std.builtin.Type.Enum.Mode)) {
...@@ -21392,7 +20600,7 @@ fn zirReifyEnum(...@@ -21392,7 +20600,7 @@ fn zirReifyEnum(
21392 .nonexhaustive => true,20600 .nonexhaustive => true,
21393 };20601 };
2139420602
21395 const field_names_uncoerced = try sema.resolveInst(extra.field_names);20603 const field_names_uncoerced = sema.resolveInst(extra.field_names);
21396 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);20604 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
21397 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .enum_field_names });20605 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .enum_field_names });
21398 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .enum_field_names });20606 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .enum_field_names });
...@@ -21404,7 +20612,7 @@ fn zirReifyEnum(...@@ -21404,7 +20612,7 @@ fn zirReifyEnum(
21404 .child = tag_ty.toIntern(),20612 .child = tag_ty.toIntern(),
21405 }));20613 }));
2140620614
21407 const field_values_uncoerced = try sema.resolveInst(extra.field_values);20615 const field_values_uncoerced = sema.resolveInst(extra.field_values);
21408 const field_values_coerced = try sema.coerce(block, field_values_ty, field_values_uncoerced, field_values_src);20616 const field_values_coerced = try sema.coerce(block, field_values_ty, field_values_uncoerced, field_values_src);
21409 const field_values_slice = try sema.resolveConstDefinedValue(block, field_values_src, field_values_coerced, .{ .simple = .enum_field_values });20617 const field_values_slice = try sema.resolveConstDefinedValue(block, field_values_src, field_values_coerced, .{ .simple = .enum_field_values });
21410 const field_values_arr = try sema.derefSliceAsArray(block, field_values_src, field_values_slice, .{ .simple = .enum_field_values });20618 const field_values_arr = try sema.derefSliceAsArray(block, field_values_src, field_values_slice, .{ .simple = .enum_field_values });
...@@ -21415,11 +20623,13 @@ fn zirReifyEnum(...@@ -21415,11 +20623,13 @@ fn zirReifyEnum(
21415 }20623 }
21416 // We don't need to check `field_names_arr`, because `sliceToIpString` will check that for us.20624 // 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.20626 // Most validation of this type happens during type resolution. We basically need to do the work
21419 // So in this first pass, let's just construct a hash to optimize for this case. If the20627 // which AstGen would normally do. An exception is checking for duplicate field names, which is
21420 // inputs turn out to be invalid, we can cancel the WIP type later.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.
21423 // TODO: use a longer hash!20633 // TODO: use a longer hash!
21424 var hasher = std.hash.Wyhash.init(0);20634 var hasher = std.hash.Wyhash.init(0);
21425 std.hash.autoHash(&hasher, tag_ty.toIntern());20635 std.hash.autoHash(&hasher, tag_ty.toIntern());
...@@ -21435,87 +20645,46 @@ fn zirReifyEnum(...@@ -21435,87 +20645,46 @@ fn zirReifyEnum(
21435 std.hash.autoHash(&hasher, field_name);20645 std.hash.autoHash(&hasher, field_name);
21436 }20646 }
2143720647
21438 const wip_ty = switch (try ip.getEnumType(gpa, io, pt.tid, .{20648 switch (try ip.getReifiedEnumType(gpa, io, pt.tid, .{
21439 .has_values = true,20649 .zir_index = tracked_inst,
21440 .tag_mode = if (nonexhaustive) .nonexhaustive else .explicit,20650 .type_hash = hasher.final(),
21441 .fields_len = @intCast(fields_len),20651 .fields_len = @intCast(fields_len),
21442 .key = .{ .reified = .{20652 .nonexhaustive = nonexhaustive,
21443 .zir_index = tracked_inst,20653 .int_tag_type = tag_ty.toIntern(),
21444 .type_hash = hasher.final(),20654 })) {
21445 } },
21446 }, false)) {
21447 .wip => |wip| wip,
21448 .existing => |ty| {20655 .existing => |ty| {
21449 try sema.declareDependency(.{ .interned = ty });20656 try sema.addTypeReferenceEntry(src, .fromInterned(ty));
21450 try sema.addTypeReferenceEntry(src, ty);20657 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
21451 return .fromIntern(ty);20658 return .fromIntern(ty);
21452 },20659 },
21453 };20660 .wip => |wip| {
21454 var done = false;20661 errdefer wip.cancel(ip, pt.tid);
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 });
2147220662
21473 try sema.declareDependency(.{ .interned = wip_ty.index });20663 try sema.setTypeName(block, &wip, name_strategy, "enum", inst);
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;
2147920664
21480 for (0..fields_len) |field_idx| {20665 // Populate field names and values. Duplicate checking will be handled by type resolution.
21481 const field_name_val = try field_names_arr.elemValue(pt, field_idx);20666 for (0..fields_len) |field_index| {
21482 // Don't pass a reason; first loop acts as a check that this is valid.20667 const field_name_val = try field_names_arr.elemValue(pt, field_index);
21483 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);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| {20676 const new_namespace_index = try pt.createNamespace(.{
21488 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {20677 .parent = block.namespace.toOptional(),
21489 .name => msg: {20678 .owner_type = wip.index,
21490 const msg = try sema.errMsg(field_names_src, "duplicate enum field '{f}'", .{field_name.fmt(ip)});20679 .file_scope = block.getFileScopeIndex(zcu),
21491 errdefer msg.destroy(gpa);20680 .generation = zcu.generation,
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 },
21503 });20681 });
21504 }20682 errdefer pt.destroyNamespace(new_namespace_index);
21505 }20683 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
2150620684 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
21507 if (nonexhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(zcu)) {20685 return .fromIntern(wip.finish(ip, new_namespace_index));
21508 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});20686 },
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 });
21517 }20687 }
21518 return Air.internedToRef(wip_ty.index);
21519}20688}
2152020689
21521fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {20690fn 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...@@ -21523,7 +20692,7 @@ fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.In
21523 const va_list_ty = try sema.getBuiltinType(src, .VaList);20692 const va_list_ty = try sema.getBuiltinType(src, .VaList);
21524 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);20693 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);
21527 return sema.coerce(block, va_list_ptr, inst, src);20696 return sema.coerce(block, va_list_ptr, inst, src);
21528}20697}
2152920698
...@@ -21535,8 +20704,8 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -21535,8 +20704,8 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2153520704
21536 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs);20705 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs);
21537 const arg_ty = try sema.resolveType(block, ty_src, extra.rhs);20706 const arg_ty = try sema.resolveType(block, ty_src, extra.rhs);
2153820707 try sema.ensureLayoutResolved(arg_ty, ty_src, .parameter);
21539 if (!try sema.validateExternType(arg_ty, .param_ty)) {20708 if (!arg_ty.validateExtern(.param_ty, sema.pt.zcu)) {
21540 const msg = msg: {20709 const msg = msg: {
21541 const msg = try sema.errMsg(ty_src, "cannot get '{f}' from variadic argument", .{arg_ty.fmt(sema.pt)});20710 const msg = try sema.errMsg(ty_src, "cannot get '{f}' from variadic argument", .{arg_ty.fmt(sema.pt)});
21542 errdefer msg.destroy(sema.gpa);20711 errdefer msg.destroy(sema.gpa);
...@@ -21573,7 +20742,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -21573,7 +20742,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
21573 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);20742 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
2157420743
21575 try sema.requireRuntimeBlock(block, src, null);20744 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;
21577}20747}
2157820748
21579fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {20749fn 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...@@ -21618,7 +20788,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
21618 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;20788 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
21619 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);20789 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
21620 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intFromFloat");20790 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);
21622 const operand_ty = sema.typeOf(operand);20792 const operand_ty = sema.typeOf(operand);
2162320793
21624 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src);20794 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...@@ -21630,7 +20800,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
21630 _ = try sema.checkIntType(block, src, dest_scalar_ty);20800 _ = try sema.checkIntType(block, src, dest_scalar_ty);
21631 try sema.checkFloatType(block, operand_src, operand_scalar_ty);20801 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| {
21634 const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, .truncate);20804 const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, .truncate);
21635 return Air.internedToRef(result_val.toIntern());20805 return Air.internedToRef(result_val.toIntern());
21636 } else if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_int) {20806 } else if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_int) {
...@@ -21671,7 +20841,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -21671,7 +20841,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
21671 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;20841 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
21672 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);20842 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
21673 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatFromInt");20843 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);
21675 const operand_ty = sema.typeOf(operand);20845 const operand_ty = sema.typeOf(operand);
2167620846
21677 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src);20847 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...@@ -21682,9 +20852,21 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
21682 try sema.checkFloatType(block, src, dest_scalar_ty);20852 try sema.checkFloatType(block, src, dest_scalar_ty);
21683 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);20853 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);
2168420854
21685 if (try sema.resolveValue(operand)) |operand_val| {20855 if (sema.resolveValue(operand)) |operand_val| {
21686 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, pt, .sema);20856 if (operand_val.isUndef(zcu)) return .fromValue(try pt.undefValue(dest_ty));
21687 return Air.internedToRef(result_val.toIntern());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));
21688 } else if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_float) {20870 } else if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_float) {
21689 return sema.failWithNeededComptime(block, operand_src, .{ .simple = .casted_to_comptime_float });20871 return sema.failWithNeededComptime(block, operand_src, .{ .simple = .casted_to_comptime_float });
21690 }20872 }
...@@ -21702,7 +20884,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -21702,7 +20884,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
21702 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;20884 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2170320885
21704 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);20886 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
21707 const uncoerced_operand_ty = sema.typeOf(operand_res);20889 const uncoerced_operand_ty = sema.typeOf(operand_res);
21708 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrFromInt");20890 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!...@@ -21719,8 +20901,10 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
21719 const ptr_ty = dest_ty.scalarType(zcu);20901 const ptr_ty = dest_ty.scalarType(zcu);
21720 try sema.checkPtrType(block, src, ptr_ty, true);20902 try sema.checkPtrType(block, src, ptr_ty, true);
2172120903
21722 const elem_ty = ptr_ty.elemType2(zcu);20904 const elem_ty = ptr_ty.nullablePtrElem(zcu);
21723 const ptr_align = try ptr_ty.ptrAlignmentSema(pt);20905
20906 try sema.ensureLayoutResolved(elem_ty, src, .align_check);
20907 const ptr_align = ptr_ty.ptrAlignment(zcu);
2172420908
21725 if (ptr_ty.isSlice(zcu)) {20909 if (ptr_ty.isSlice(zcu)) {
21726 const msg = msg: {20910 const msg = msg: {
...@@ -21746,18 +20930,9 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -21746,18 +20930,9 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
21746 }20930 }
21747 return Air.internedToRef((try pt.aggregateValue(dest_ty, new_elems)).toIntern());20931 return Air.internedToRef((try pt.aggregateValue(dest_ty, new_elems)).toIntern());
21748 }20932 }
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 }
21758 try sema.requireRuntimeBlock(block, src, operand_src);20933 try sema.requireRuntimeBlock(block, src, operand_src);
21759 try sema.checkLogicalPtrOperation(block, src, ptr_ty);20934 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()) {
21761 if (!ptr_ty.isAllowzeroPtr(zcu)) {20936 if (!ptr_ty.isAllowzeroPtr(zcu)) {
21762 const is_non_zero = if (is_vector) all_non_zero: {20937 const is_non_zero = if (is_vector) all_non_zero: {
21763 const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern());20938 const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern());
...@@ -21804,7 +20979,7 @@ fn ptrFromIntVal(...@@ -21804,7 +20979,7 @@ fn ptrFromIntVal(
21804 }20979 }
21805 return sema.failWithUseOfUndef(block, operand_src, vec_idx);20980 return sema.failWithUseOfUndef(block, operand_src, vec_idx);
21806 }20981 }
21807 const addr = try operand_val.toUnsignedIntSema(pt);20982 const addr = operand_val.toUnsignedInt(zcu);
21808 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)20983 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
21809 return sema.fail(block, operand_src, "pointer type '{f}' does not allow address zero", .{ptr_ty.fmt(pt)});20984 return sema.fail(block, operand_src, "pointer type '{f}' does not allow address zero", .{ptr_ty.fmt(pt)});
21810 if (addr != 0 and ptr_align != .none) {20985 if (addr != 0 and ptr_align != .none) {
...@@ -21836,7 +21011,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21836,7 +21011,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21836 const src = block.nodeOffset(extra.node);21011 const src = block.nodeOffset(extra.node);
21837 const operand_src = block.builtinCallArgSrc(extra.node, 0);21012 const operand_src = block.builtinCallArgSrc(extra.node, 0);
21838 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_opt, "@errorCast");21013 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);
21840 const operand_ty = sema.typeOf(operand);21015 const operand_ty = sema.typeOf(operand);
2184121016
21842 const dest_tag = dest_ty.zigTypeTag(zcu);21017 const dest_tag = dest_ty.zigTypeTag(zcu);
...@@ -21877,34 +21052,62 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21877,34 +21052,62 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21877 else => unreachable,21052 else => unreachable,
21878 };21053 };
2187921054
21880 const disjoint = disjoint: {21055 switch (ip.indexToKey(operand_err_ty.toIntern())) {
21881 // Try avoiding resolving inferred error sets if we can21056 .inferred_error_set_type => |func| try sema.ensureFuncIesResolved(block, src, func),
21882 if (!dest_err_ty.isAnyError(zcu) and dest_err_ty.errorSetIsEmpty(zcu)) break :disjoint true;21057 else => {},
21883 if (!operand_err_ty.isAnyError(zcu) and operand_err_ty.errorSetIsEmpty(zcu)) break :disjoint true;21058 }
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 }
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 },
21906 };21108 };
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)) {
21908 return sema.fail(block, src, "error sets '{f}' and '{f}' have no common errors", .{21111 return sema.fail(block, src, "error sets '{f}' and '{f}' have no common errors", .{
21909 operand_err_ty.fmt(pt), dest_err_ty.fmt(pt),21112 operand_err_ty.fmt(pt), dest_err_ty.fmt(pt),
21910 });21113 });
...@@ -21912,25 +21115,30 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21912,25 +21115,30 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2191221115
21913 // operand must be defined since it can be an invalid error value21116 // operand must be defined since it can be an invalid error value
21914 if (try sema.resolveDefinedValue(block, operand_src, operand)) |operand_val| {21117 if (try sema.resolveDefinedValue(block, operand_src, operand)) |operand_val| {
21915 const err_name: InternPool.NullTerminatedString = switch (operand_tag) {21118 const err_name: InternPool.NullTerminatedString = switch (ip.indexToKey(operand_val.toIntern())) {
21916 .error_set => ip.indexToKey(operand_val.toIntern()).err.name,21119 .err => |err| err.name,
21917 .error_union => switch (ip.indexToKey(operand_val.toIntern()).error_union.val) {21120 .error_union => |eu| switch (eu.val) {
21918 .err_name => |name| name,21121 .err_name => |name| name,
21919 .payload => |payload_val| {21122 .payload => |payload_val| {
21920 assert(dest_tag == .error_union); // should be guaranteed from the type checks above21123 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 };
21922 },21130 },
21923 },21131 },
21924 else => unreachable,21132 else => unreachable,
21925 };21133 };
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)) {
21928 return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{21136 return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{
21929 err_name.fmt(ip), dest_err_ty.fmt(pt),21137 err_name.fmt(ip), dest_err_ty.fmt(pt),
21930 });21138 });
21931 }21139 }
2193221140
21933 return Air.internedToRef(try pt.intern(switch (dest_tag) {21141 return .fromIntern(try pt.intern(switch (dest_tag) {
21934 .error_set => .{ .err = .{21142 .error_set => .{ .err = .{
21935 .ty = dest_ty.toIntern(),21143 .ty = dest_ty.toIntern(),
21936 .name = err_name,21144 .name = err_name,
...@@ -21944,21 +21152,17 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21944,21 +21152,17 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21944 }21152 }
2194521153
21946 const err_int_ty = try pt.errorIntType();21154 const err_int_ty = try pt.errorIntType();
21947 if (block.wantSafety() and !dest_err_ty.isAnyError(zcu) and21155 if (block.wantSafety() and result != .superset and zcu.backendSupportsFeature(.error_set_has_value)) {
21948 dest_err_ty.toIntern() != .adhoc_inferred_error_set_type and
21949 zcu.backendSupportsFeature(.error_set_has_value))
21950 {
21951 const err_code_inst = switch (operand_tag) {21156 const err_code_inst = switch (operand_tag) {
21952 .error_set => operand,21157 .error_set => operand,
21953 .error_union => try block.addTyOp(.unwrap_errunion_err, operand_err_ty, operand),21158 .error_union => try block.addTyOp(.unwrap_errunion_err, operand_err_ty, operand),
21954 else => unreachable,21159 else => unreachable,
21955 };21160 };
21956 const err_int_inst = try block.addBitCast(err_int_ty, err_code_inst);21161 const err_int_inst = try block.addBitCast(err_int_ty, err_code_inst);
21957
21958 if (dest_tag == .error_union) {21162 if (dest_tag == .error_union) {
21959 const zero_err = try pt.intRef(err_int_ty, 0);21163 const zero_err = try pt.intRef(err_int_ty, 0);
21960 const is_zero = try block.addBinOp(.cmp_eq, err_int_inst, zero_err);21164 const is_zero = try block.addBinOp(.cmp_eq, err_int_inst, zero_err);
21961 if (disjoint) {21165 if (result == .disjoint) {
21962 // Error must be zero.21166 // Error must be zero.
21963 try sema.addSafetyCheck(block, src, is_zero, .invalid_error_code);21167 try sema.addSafetyCheck(block, src, is_zero, .invalid_error_code);
21964 } else {21168 } else {
...@@ -21987,7 +21191,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa...@@ -21987,7 +21191,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
21987 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;21191 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
21988 const src = block.nodeOffset(extra.node);21192 const src = block.nodeOffset(extra.node);
21989 const operand_src = block.src(.{ .node_offset_ptrcast_operand = extra.node });21193 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);
21991 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName());21195 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName());
21992 return sema.ptrCastFull(21196 return sema.ptrCastFull(
21993 block,21197 block,
...@@ -22006,7 +21210,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -22006,7 +21210,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
22006 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21210 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22007 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;21211 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
22008 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrCast");21212 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
22011 return sema.ptrCastFull(21215 return sema.ptrCastFull(
22012 block,21216 block,
...@@ -22043,8 +21247,8 @@ fn ptrCastFull(...@@ -22043,8 +21247,8 @@ fn ptrCastFull(
22043 const src_info = operand_ty.ptrInfo(zcu);21247 const src_info = operand_ty.ptrInfo(zcu);
22044 const dest_info = dest_ty.ptrInfo(zcu);21248 const dest_info = dest_ty.ptrInfo(zcu);
2204521249
22046 try Type.fromInterned(src_info.child).resolveLayout(pt);21250 try sema.ensureLayoutResolved(.fromInterned(src_info.child), operand_src, .align_check);
22047 try Type.fromInterned(dest_info.child).resolveLayout(pt);21251 try sema.ensureLayoutResolved(.fromInterned(dest_info.child), src, .align_check);
2204821252
22049 const DestSliceLen = union(enum) {21253 const DestSliceLen = union(enum) {
22050 undef,21254 undef,
...@@ -22072,16 +21276,16 @@ fn ptrCastFull(...@@ -22072,16 +21276,16 @@ fn ptrCastFull(
22072 };21276 };
22073 },21277 },
22074 .slice => src: {21278 .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 };
22076 if (operand_val.isUndef(zcu)) break :len .undef;21280 if (operand_val.isUndef(zcu)) break :len .undef;
22077 const slice_val = switch (operand_ty.zigTypeTag(zcu)) {21281 const slice_val = switch (operand_ty.zigTypeTag(zcu)) {
22078 .optional => operand_val.optionalValue(zcu) orelse break :len .undef,21282 .optional => operand_val.optionalValue(zcu) orelse break :len .undef,
22079 .pointer => operand_val,21283 .pointer => operand_val,
22080 else => unreachable,21284 else => unreachable,
22081 };21285 };
22082 const slice_len_resolved = try sema.resolveLazyValue(.fromInterned(zcu.intern_pool.sliceLen(slice_val.toIntern())));21286 const slice_len: Value = .fromInterned(zcu.intern_pool.sliceLen(slice_val.toIntern()));
22083 if (slice_len_resolved.isUndef(zcu)) break :len .undef;21287 if (slice_len.isUndef(zcu)) break :len .undef;
22084 break :src .{ .fromInterned(src_info.child), slice_len_resolved.toUnsignedInt(zcu) };21288 break :src .{ .fromInterned(src_info.child), slice_len.toUnsignedInt(zcu) };
22085 },21289 },
22086 .many, .c => {21290 .many, .c => {
22087 return sema.fail(block, src, "cannot infer length of slice from {s}", .{pointerSizeString(src_info.flags.size)});21291 return sema.fail(block, src, "cannot infer length of slice from {s}", .{pointerSizeString(src_info.flags.size)});
...@@ -22369,7 +21573,7 @@ fn ptrCastFull(...@@ -22369,7 +21573,7 @@ fn ptrCastFull(
2236921573
22370 ct: {21574 ct: {
22371 if (flags.addrspace_cast) break :ct; // cannot `@addrSpaceCast` at comptime21575 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
22374 if (operand_val.isUndef(zcu)) {21578 if (operand_val.isUndef(zcu)) {
22375 if (!dest_ty.ptrAllowsZero(zcu)) {21579 if (!dest_ty.ptrAllowsZero(zcu)) {
...@@ -22395,7 +21599,7 @@ fn ptrCastFull(...@@ -22395,7 +21599,7 @@ fn ptrCastFull(
22395 };21599 };
2239621600
22397 if (dest_align.compare(.gt, src_align)) {21601 if (dest_align.compare(.gt, src_align)) {
22398 if (try ptr_val.getUnsignedIntSema(pt)) |addr| {21602 if (ptr_val.getUnsignedInt(zcu)) |addr| {
22399 const masked_addr = if (Type.fromInterned(dest_info.child).fnPtrMaskOrNull(zcu)) |mask|21603 const masked_addr = if (Type.fromInterned(dest_info.child).fnPtrMaskOrNull(zcu)) |mask|
22400 addr & mask21604 addr & mask
22401 else21605 else
...@@ -22464,7 +21668,7 @@ fn ptrCastFull(...@@ -22464,7 +21668,7 @@ fn ptrCastFull(
22464 // Now, do an addrspace cast if necessary!21668 // Now, do an addrspace cast if necessary!
22465 if (!flags.addrspace_cast) break :ptr pre_addrspace_cast;21669 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: {
22468 var info = src_info;21672 var info = src_info;
22469 info.flags.address_space = dest_info.flags.address_space;21673 info.flags.address_space = dest_info.flags.address_space;
22470 break :info info;21674 break :info info;
...@@ -22629,7 +21833,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -22629,7 +21833,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
22629 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;21833 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
22630 const src = block.nodeOffset(extra.node);21834 const src = block.nodeOffset(extra.node);
22631 const operand_src = block.src(.{ .node_offset_ptrcast_operand = extra.node });21835 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);
22633 const operand_ty = sema.typeOf(operand);21837 const operand_ty = sema.typeOf(operand);
22634 try sema.checkPtrOperand(block, operand_src, operand_ty);21838 try sema.checkPtrOperand(block, operand_src, operand_ty);
2263521839
...@@ -22638,14 +21842,14 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -22638,14 +21842,14 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
22638 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;21842 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;
2263921843
22640 const dest_ty = blk: {21844 const dest_ty = blk: {
22641 const dest_ty = try pt.ptrTypeSema(ptr_info);21845 const dest_ty = try pt.ptrType(ptr_info);
22642 if (operand_ty.zigTypeTag(zcu) == .optional) {21846 if (operand_ty.zigTypeTag(zcu) == .optional) {
22643 break :blk try pt.optionalType(dest_ty.toIntern());21847 break :blk try pt.optionalType(dest_ty.toIntern());
22644 }21848 }
22645 break :blk dest_ty;21849 break :blk dest_ty;
22646 };21850 };
2264721851
22648 if (try sema.resolveValue(operand)) |operand_val| {21852 if (sema.resolveValue(operand)) |operand_val| {
22649 return Air.internedToRef((try pt.getCoerced(operand_val, dest_ty)).toIntern());21853 return Air.internedToRef((try pt.getCoerced(operand_val, dest_ty)).toIntern());
22650 }21854 }
2265121855
...@@ -22664,7 +21868,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -22664,7 +21868,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22664 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;21868 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
22665 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate");21869 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate");
22666 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, src);21870 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);
22668 const operand_ty = sema.typeOf(operand);21872 const operand_ty = sema.typeOf(operand);
22669 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);21873 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...@@ -22678,48 +21882,24 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22678 return sema.coerce(block, dest_ty, operand, operand_src);21882 return sema.coerce(block, dest_ty, operand, operand_src);
22679 }21883 }
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| {21887 const dest_info = dest_scalar_ty.intInfo(zcu);
22684 return Air.internedToRef(val.toIntern());
22685 }
2268621888
22687 if (operand_scalar_ty.zigTypeTag(zcu) != .comptime_int) {21889 if (operand_scalar_ty.zigTypeTag(zcu) != .comptime_int) {
22688 const operand_info = operand_ty.intInfo(zcu);21890 const operand_info = operand_ty.intInfo(zcu);
22689 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22690 return Air.internedToRef(val.toIntern());
22691 }
2269221891
22693 if (operand_info.signedness != dest_info.signedness) {21892 if (operand_info.signedness != dest_info.signedness) {
22694 return sema.fail(block, operand_src, "expected {s} integer type, found '{f}'", .{21893 return sema.fail(block, operand_src, "expected {s} integer type, found '{f}'", .{
22695 @tagName(dest_info.signedness), operand_ty.fmt(pt),21894 @tagName(dest_info.signedness), operand_ty.fmt(pt),
22696 });21895 });
22697 }21896 }
22698 switch (std.math.order(dest_info.bits, operand_info.bits)) {21897 if (dest_info.bits >= operand_info.bits) {
22699 .gt => {21898 return sema.coerce(block, dest_ty, operand, operand_src);
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 => {},
22719 }21899 }
22720 }21900 }
2272121901
22722 if (try sema.resolveValueResolveLazy(operand)) |val| {21902 if (sema.resolveValue(operand)) |val| {
22723 const result_val = try arith.truncate(sema, val, operand_ty, dest_ty, dest_info.signedness, dest_info.bits);21903 const result_val = try arith.truncate(sema, val, operand_ty, dest_ty, dest_info.signedness, dest_info.bits);
22724 return Air.internedToRef(result_val.toIntern());21904 return Air.internedToRef(result_val.toIntern());
22725 }21905 }
...@@ -22740,15 +21920,11 @@ fn zirBitCount(...@@ -22740,15 +21920,11 @@ fn zirBitCount(
22740 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21920 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22741 const src = block.nodeOffset(inst_data.src_node);21921 const src = block.nodeOffset(inst_data.src_node);
22742 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21922 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);
22744 const operand_ty = sema.typeOf(operand);21924 const operand_ty = sema.typeOf(operand);
22745 _ = try sema.checkIntOrVector(block, operand, operand_src);21925 _ = try sema.checkIntOrVector(block, operand, operand_src);
22746 const bits = operand_ty.intInfo(zcu).bits;21926 const bits = operand_ty.intInfo(zcu).bits;
2274721927
22748 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22749 return Air.internedToRef(val.toIntern());
22750 }
22751
22752 const result_scalar_ty = try pt.smallestUnsignedInt(bits);21928 const result_scalar_ty = try pt.smallestUnsignedInt(bits);
22753 switch (operand_ty.zigTypeTag(zcu)) {21929 switch (operand_ty.zigTypeTag(zcu)) {
22754 .vector => {21930 .vector => {
...@@ -22757,7 +21933,7 @@ fn zirBitCount(...@@ -22757,7 +21933,7 @@ fn zirBitCount(
22757 .len = vec_len,21933 .len = vec_len,
22758 .child = result_scalar_ty.toIntern(),21934 .child = result_scalar_ty.toIntern(),
22759 });21935 });
22760 if (try sema.resolveValue(operand)) |val| {21936 if (sema.resolveValue(operand)) |val| {
22761 if (val.isUndef(zcu)) return pt.undefRef(result_ty);21937 if (val.isUndef(zcu)) return pt.undefRef(result_ty);
2276221938
22763 const elems = try sema.arena.alloc(InternPool.Index, vec_len);21939 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
...@@ -22774,7 +21950,7 @@ fn zirBitCount(...@@ -22774,7 +21950,7 @@ fn zirBitCount(
22774 }21950 }
22775 },21951 },
22776 .int => {21952 .int => {
22777 if (try sema.resolveValueResolveLazy(operand)) |val| {21953 if (sema.resolveValue(operand)) |val| {
22778 if (val.isUndef(zcu)) return pt.undefRef(result_scalar_ty);21954 if (val.isUndef(zcu)) return pt.undefRef(result_scalar_ty);
22779 return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, zcu));21955 return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, zcu));
22780 } else {21956 } else {
...@@ -22791,7 +21967,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -22791,7 +21967,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22791 const zcu = pt.zcu;21967 const zcu = pt.zcu;
22792 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21968 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22793 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21969 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);
22795 const operand_ty = sema.typeOf(operand);21971 const operand_ty = sema.typeOf(operand);
22796 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);21972 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
22797 const bits = scalar_ty.intInfo(zcu).bits;21973 const bits = scalar_ty.intInfo(zcu).bits;
...@@ -22803,10 +21979,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -22803,10 +21979,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22803 .{ scalar_ty.fmt(pt), bits },21979 .{ scalar_ty.fmt(pt), bits },
22804 );21980 );
22805 }21981 }
22806 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {21982 if (sema.resolveValue(operand)) |operand_val| {
22807 return .fromValue(val);
22808 }
22809 if (try sema.resolveValue(operand)) |operand_val| {
22810 return .fromValue(try arith.byteSwap(sema, operand_val, operand_ty));21983 return .fromValue(try arith.byteSwap(sema, operand_val, operand_ty));
22811 }21984 }
22812 return block.addTyOp(.byte_swap, operand_ty, operand);21985 return block.addTyOp(.byte_swap, operand_ty, operand);
...@@ -22815,14 +21988,11 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -22815,14 +21988,11 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22815fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21988fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22816 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21989 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22817 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21990 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);
22819 const operand_ty = sema.typeOf(operand);21992 const operand_ty = sema.typeOf(operand);
22820 _ = try sema.checkIntOrVector(block, operand, operand_src);21993 _ = try sema.checkIntOrVector(block, operand, operand_src);
2282121994
22822 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {21995 if (sema.resolveValue(operand)) |operand_val| {
22823 return .fromValue(val);
22824 }
22825 if (try sema.resolveValue(operand)) |operand_val| {
22826 return .fromValue(try arith.bitReverse(sema, operand_val, operand_ty));21996 return .fromValue(try arith.bitReverse(sema, operand_val, operand_ty));
22827 }21997 }
22828 return block.addTyOp(.bit_reverse, operand_ty, operand);21998 return block.addTyOp(.bit_reverse, operand_ty, operand);
...@@ -22849,10 +22019,11 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -22849,10 +22019,11 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
22849 const ty = try sema.resolveType(block, ty_src, extra.lhs);22019 const ty = try sema.resolveType(block, ty_src, extra.lhs);
22850 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.rhs, .{ .simple = .field_name });22020 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
22852 const pt = sema.pt;22024 const pt = sema.pt;
22853 const zcu = pt.zcu;22025 const zcu = pt.zcu;
22854 const ip = &zcu.intern_pool;22026 const ip = &zcu.intern_pool;
22855 try ty.resolveLayout(pt);
22856 switch (ty.zigTypeTag(zcu)) {22027 switch (ty.zigTypeTag(zcu)) {
22857 .@"struct" => {},22028 .@"struct" => {},
22858 else => return sema.fail(block, ty_src, "expected struct type, found '{f}'", .{ty.fmt(pt)}),22029 else => return sema.fail(block, ty_src, "expected struct type, found '{f}'", .{ty.fmt(pt)}),
...@@ -23090,7 +22261,7 @@ fn checkAtomicPtrOperand(...@@ -23090,7 +22261,7 @@ fn checkAtomicPtrOperand(
23090) CompileError!Air.Inst.Ref {22261) CompileError!Air.Inst.Ref {
23091 const pt = sema.pt;22262 const pt = sema.pt;
23092 const zcu = pt.zcu;22263 const zcu = pt.zcu;
23093 try elem_ty.resolveLayout(pt);22264 try sema.ensureLayoutResolved(elem_ty, elem_ty_src, .ptr_access);
23094 var diag: Zcu.AtomicPtrAlignmentDiagnostics = .{};22265 var diag: Zcu.AtomicPtrAlignmentDiagnostics = .{};
23095 const alignment = zcu.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {22266 const alignment = zcu.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
23096 error.OutOfMemory => return error.OutOfMemory,22267 error.OutOfMemory => return error.OutOfMemory,
...@@ -23126,7 +22297,7 @@ fn checkAtomicPtrOperand(...@@ -23126,7 +22297,7 @@ fn checkAtomicPtrOperand(
23126 const ptr_data = switch (ptr_ty.zigTypeTag(zcu)) {22297 const ptr_data = switch (ptr_ty.zigTypeTag(zcu)) {
23127 .pointer => ptr_ty.ptrInfo(zcu),22298 .pointer => ptr_ty.ptrInfo(zcu),
23128 else => {22299 else => {
23129 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);22300 const wanted_ptr_ty = try pt.ptrType(wanted_ptr_data);
23130 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);22301 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
23131 unreachable;22302 unreachable;
23132 },22303 },
...@@ -23136,7 +22307,7 @@ fn checkAtomicPtrOperand(...@@ -23136,7 +22307,7 @@ fn checkAtomicPtrOperand(
23136 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;22307 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
23137 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;22308 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);
23140 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);22311 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2314122312
23142 return casted_ptr;22313 return casted_ptr;
...@@ -23245,8 +22416,8 @@ fn checkSimdBinOp(...@@ -23245,8 +22416,8 @@ fn checkSimdBinOp(
23245 .len = vec_len,22416 .len = vec_len,
23246 .lhs = lhs,22417 .lhs = lhs,
23247 .rhs = rhs,22418 .rhs = rhs,
23248 .lhs_val = try sema.resolveValue(lhs),22419 .lhs_val = sema.resolveValue(lhs),
23249 .rhs_val = try sema.resolveValue(rhs),22420 .rhs_val = sema.resolveValue(rhs),
23250 .result_ty = result_ty,22421 .result_ty = result_ty,
23251 .scalar_ty = result_ty.scalarType(zcu),22422 .scalar_ty = result_ty.scalarType(zcu),
23252 };22423 };
...@@ -23338,7 +22509,7 @@ fn resolveExportOptions(...@@ -23338,7 +22509,7 @@ fn resolveExportOptions(
23338 const ip = &zcu.intern_pool;22509 const ip = &zcu.intern_pool;
2333922510
23340 const export_options_ty = try sema.getBuiltinType(src, .ExportOptions);22511 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);
23342 const options = try sema.coerce(block, export_options_ty, air_ref, src);22513 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2334322514
23344 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });22515 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -23391,7 +22562,7 @@ fn resolveBuiltinEnum(...@@ -23391,7 +22562,7 @@ fn resolveBuiltinEnum(
23391 reason: ComptimeReason,22562 reason: ComptimeReason,
23392) CompileError!@field(std.builtin, @tagName(name)) {22563) CompileError!@field(std.builtin, @tagName(name)) {
23393 const ty = try sema.getBuiltinType(src, name);22564 const ty = try sema.getBuiltinType(src, name);
23394 const air_ref = try sema.resolveInst(zir_ref);22565 const air_ref = sema.resolveInst(zir_ref);
23395 const coerced = try sema.coerce(block, ty, air_ref, src);22566 const coerced = try sema.coerce(block, ty, air_ref, src);
23396 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);22567 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
23397 return sema.interpretBuiltinType(block, src, val, @field(std.builtin, @tagName(name)));22568 return sema.interpretBuiltinType(block, src, val, @field(std.builtin, @tagName(name)));
...@@ -23438,7 +22609,7 @@ fn zirCmpxchg(...@@ -23438,7 +22609,7 @@ fn zirCmpxchg(
23438 const success_order_src = block.builtinCallArgSrc(extra.node, 4);22609 const success_order_src = block.builtinCallArgSrc(extra.node, 4);
23439 const failure_order_src = block.builtinCallArgSrc(extra.node, 5);22610 const failure_order_src = block.builtinCallArgSrc(extra.node, 5);
23440 // zig fmt: on22611 // zig fmt: on
23441 const expected_value = try sema.resolveInst(extra.expected_value);22612 const expected_value = sema.resolveInst(extra.expected_value);
23442 const elem_ty = sema.typeOf(expected_value);22613 const elem_ty = sema.typeOf(expected_value);
23443 if (elem_ty.zigTypeTag(zcu) == .float) {22614 if (elem_ty.zigTypeTag(zcu) == .float) {
23444 return sema.fail(22615 return sema.fail(
...@@ -23448,9 +22619,9 @@ fn zirCmpxchg(...@@ -23448,9 +22619,9 @@ fn zirCmpxchg(
23448 .{elem_ty.fmt(pt)},22619 .{elem_ty.fmt(pt)},
23449 );22620 );
23450 }22621 }
23451 const uncasted_ptr = try sema.resolveInst(extra.ptr);22622 const uncasted_ptr = sema.resolveInst(extra.ptr);
23452 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);22623 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);
23454 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order, .{ .simple = .atomic_order });22625 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order, .{ .simple = .atomic_order });
23455 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order, .{ .simple = .atomic_order });22626 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order, .{ .simple = .atomic_order });
2345622627
...@@ -23470,16 +22641,13 @@ fn zirCmpxchg(...@@ -23470,16 +22641,13 @@ fn zirCmpxchg(
23470 const result_ty = try pt.optionalType(elem_ty.toIntern());22641 const result_ty = try pt.optionalType(elem_ty.toIntern());
2347122642
23472 // special case zero bit types22643 // special case zero bit types
23473 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {22644 if (elem_ty.classify(zcu) == .one_possible_value) {
23474 return Air.internedToRef((try pt.intern(.{ .opt = .{22645 return .fromValue(try pt.nullValue(result_ty));
23475 .ty = result_ty.toIntern(),
23476 .val = .none,
23477 } })));
23478 }22646 }
2347922647
23480 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {22648 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {
23481 if (try sema.resolveValue(expected_value)) |expected_val| {22649 if (sema.resolveValue(expected_value)) |expected_val| {
23482 if (try sema.resolveValue(new_value)) |new_val| {22650 if (sema.resolveValue(new_value)) |new_val| {
23483 if (expected_val.isUndef(zcu) or new_val.isUndef(zcu)) {22651 if (expected_val.isUndef(zcu) or new_val.isUndef(zcu)) {
23484 // TODO: this should probably cause the memory stored at the pointer22652 // TODO: this should probably cause the memory stored at the pointer
23485 // to become undef as well22653 // to become undef as well
...@@ -23531,22 +22699,18 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -23531,22 +22699,18 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
23531 else => return sema.fail(block, src, "expected array or vector type, found '{f}'", .{dest_ty.fmt(pt)}),22699 else => return sema.fail(block, src, "expected array or vector type, found '{f}'", .{dest_ty.fmt(pt)}),
23532 }22700 }
2353322701
23534 const operand = try sema.resolveInst(extra.rhs);22702 const operand = sema.resolveInst(extra.rhs);
23535 const scalar_ty = dest_ty.childType(zcu);22703 const scalar_ty = dest_ty.childType(zcu);
23536 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);22704 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);
2353722705
23538 const len = try sema.usizeCast(block, src, dest_ty.arrayLen(zcu));22706 const len = try sema.usizeCast(block, src, dest_ty.arrayLen(zcu));
2353922707
23540 if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {22708 // If the length is 0, the result is comptime-known even if the operand isn't.
23541 return Air.internedToRef(val.toIntern());
23542 }
23543
23544 // We also need this case because `[0:s]T` is not OPV.
23545 if (len == 0) return .fromValue(try pt.aggregateValue(dest_ty, &.{}));22709 if (len == 0) return .fromValue(try pt.aggregateValue(dest_ty, &.{}));
2354622710
23547 const maybe_sentinel = dest_ty.sentinel(zcu);22711 const maybe_sentinel = dest_ty.sentinel(zcu);
2354822712
23549 if (try sema.resolveValue(scalar)) |scalar_val| {22713 if (sema.resolveValue(scalar)) |scalar_val| {
23550 full: {22714 full: {
23551 if (dest_ty.zigTypeTag(zcu) == .vector) break :full;22715 if (dest_ty.zigTypeTag(zcu) == .vector) break :full;
23552 const sentinel = maybe_sentinel orelse break :full;22716 const sentinel = maybe_sentinel orelse break :full;
...@@ -23581,7 +22745,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -23581,7 +22745,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
23581 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);22745 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
23582 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);22746 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
23583 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, .ReduceOp, .{ .simple = .operand_reduce_operation });22747 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);
23585 const operand_ty = sema.typeOf(operand);22749 const operand_ty = sema.typeOf(operand);
23586 const pt = sema.pt;22750 const pt = sema.pt;
23587 const zcu = pt.zcu;22751 const zcu = pt.zcu;
...@@ -23615,7 +22779,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -23615,7 +22779,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
23615 return sema.fail(block, operand_src, "@reduce operation requires a vector with nonzero length", .{});22779 return sema.fail(block, operand_src, "@reduce operation requires a vector with nonzero length", .{});
23616 }22780 }
2361722781
23618 if (try sema.resolveValue(operand)) |operand_val| {22782 if (sema.resolveValue(operand)) |operand_val| {
23619 if (operand_val.isUndef(zcu)) return pt.undefRef(scalar_ty);22783 if (operand_val.isUndef(zcu)) return pt.undefRef(scalar_ty);
2362022784
23621 var accum: Value = try operand_val.elemValue(pt, 0);22785 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...@@ -23651,9 +22815,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2365122815
23652 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);22816 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
23653 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);22817 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
23654 const a = try sema.resolveInst(extra.a);22818 const a = sema.resolveInst(extra.a);
23655 const b = try sema.resolveInst(extra.b);22819 const b = sema.resolveInst(extra.b);
23656 var mask = try sema.resolveInst(extra.mask);22820 var mask = sema.resolveInst(extra.mask);
23657 var mask_ty = sema.typeOf(mask);22821 var mask_ty = sema.typeOf(mask);
2365822822
23659 const mask_len = switch (sema.typeOf(mask).zigTypeTag(zcu)) {22823 const mask_len = switch (sema.typeOf(mask).zigTypeTag(zcu)) {
...@@ -23733,7 +22897,7 @@ fn analyzeShuffle(...@@ -23733,7 +22897,7 @@ fn analyzeShuffle(
23733 continue;22897 continue;
23734 }22898 }
23735 // Safe because mask elements are `i32` and we already checked for undef:22899 // 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);
23737 if (raw >= 0) {22901 if (raw >= 0) {
23738 const idx: u32 = @intCast(raw);22902 const idx: u32 = @intCast(raw);
23739 a_used = true;22903 a_used = true;
...@@ -23760,8 +22924,8 @@ fn analyzeShuffle(...@@ -23760,8 +22924,8 @@ fn analyzeShuffle(
23760 }22924 }
23761 }22925 }
2376222926
23763 const maybe_a_val = try sema.resolveValue(a_coerced);22927 const maybe_a_val = sema.resolveValue(a_coerced);
23764 const maybe_b_val = try sema.resolveValue(b_coerced);22928 const maybe_b_val = sema.resolveValue(b_coerced);
2376522929
23766 const a_rt = a_used and maybe_a_val == null;22930 const a_rt = a_used and maybe_a_val == null;
23767 const b_rt = b_used and maybe_b_val == null;22931 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...@@ -23849,7 +23013,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2384923013
23850 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);23014 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
23851 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);23015 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);
23853 const pred_ty = sema.typeOf(pred_uncoerced);23017 const pred_ty = sema.typeOf(pred_uncoerced);
2385423018
23855 const vec_len_u64 = switch (pred_ty.zigTypeTag(zcu)) {23019 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...@@ -23868,12 +23032,12 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
23868 .len = vec_len,23032 .len = vec_len,
23869 .child = elem_ty.toIntern(),23033 .child = elem_ty.toIntern(),
23870 });23034 });
23871 const a = try sema.coerce(block, vec_ty, try sema.resolveInst(extra.a), a_src);23035 const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src);
23872 const b = try sema.coerce(block, vec_ty, try sema.resolveInst(extra.b), b_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);23038 const maybe_pred = sema.resolveValue(pred);
23875 const maybe_a = try sema.resolveValue(a);23039 const maybe_a = sema.resolveValue(a);
23876 const maybe_b = try sema.resolveValue(b);23040 const maybe_b = sema.resolveValue(b);
2387723041
23878 const runtime_src = if (maybe_pred) |pred_val| rs: {23042 const runtime_src = if (maybe_pred) |pred_val| rs: {
23879 if (pred_val.isUndef(zcu)) return pt.undefRef(vec_ty);23043 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!...@@ -23934,10 +23098,12 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23934 const order_src = block.builtinCallArgSrc(inst_data.src_node, 2);23098 const order_src = block.builtinCallArgSrc(inst_data.src_node, 2);
23935 // zig fmt: on23099 // zig fmt: on
23936 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);23100 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);
23938 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);23102 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);
23939 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, .{ .simple = .atomic_order });23103 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
23941 switch (order) {23107 switch (order) {
23942 .release, .acq_rel => {23108 .release, .acq_rel => {
23943 return sema.fail(23109 return sema.fail(
...@@ -23950,9 +23116,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23950,9 +23116,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23950 else => {},23116 else => {},
23951 }23117 }
2395223118
23953 if (try sema.typeHasOnePossibleValue(elem_ty)) |val| {23119 if (try elem_ty.onePossibleValue(sema.pt)) |opv| return .fromValue(opv);
23954 return Air.internedToRef(val.toIntern());
23955 }
2395623120
23957 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {23121 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
23958 if (try sema.pointerDeref(block, ptr_src, ptr_val, sema.typeOf(ptr))) |elem_val| {23122 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...@@ -23983,9 +23147,9 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23983 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 3);23147 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 3);
23984 const order_src = block.builtinCallArgSrc(inst_data.src_node, 4);23148 const order_src = block.builtinCallArgSrc(inst_data.src_node, 4);
23985 // zig fmt: on23149 // zig fmt: on
23986 const operand = try sema.resolveInst(extra.operand);23150 const operand = sema.resolveInst(extra.operand);
23987 const elem_ty = sema.typeOf(operand);23151 const elem_ty = sema.typeOf(operand);
23988 const uncasted_ptr = try sema.resolveInst(extra.ptr);23152 const uncasted_ptr = sema.resolveInst(extra.ptr);
23989 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);23153 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
23990 const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation);23154 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...@@ -24009,12 +23173,10 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
24009 }23173 }
2401023174
24011 // special case zero bit types23175 // special case zero bit types
24012 if (try sema.typeHasOnePossibleValue(elem_ty)) |val| {23176 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
24013 return Air.internedToRef(val.toIntern());
24014 }
2401523177
24016 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {23178 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);
24018 const operand_val = maybe_operand_val orelse {23180 const operand_val = maybe_operand_val orelse {
24019 try sema.checkPtrIsNotComptimeMutable(block, ptr_val, ptr_src, operand_src);23181 try sema.checkPtrIsNotComptimeMutable(block, ptr_val, ptr_src, operand_src);
24020 break :rs operand_src;23182 break :rs operand_src;
...@@ -24065,9 +23227,9 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24065,9 +23227,9 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24065 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 2);23227 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 2);
24066 const order_src = block.builtinCallArgSrc(inst_data.src_node, 3);23228 const order_src = block.builtinCallArgSrc(inst_data.src_node, 3);
24067 // zig fmt: on23229 // zig fmt: on
24068 const operand = try sema.resolveInst(extra.operand);23230 const operand = sema.resolveInst(extra.operand);
24069 const elem_ty = sema.typeOf(operand);23231 const elem_ty = sema.typeOf(operand);
24070 const uncasted_ptr = try sema.resolveInst(extra.ptr);23232 const uncasted_ptr = sema.resolveInst(extra.ptr);
24071 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);23233 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
24072 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, .{ .simple = .atomic_order });23234 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....@@ -24098,14 +23260,14 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24098 const mulend2_src = block.builtinCallArgSrc(inst_data.src_node, 2);23260 const mulend2_src = block.builtinCallArgSrc(inst_data.src_node, 2);
24099 const addend_src = block.builtinCallArgSrc(inst_data.src_node, 3);23261 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);
24102 const ty = sema.typeOf(addend);23264 const ty = sema.typeOf(addend);
24103 const mulend1 = try sema.coerce(block, ty, try sema.resolveInst(extra.mulend1), mulend1_src);23265 const mulend1 = try sema.coerce(block, ty, sema.resolveInst(extra.mulend1), mulend1_src);
24104 const mulend2 = try sema.coerce(block, ty, try sema.resolveInst(extra.mulend2), mulend2_src);23266 const mulend2 = try sema.coerce(block, ty, sema.resolveInst(extra.mulend2), mulend2_src);
2410523267
24106 const maybe_mulend1 = try sema.resolveValue(mulend1);23268 const maybe_mulend1 = sema.resolveValue(mulend1);
24107 const maybe_mulend2 = try sema.resolveValue(mulend2);23269 const maybe_mulend2 = sema.resolveValue(mulend2);
24108 const maybe_addend = try sema.resolveValue(addend);23270 const maybe_addend = sema.resolveValue(addend);
24109 const pt = sema.pt;23271 const pt = sema.pt;
24110 const zcu = pt.zcu;23272 const zcu = pt.zcu;
2411123273
...@@ -24167,10 +23329,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24167,10 +23329,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24167 const call_src = block.nodeOffset(inst_data.src_node);23329 const call_src = block.nodeOffset(inst_data.src_node);
2416823330
24169 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;23331 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
24172 const modifier_ty = try sema.getBuiltinType(call_src, .CallModifier);23334 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);
24174 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);23336 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
24175 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });23337 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });
24176 var modifier = try sema.interpretBuiltinType(block, modifier_src, modifier_val, std.builtin.CallModifier);23338 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...@@ -24208,7 +23370,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24208 },23370 },
24209 }23371 }
2421023372
24211 const args = try sema.resolveInst(extra.args);23373 const args = sema.resolveInst(extra.args);
2421223374
24213 const args_ty = sema.typeOf(args);23375 const args_ty = sema.typeOf(args);
24214 if (!args_ty.isTuple(zcu)) {23376 if (!args_ty.isTuple(zcu)) {
...@@ -24253,18 +23415,23 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24253,18 +23415,23 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24253 const field_name_src = block.builtinCallArgSrc(extra.src_node, 0);23415 const field_name_src = block.builtinCallArgSrc(extra.src_node, 0);
24254 const field_ptr_src = block.builtinCallArgSrc(extra.src_node, 1);23416 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");23418 const maybe_opt_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);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 };
24258 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);23425 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
24259 if (parent_ptr_info.flags.size != .one) {23426 if (parent_ptr_info.flags.size != .one) {
24260 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});23427 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});
24261 }23428 }
24262 const parent_ty: Type = .fromInterned(parent_ptr_info.child);23429 const parent_ty: Type = .fromInterned(parent_ptr_info.child);
23430 try sema.ensureLayoutResolved(parent_ty, inst_src, .field_used);
24263 switch (parent_ty.zigTypeTag(zcu)) {23431 switch (parent_ty.zigTypeTag(zcu)) {
24264 .@"struct", .@"union" => {},23432 .@"struct", .@"union" => {},
24265 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{f}'", .{parent_ptr_ty.fmt(pt)}),23433 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{f}'", .{parent_ptr_ty.fmt(pt)}),
24266 }23434 }
24267 try parent_ty.resolveLayout(pt);
2426823435
24269 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });23436 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });
24270 const field_index = switch (parent_ty.zigTypeTag(zcu)) {23437 const field_index = switch (parent_ty.zigTypeTag(zcu)) {
...@@ -24285,144 +23452,77 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24285,144 +23452,77 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24285 return sema.fail(block, field_name_src, "cannot get @fieldParentPtr of a comptime field", .{});23452 return sema.fail(block, field_name_src, "cannot get @fieldParentPtr of a comptime field", .{});
24286 }23453 }
2428723454
24288 const field_ptr = try sema.resolveInst(extra.field_ptr);23455 const field_ptr = sema.resolveInst(extra.field_ptr);
24289 const field_ptr_ty = sema.typeOf(field_ptr);23456 const field_ptr_ty = sema.typeOf(field_ptr);
24290 try sema.checkPtrOperand(block, field_ptr_src, field_ptr_ty);23457 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 };23459 const hypothetical_field_ptr_ty = try parent_ptr_ty.fieldPtrType(field_index, pt);
24346 actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };23460 const casted_field_ptr = try sema.ptrCastFull(
24347 },23461 block,
24348 .@"packed" => {23462 flags,
24349 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +23463 inst_src,
24350 (if (zcu.typeToStruct(parent_ty)) |struct_obj| zcu.structPackedFieldBitOffset(struct_obj, field_index) else 0) -23464 field_ptr,
24351 actual_field_ptr_info.packed_offset.bit_offset), 8) catch23465 field_ptr_src,
24352 return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{});23466 hypothetical_field_ptr_ty,
24353 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0)23467 "@fieldParentPtr",
24354 Alignment.fromLog2Units(@ctz(byte_offset))23468 );
24355 else
24356 actual_field_ptr_info.flags.alignment);
24357 },
24358 }
2435923469
24360 const actual_field_ptr_ty = try pt.ptrTypeSema(actual_field_ptr_info);23470 const unaligned_parent_ptr_ty = try pt.ptrType(info: {
24361 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src);23471 var info = parent_ptr_info;
24362 const actual_parent_ptr_ty = try pt.ptrTypeSema(actual_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: {23476 const unaligned_parent_ptr: Air.Inst.Ref = if (try sema.resolveDefinedValue(
24365 switch (parent_ty.zigTypeTag(zcu)) {23477 block,
24366 .@"struct" => switch (parent_ty.containerLayout(zcu)) {23478 field_ptr_src,
24367 .auto => {},23479 casted_field_ptr,
24368 .@"extern" => {23480 )) |field_ptr_val| switch (parent_ty.containerLayout(zcu)) {
24369 const byte_offset = parent_ty.structFieldOffset(field_index, zcu);23481 .@"packed" => .fromValue(try pt.getCoerced(field_ptr_val, unaligned_parent_ptr_ty)),
24370 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);23482 .@"extern" => switch (parent_ty.zigTypeTag(zcu)) {
24371 break :result Air.internedToRef(parent_ptr_val.toIntern());23483 .@"struct" => .fromValue(try sema.ptrSubtract(
24372 },23484 block,
24373 .@"packed" => {23485 field_ptr_src,
24374 // Logic lifted from type computation above - I'm just assuming it's correct.23486 field_ptr_val,
24375 // `catch unreachable` since error case handled above.23487 parent_ty.structFieldOffset(field_index, zcu),
24376 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +23488 unaligned_parent_ptr_ty,
24377 zcu.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) -23489 )),
24378 actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable;23490 .@"union" => .fromValue(try pt.getCoerced(field_ptr_val, unaligned_parent_ptr_ty)),
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 },
24391 else => unreachable,23491 else => unreachable,
24392 }23492 },
2439323493 .auto => result: {
24394 const opt_field: ?InternPool.Key.Ptr.BaseAddr.BaseIndex = opt_field: {23494 const opt_field: ?InternPool.Key.Ptr.BaseAddr.BaseIndex = opt_field: {
24395 const ptr = switch (ip.indexToKey(field_ptr_val.toIntern())) {23495 const ptr = switch (ip.indexToKey(field_ptr_val.toIntern())) {
24396 .ptr => |ptr| ptr,23496 .ptr => |ptr| ptr,
24397 else => break :opt_field null,23497 else => break :opt_field null,
24398 };23498 };
24399 if (ptr.byte_offset != 0) break :opt_field null;23499 if (ptr.byte_offset != 0) break :opt_field null;
24400 break :opt_field switch (ptr.base_addr) {23500 break :opt_field switch (ptr.base_addr) {
24401 .field => |field| field,23501 .field => |field| field,
24402 else => null,23502 else => null,
23503 };
24403 };23504 };
24404 };
2440523505
24406 const field = opt_field orelse {23506 const field = opt_field orelse {
24407 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});23507 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});
24408 };23508 };
2440923509
24410 if (Value.fromInterned(field.base).typeOf(zcu).childType(zcu).toIntern() != parent_ty.toIntern()) {23510 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", .{});23511 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});
24412 }23512 }
2441323513
24414 if (field.index != field_index) {23514 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}'", .{23515 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),23516 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt),
24417 });23517 });
24418 }23518 }
24419 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);23519 break :result .fromValue(try pt.getCoerced(.fromInterned(field.base), unaligned_parent_ptr_ty));
23520 },
24420 } else result: {23521 } else result: {
24421 try sema.requireRuntimeBlock(block, inst_src, field_ptr_src);
24422 break :result try block.addInst(.{23522 break :result try block.addInst(.{
24423 .tag = .field_parent_ptr,23523 .tag = .field_parent_ptr,
24424 .data = .{ .ty_pl = .{23524 .data = .{ .ty_pl = .{
24425 .ty = Air.internedToRef(actual_parent_ptr_ty.toIntern()),23525 .ty = .fromType(unaligned_parent_ptr_ty),
24426 .payload = try block.sema.addExtra(Air.FieldParentPtr{23526 .payload = try block.sema.addExtra(Air.FieldParentPtr{
24427 .field_ptr = casted_field_ptr,23527 .field_ptr = casted_field_ptr,
24428 .field_index = @intCast(field_index),23528 .field_index = @intCast(field_index),
...@@ -24430,14 +23530,61 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24430,14 +23530,61 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24430 } },23530 } },
24431 });23531 });
24432 };23532 };
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 }
24434}23581}
2443523582
24436fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {23583fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {
24437 const pt = sema.pt;23584 const pt = sema.pt;
24438 const zcu = pt.zcu;23585 const zcu = pt.zcu;
24439 if (byte_subtract == 0) return pt.getCoerced(ptr_val, new_ty);23586 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())) {
24441 .undef => return sema.failWithUseOfUndef(block, src, null),23588 .undef => return sema.failWithUseOfUndef(block, src, null),
24442 .ptr => |ptr| ptr,23589 .ptr => |ptr| ptr,
24443 else => unreachable,23590 else => unreachable,
...@@ -24450,9 +23597,11 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte...@@ -24450,9 +23597,11 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte
24450 break :msg msg;23597 break :msg msg;
24451 });23598 });
24452 }23599 }
24453 ptr.byte_offset -= byte_subtract;23600 return Value.fromInterned(try pt.intern(.{ .ptr = .{
24454 ptr.ty = new_ty.toIntern();23601 .ty = new_ty.toIntern(),
24455 return Value.fromInterned(try pt.intern(.{ .ptr = ptr }));23602 .base_addr = ptr.base_addr,
23603 .byte_offset = ptr.byte_offset - byte_subtract,
23604 } }));
24456}23605}
2445723606
24458fn zirMinMax(23607fn zirMinMax(
...@@ -24466,8 +23615,8 @@ fn zirMinMax(...@@ -24466,8 +23615,8 @@ fn zirMinMax(
24466 const src = block.nodeOffset(inst_data.src_node);23615 const src = block.nodeOffset(inst_data.src_node);
24467 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);23616 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
24468 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);23617 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
24469 const lhs = try sema.resolveInst(extra.lhs);23618 const lhs = sema.resolveInst(extra.lhs);
24470 const rhs = try sema.resolveInst(extra.rhs);23619 const rhs = sema.resolveInst(extra.rhs);
24471 return sema.analyzeMinMax(block, src, air_tag, &.{ lhs, rhs }, &.{ lhs_src, rhs_src });23620 return sema.analyzeMinMax(block, src, air_tag, &.{ lhs, rhs }, &.{ lhs_src, rhs_src });
24472}23621}
2447323622
...@@ -24487,7 +23636,7 @@ fn zirMinMaxMulti(...@@ -24487,7 +23636,7 @@ fn zirMinMaxMulti(
2448723636
24488 for (operands, air_refs, operand_srcs, 0..) |zir_ref, *air_ref, *op_src, i| {23637 for (operands, air_refs, operand_srcs, 0..) |zir_ref, *air_ref, *op_src, i| {
24489 op_src.* = block.builtinCallArgSrc(src_node, @intCast(i));23638 op_src.* = block.builtinCallArgSrc(src_node, @intCast(i));
24490 air_ref.* = try sema.resolveInst(zir_ref);23639 air_ref.* = sema.resolveInst(zir_ref);
24491 }23640 }
2449223641
24493 return sema.analyzeMinMax(block, src, air_tag, air_refs, operand_srcs);23642 return sema.analyzeMinMax(block, src, air_tag, air_refs, operand_srcs);
...@@ -24590,7 +23739,7 @@ fn analyzeMinMax(...@@ -24590,7 +23739,7 @@ fn analyzeMinMax(
24590 const operand_scalar_ty = sema.typeOf(operand).scalarType(zcu);23739 const operand_scalar_ty = sema.typeOf(operand).scalarType(zcu);
24591 const want_strat: TypeStrat = switch (operand_scalar_ty.zigTypeTag(zcu)) {23740 const want_strat: TypeStrat = switch (operand_scalar_ty.zigTypeTag(zcu)) {
24592 .comptime_int => s: {23741 .comptime_int => s: {
24593 const val = (try sema.resolveValueResolveLazy(operand)).?;23742 const val = sema.resolveValue(operand).?;
24594 if (val.isUndef(zcu)) break :s .none;23743 if (val.isUndef(zcu)) break :s .none;
24595 break :s .{ .int = .{23744 break :s .{ .int = .{
24596 .all_comptime_int = true,23745 .all_comptime_int = true,
...@@ -24609,7 +23758,7 @@ fn analyzeMinMax(...@@ -24609,7 +23758,7 @@ fn analyzeMinMax(
24609 // (replaced with just the simple calls to `Type.minInt`/`Type.maxInt`) so that we only23758 // (replaced with just the simple calls to `Type.minInt`/`Type.maxInt`) so that we only
24610 // use the input *types* to determine the result type.23759 // use the input *types* to determine the result type.
24611 const min: Value, const max: Value = bounds: {23760 const min: Value, const max: Value = bounds: {
24612 if (try sema.resolveValueResolveLazy(operand)) |operand_val| {23761 if (sema.resolveValue(operand)) |operand_val| {
24613 if (vector_len) |len| {23762 if (vector_len) |len| {
24614 var min = try operand_val.elemValue(pt, 0);23763 var min = try operand_val.elemValue(pt, 0);
24615 var max = min;23764 var max = min;
...@@ -24696,6 +23845,9 @@ fn analyzeMinMax(...@@ -24696,6 +23845,9 @@ fn analyzeMinMax(
24696 .child = intermediate_scalar_ty.toIntern(),23845 .child = intermediate_scalar_ty.toIntern(),
24697 }) else intermediate_scalar_ty;23846 }) 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
24699 // This value, if not `null`, will have type `intermediate_ty`.23851 // This value, if not `null`, will have type `intermediate_ty`.
24700 const comptime_part: ?Value = ct: {23852 const comptime_part: ?Value = ct: {
24701 // Contains the comptime-known scalar result values.23853 // Contains the comptime-known scalar result values.
...@@ -24712,7 +23864,7 @@ fn analyzeMinMax(...@@ -24712,7 +23864,7 @@ fn analyzeMinMax(
24712 var opt_runtime_src: ?LazySrcLoc = null;23864 var opt_runtime_src: ?LazySrcLoc = null;
2471323865
24714 for (operands, operand_srcs) |operand, operand_src| {23866 for (operands, operand_srcs) |operand, operand_src| {
24715 const operand_val = try sema.resolveValueResolveLazy(operand) orelse {23867 const operand_val = sema.resolveValue(operand) orelse {
24716 if (opt_runtime_src == null) opt_runtime_src = operand_src;23868 if (opt_runtime_src == null) opt_runtime_src = operand_src;
24717 continue;23869 continue;
24718 };23870 };
...@@ -24819,7 +23971,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A...@@ -24819,7 +23971,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A
24819 // Already an array pointer.23971 // Already an array pointer.
24820 return ptr;23972 return ptr;
24821 }23973 }
24822 const new_ty = try pt.ptrTypeSema(.{23974 const new_ty = try pt.ptrType(.{
24823 .child = (try pt.arrayType(.{23975 .child = (try pt.arrayType(.{
24824 .len = len,23976 .len = len,
24825 .sentinel = info.sentinel,23977 .sentinel = info.sentinel,
...@@ -24852,8 +24004,8 @@ fn zirMemcpy(...@@ -24852,8 +24004,8 @@ fn zirMemcpy(
24852 const src = block.nodeOffset(inst_data.src_node);24004 const src = block.nodeOffset(inst_data.src_node);
24853 const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);24005 const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);
24854 const src_src = block.builtinCallArgSrc(inst_data.src_node, 1);24006 const src_src = block.builtinCallArgSrc(inst_data.src_node, 1);
24855 const dest_ptr = try sema.resolveInst(extra.lhs);24007 const dest_ptr = sema.resolveInst(extra.lhs);
24856 const src_ptr = try sema.resolveInst(extra.rhs);24008 const src_ptr = sema.resolveInst(extra.rhs);
24857 const dest_ty = sema.typeOf(dest_ptr);24009 const dest_ty = sema.typeOf(dest_ptr);
24858 const src_ty = sema.typeOf(src_ptr);24010 const src_ty = sema.typeOf(src_ptr);
24859 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);24011 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
...@@ -24880,8 +24032,11 @@ fn zirMemcpy(...@@ -24880,8 +24032,11 @@ fn zirMemcpy(
24880 return sema.failWithOwnedErrorMsg(block, msg);24032 return sema.failWithOwnedErrorMsg(block, msg);
24881 }24033 }
2488224034
24883 const dest_elem_ty = dest_ty.indexablePtrElem(zcu);24035 const dest_elem_ty = dest_ty.indexableElem(zcu);
24884 const src_elem_ty = src_ty.indexablePtrElem(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
24886 const imc = try sema.coerceInMemoryAllowed(24041 const imc = try sema.coerceInMemoryAllowed(
24887 block,24042 block,
...@@ -24946,13 +24101,13 @@ fn zirMemcpy(...@@ -24946,13 +24101,13 @@ fn zirMemcpy(
24946 }24101 }
2494724102
24948 zero_bit: {24103 zero_bit: {
24949 const src_comptime = try src_elem_ty.comptimeOnlySema(pt);24104 const src_comptime = src_elem_ty.comptimeOnly(zcu);
24950 const dest_comptime = try dest_elem_ty.comptimeOnlySema(pt);24105 const dest_comptime = dest_elem_ty.comptimeOnly(zcu);
24951 assert(src_comptime == dest_comptime); // IMC24106 assert(src_comptime == dest_comptime); // IMC
24952 if (src_comptime) break :zero_bit;24107 if (src_comptime) break :zero_bit;
2495324108
24954 const src_has_bits = try src_elem_ty.hasRuntimeBitsIgnoreComptimeSema(pt);24109 const src_has_bits = src_elem_ty.hasRuntimeBits(zcu);
24955 const dest_has_bits = try dest_elem_ty.hasRuntimeBitsIgnoreComptimeSema(pt);24110 const dest_has_bits = dest_elem_ty.hasRuntimeBits(zcu);
24956 assert(src_has_bits == dest_has_bits); // IMC24111 assert(src_has_bits == dest_has_bits); // IMC
24957 if (src_has_bits) break :zero_bit;24112 if (src_has_bits) break :zero_bit;
2495824113
...@@ -24968,7 +24123,7 @@ fn zirMemcpy(...@@ -24968,7 +24123,7 @@ fn zirMemcpy(
24968 const raw_dest_ptr = if (dest_ty.isSlice(zcu)) dest_ptr_val.slicePtr(zcu) else dest_ptr_val;24123 const raw_dest_ptr = if (dest_ty.isSlice(zcu)) dest_ptr_val.slicePtr(zcu) else dest_ptr_val;
24969 const raw_src_ptr = if (src_ty.isSlice(zcu)) src_ptr_val.slicePtr(zcu) else src_ptr_val;24124 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
24973 if (check_aliasing) {24128 if (check_aliasing) {
24974 if (Value.doPointersOverlap(24129 if (Value.doPointersOverlap(
...@@ -25018,7 +24173,7 @@ fn zirMemcpy(...@@ -25018,7 +24173,7 @@ fn zirMemcpy(
25018 var new_dest_ptr = dest_ptr;24173 var new_dest_ptr = dest_ptr;
25019 var new_src_ptr = src_ptr;24174 var new_src_ptr = src_ptr;
25020 if (len_val) |val| {24175 if (len_val) |val| {
25021 const len = try val.toUnsignedIntSema(pt);24176 const len = val.toUnsignedInt(zcu);
25022 if (len == 0) {24177 if (len == 0) {
25023 // This AIR instruction guarantees length > 0 if it is comptime-known.24178 // This AIR instruction guarantees length > 0 if it is comptime-known.
25024 return;24179 return;
...@@ -25036,7 +24191,7 @@ fn zirMemcpy(...@@ -25036,7 +24191,7 @@ fn zirMemcpy(
25036 }24191 }
25037 } else if (dest_len == .none and len_val == null) {24192 } else if (dest_len == .none and len_val == null) {
25038 // Change the dest to a slice, since its type must have the length.24193 // 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);
25040 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);24195 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);
25041 const new_src_ptr_ty = sema.typeOf(new_src_ptr);24196 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
25042 if (new_src_ptr_ty.isSlice(zcu)) {24197 if (new_src_ptr_ty.isSlice(zcu)) {
...@@ -25067,7 +24222,7 @@ fn zirMemcpy(...@@ -25067,7 +24222,7 @@ fn zirMemcpy(
25067 assert(dest_manyptr_ty_key.flags.size == .one);24222 assert(dest_manyptr_ty_key.flags.size == .one);
25068 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();24223 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();
25069 dest_manyptr_ty_key.flags.size = .many;24224 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);
25071 } else new_dest_ptr;24226 } else new_dest_ptr;
2507224227
25073 const new_src_ptr_ty = sema.typeOf(new_src_ptr);24228 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
...@@ -25078,13 +24233,13 @@ fn zirMemcpy(...@@ -25078,13 +24233,13 @@ fn zirMemcpy(
25078 assert(src_manyptr_ty_key.flags.size == .one);24233 assert(src_manyptr_ty_key.flags.size == .one);
25079 src_manyptr_ty_key.child = src_elem_ty.toIntern();24234 src_manyptr_ty_key.child = src_elem_ty.toIntern();
25080 src_manyptr_ty_key.flags.size = .many;24235 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);
25082 } else new_src_ptr;24237 } else new_src_ptr;
2508324238
25084 // ok1: dest >= src + len24239 // ok1: dest >= src + len
25085 // ok2: src >= dest + len24240 // ok2: src >= dest + len
25086 const src_plus_len = try sema.analyzePtrArithmetic(block, src, raw_src_ptr, len, .ptr_add, src_src, src);24241 const src_plus_len = try sema.analyzePtrArithmetic(block, src, raw_src_ptr, len, .ptr_add, src);
25087 const dest_plus_len = try sema.analyzePtrArithmetic(block, src, raw_dest_ptr, len, .ptr_add, dest_src, src);24242 const dest_plus_len = try sema.analyzePtrArithmetic(block, src, raw_dest_ptr, len, .ptr_add, src);
25088 const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len);24243 const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len);
25089 const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len);24244 const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len);
25090 const ok = try block.addBinOp(.bool_or, ok1, ok2);24245 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...@@ -25113,8 +24268,8 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25113 const src = block.nodeOffset(inst_data.src_node);24268 const src = block.nodeOffset(inst_data.src_node);
25114 const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);24269 const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);
25115 const value_src = block.builtinCallArgSrc(inst_data.src_node, 1);24270 const value_src = block.builtinCallArgSrc(inst_data.src_node, 1);
25116 const dest_ptr = try sema.resolveInst(extra.lhs);24271 const dest_ptr = sema.resolveInst(extra.lhs);
25117 const uncoerced_elem = try sema.resolveInst(extra.rhs);24272 const uncoerced_elem = sema.resolveInst(extra.rhs);
25118 const dest_ptr_ty = sema.typeOf(dest_ptr);24273 const dest_ptr_ty = sema.typeOf(dest_ptr);
25119 try checkMemOperand(sema, block, dest_src, dest_ptr_ty);24274 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...@@ -25145,10 +24300,17 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2514524300
25146 const elem = try sema.coerce(block, dest_elem_ty, uncoerced_elem, value_src);24301 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
25148 const runtime_src = rs: {24310 const runtime_src = rs: {
25149 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls), dest_src);24311 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls), dest_src);
25150 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;24312 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);
25152 const len = try sema.usizeCast(block, dest_src, len_u64);24314 const len = try sema.usizeCast(block, dest_src, len_u64);
25153 if (len == 0) {24315 if (len == 0) {
25154 // This AIR instruction guarantees length > 0 if it is comptime-known.24316 // 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...@@ -25157,7 +24319,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2515724319
25158 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;24320 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
25159 if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src;24321 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;
25161 const array_ty = try pt.arrayType(.{24323 const array_ty = try pt.arrayType(.{
25162 .child = dest_elem_ty.toIntern(),24324 .child = dest_elem_ty.toIntern(),
25163 .len = len_u64,24325 .len = len_u64,
...@@ -25174,6 +24336,15 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25174,6 +24336,15 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25174 return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty);24336 return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty);
25175 };24337 };
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
25177 try sema.requireRuntimeBlock(block, src, runtime_src);24348 try sema.requireRuntimeBlock(block, src, runtime_src);
25178 try sema.validateRuntimeValue(block, dest_src, dest_ptr);24349 try sema.validateRuntimeValue(block, dest_src, dest_ptr);
25179 try sema.validateRuntimeValue(block, value_src, elem);24350 try sema.validateRuntimeValue(block, value_src, elem);
...@@ -25227,7 +24398,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25227,7 +24398,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25227 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);24398 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
25228 extra_index += 1;24399 extra_index += 1;
25229 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);24400 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);
25231 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);24402 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);
25232 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });24403 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });
25233 break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val);24404 break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val);
...@@ -25344,7 +24515,7 @@ fn zirCDefine(...@@ -25344,7 +24515,7 @@ fn zirCDefine(
25344 const val_src = block.builtinCallArgSrc(extra.node, 1);24515 const val_src = block.builtinCallArgSrc(extra.node, 1);
2534524516
25346 const name = try sema.resolveConstString(block, name_src, extra.lhs, .{ .simple = .operand_cDefine_macro_name });24517 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);
25348 if (sema.typeOf(rhs).zigTypeTag(zcu) != .void) {24519 if (sema.typeOf(rhs).zigTypeTag(zcu) != .void) {
25349 const value = try sema.resolveConstString(block, val_src, extra.rhs, .{ .simple = .operand_cDefine_macro_value });24520 const value = try sema.resolveConstString(block, val_src, extra.rhs, .{ .simple = .operand_cDefine_macro_value });
25350 try block.c_import_buf.?.print("#define {s} {s}\n", .{ name, value });24521 try block.c_import_buf.?.print("#define {s} {s}\n", .{ name, value });
...@@ -25393,7 +24564,7 @@ fn zirWasmMemoryGrow(...@@ -25393,7 +24564,7 @@ fn zirWasmMemoryGrow(
25393 }24564 }
2539424565
25395 const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.lhs, .u32, .{ .simple = .wasm_memory_index }));24566 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
25398 try sema.requireRuntimeBlock(block, builtin_src, null);24569 try sema.requireRuntimeBlock(block, builtin_src, null);
25399 return block.addInst(.{24570 return block.addInst(.{
...@@ -25419,7 +24590,7 @@ fn resolvePrefetchOptions(...@@ -25419,7 +24590,7 @@ fn resolvePrefetchOptions(
25419 const ip = &zcu.intern_pool;24590 const ip = &zcu.intern_pool;
2542024591
25421 const options_ty = try sema.getBuiltinType(src, .PrefetchOptions);24592 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
25424 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });24595 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
25425 const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });24596 const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -25436,7 +24607,7 @@ fn resolvePrefetchOptions(...@@ -25436,7 +24607,7 @@ fn resolvePrefetchOptions(
2543624607
25437 return std.builtin.PrefetchOptions{24608 return std.builtin.PrefetchOptions{
25438 .rw = try sema.interpretBuiltinType(block, rw_src, rw_val, std.builtin.PrefetchOptions.Rw),24609 .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)),
25440 .cache = try sema.interpretBuiltinType(block, cache_src, cache_val, std.builtin.PrefetchOptions.Cache),24611 .cache = try sema.interpretBuiltinType(block, cache_src, cache_val, std.builtin.PrefetchOptions.Cache),
25441 };24612 };
25442}24613}
...@@ -25449,7 +24620,7 @@ fn zirPrefetch(...@@ -25449,7 +24620,7 @@ fn zirPrefetch(
25449 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;24620 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
25450 const ptr_src = block.builtinCallArgSrc(extra.node, 0);24621 const ptr_src = block.builtinCallArgSrc(extra.node, 0);
25451 const opts_src = block.builtinCallArgSrc(extra.node, 1);24622 const opts_src = block.builtinCallArgSrc(extra.node, 1);
25452 const ptr = try sema.resolveInst(extra.lhs);24623 const ptr = sema.resolveInst(extra.lhs);
25453 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));24624 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
2545424625
25455 const options = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs);24626 const options = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs);
...@@ -25491,7 +24662,7 @@ fn resolveExternOptions(...@@ -25491,7 +24662,7 @@ fn resolveExternOptions(
25491 const io = comp.io;24662 const io = comp.io;
25492 const ip = &zcu.intern_pool;24663 const ip = &zcu.intern_pool;
2549324664
25494 const options_inst = try sema.resolveInst(zir_ref);24665 const options_inst = sema.resolveInst(zir_ref);
25495 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);24666 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);
25496 const options = try sema.coerce(block, extern_options_ty, options_inst, src);24667 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2549724668
...@@ -25574,18 +24745,32 @@ fn zirBuiltinExtern(...@@ -25574,18 +24745,32 @@ fn zirBuiltinExtern(
25574 const ty_src = block.builtinCallArgSrc(extra.node, 0);24745 const ty_src = block.builtinCallArgSrc(extra.node, 0);
25575 const options_src = block.builtinCallArgSrc(extra.node, 1);24746 const options_src = block.builtinCallArgSrc(extra.node, 1);
2557624747
25577 var ty = try sema.resolveType(block, ty_src, extra.lhs);24748 const ptr_ty = try sema.resolveType(block, ty_src, extra.lhs);
25578 if (!ty.isPtrAtRuntime(zcu)) {24749 if (!ptr_ty.isPtrAtRuntime(zcu)) {
25579 return sema.fail(block, ty_src, "expected (optional) pointer", .{});24750 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
25580 }24751 }
25581 if (!try sema.validateExternType(ty, .other)) {24752
25582 const msg = msg: {24753 const ptr_info = ptr_ty.ptrInfo(zcu);
25583 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ty.fmt(pt)});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)});
25584 errdefer msg.destroy(sema.gpa);24761 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);
25586 break :msg msg;24764 break :msg msg;
25587 };24765 });
25588 return sema.failWithOwnedErrorMsg(block, msg);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 });
25589 }24774 }
2559024775
25591 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);24776 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
...@@ -25603,14 +24788,9 @@ fn zirBuiltinExtern(...@@ -25603,14 +24788,9 @@ fn zirBuiltinExtern(
2560324788
25604 // TODO: error for threadlocal functions, non-const functions, etc24789 // 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
25611 const extern_val = try pt.getExtern(.{24791 const extern_val = try pt.getExtern(.{
25612 .name = options.name,24792 .name = options.name,
25613 .ty = ptr_info.child,24793 .ty = elem_ty.toIntern(),
25614 .lib_name = options.library_name,24794 .lib_name = options.library_name,
25615 .linkage = options.linkage,24795 .linkage = options.linkage,
25616 .visibility = options.visibility,24796 .visibility = options.visibility,
...@@ -25626,7 +24806,7 @@ fn zirBuiltinExtern(...@@ -25626,7 +24806,7 @@ fn zirBuiltinExtern(
25626 // So, for now, just use our containing `declaration`.24806 // So, for now, just use our containing `declaration`.
25627 .zir_index = switch (sema.owner.unwrap()) {24807 .zir_index = switch (sema.owner.unwrap()) {
25628 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,24808 .@"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).?,
25630 .memoized_state => unreachable,24810 .memoized_state => unreachable,
25631 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,24811 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,
25632 .func => |func| zir_index: {24812 .func => |func| zir_index: {
...@@ -25641,13 +24821,17 @@ fn zirBuiltinExtern(...@@ -25641,13 +24821,17 @@ fn zirBuiltinExtern(
25641 .source = .builtin,24821 .source = .builtin,
25642 });24822 });
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
25644 const uncasted_ptr = try sema.analyzeNavRef(block, src, ip.indexToKey(extern_val).@"extern".owner_nav);24829 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.24830 if (sema.resolveValue(uncasted_ptr)) |uncasted_ptr_val| {
25646 if (try sema.resolveValue(uncasted_ptr)) |uncasted_ptr_val| {24831 const casted_ptr_val = try pt.getCoerced(uncasted_ptr_val, result_ptr_ty);
25647 const casted_ptr_val = try pt.getCoerced(uncasted_ptr_val, ty);
25648 return Air.internedToRef(casted_ptr_val.toIntern());24832 return Air.internedToRef(casted_ptr_val.toIntern());
25649 } else {24833 } else {
25650 return block.addBitCast(ty, uncasted_ptr);24834 return block.addBitCast(result_ptr_ty, uncasted_ptr);
25651 }24835 }
25652}24836}
2565324837
...@@ -25732,6 +24916,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -25732,6 +24916,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
25732 // Values are handled here.24916 // Values are handled here.
25733 .calling_convention_c => {24917 .calling_convention_c => {
25734 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);24918 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
24919 // Cannot use `Value.uninterpret` because `c` is a *declaration* whose value depends on the target.
25735 return try sema.namespaceLookupVal(24920 return try sema.namespaceLookupVal(
25736 block,24921 block,
25737 src,24922 src,
...@@ -25740,17 +24925,15 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -25740,17 +24925,15 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
25740 ) orelse @panic("std.builtin is corrupt");24925 ) orelse @panic("std.builtin is corrupt");
25741 },24926 },
25742 .calling_convention_inline => {24927 .calling_convention_inline => {
25743 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);
25744 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);24928 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
25745 const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt");24929 return .fromValue(Value.uninterpret(
25746 const inline_tag_val = try pt.enumValue(24930 @as(std.builtin.CallingConvention, .@"inline"),
25747 callconv_tag_ty,24931 callconv_ty,
25748 (try pt.intValue(24932 pt,
25749 .u8,24933 ) catch |err| switch (err) {
25750 @intFromEnum(std.builtin.CallingConvention.@"inline"),24934 error.TypeMismatch => @panic("std.builtin is corrupt"),
25751 )).toIntern(),24935 error.OutOfMemory => |e| return e,
25752 );24936 });
25753 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);
25754 },24937 },
25755 };24938 };
25756 return .fromType(try sema.getBuiltinType(src, builtin_type));24939 return .fromType(try sema.getBuiltinType(src, builtin_type));
...@@ -25760,7 +24943,7 @@ fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) Co...@@ -25760,7 +24943,7 @@ fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) Co
25760 const pt = sema.pt;24943 const pt = sema.pt;
25761 const zcu = pt.zcu;24944 const zcu = pt.zcu;
2576224945
25763 const lhs = try sema.resolveInst(@enumFromInt(extended.operand));24946 const lhs = sema.resolveInst(@enumFromInt(extended.operand));
25764 const lhs_ty = sema.typeOf(lhs);24947 const lhs_ty = sema.typeOf(lhs);
2576524948
25766 const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small);24949 const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small);
...@@ -25785,7 +24968,7 @@ fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) Co...@@ -25785,7 +24968,7 @@ fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) Co
2578524968
25786fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {24969fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
25787 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;24970 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);
25789 const operand_src = block.builtinCallArgSrc(extra.node, 0);24972 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2579024973
25791 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);24974 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);
...@@ -25839,7 +25022,8 @@ fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src:...@@ -25839,7 +25022,8 @@ fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src:
25839 }25022 }
25840}25023}
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.
25843pub fn validateVarType(25027pub fn validateVarType(
25844 sema: *Sema,25028 sema: *Sema,
25845 block: *Block,25029 block: *Block,
...@@ -25849,8 +25033,9 @@ pub fn validateVarType(...@@ -25849,8 +25033,9 @@ pub fn validateVarType(
25849) CompileError!void {25033) CompileError!void {
25850 const pt = sema.pt;25034 const pt = sema.pt;
25851 const zcu = pt.zcu;25035 const zcu = pt.zcu;
25036 var_ty.assertHasLayout(zcu);
25852 if (is_extern) {25037 if (is_extern) {
25853 if (!try sema.validateExternType(var_ty, .other)) {25038 if (!var_ty.validateExtern(.other, zcu)) {
25854 const msg = msg: {25039 const msg = msg: {
25855 const msg = try sema.errMsg(src, "extern variable cannot have type '{f}'", .{var_ty.fmt(pt)});25040 const msg = try sema.errMsg(src, "extern variable cannot have type '{f}'", .{var_ty.fmt(pt)});
25856 errdefer msg.destroy(sema.gpa);25041 errdefer msg.destroy(sema.gpa);
...@@ -25870,7 +25055,7 @@ pub fn validateVarType(...@@ -25870,7 +25055,7 @@ pub fn validateVarType(
25870 }25055 }
25871 }25056 }
2587225057
25873 if (!try var_ty.comptimeOnlySema(pt)) return;25058 if (!var_ty.comptimeOnly(zcu)) return;
2587425059
25875 const msg = msg: {25060 const msg = msg: {
25876 const msg = try sema.errMsg(src, "variable of type '{f}' must be const or comptime", .{var_ty.fmt(pt)});25061 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(...@@ -25886,49 +25071,28 @@ pub fn validateVarType(
25886 return sema.failWithOwnedErrorMsg(block, msg);25071 return sema.failWithOwnedErrorMsg(block, msg);
25887}25072}
2588825073
25889const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void);
25890
25891fn explainWhyTypeIsComptime(25074fn explainWhyTypeIsComptime(
25892 sema: *Sema,25075 sema: *Sema,
25893 msg: *Zcu.ErrorMsg,25076 msg: *Zcu.ErrorMsg,
25894 src_loc: LazySrcLoc,25077 src: 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,
25908 ty: Type,25078 ty: Type,
25909 type_set: *TypeSet,
25910) CompileError!void {25079) CompileError!void {
25911 const pt = sema.pt;25080 const pt = sema.pt;
25912 const zcu = pt.zcu;25081 const zcu = pt.zcu;
25913 const ip = &zcu.intern_pool;25082 const ip = &zcu.intern_pool;
25083 assert(ty.comptimeOnly(zcu));
25914 switch (ty.zigTypeTag(zcu)) {25084 switch (ty.zigTypeTag(zcu)) {
25915 .bool,25085 .bool,
25916 .int,25086 .int,
25917 .float,25087 .float,
25918 .error_set,25088 .error_set,
25919 .@"enum",
25920 .frame,25089 .frame,
25921 .@"anyframe",25090 .@"anyframe",
25922 .void,25091 .void,
25923 => return,25092 .@"enum",
2592425093 .@"opaque",
25925 .@"fn" => {25094 .pointer,
25926 try sema.errNote(src_loc, msg, "use '*const {f}' for a function pointer type", .{ty.fmt(pt)});25095 => unreachable, // not comptime-only
25927 },
25928
25929 .type => {
25930 try sema.errNote(src_loc, msg, "types are not available at runtime", .{});
25931 },
2593225096
25933 .comptime_float,25097 .comptime_float,
25934 .comptime_int,25098 .comptime_int,
...@@ -25936,99 +25100,65 @@ fn explainWhyTypeIsComptimeInner(...@@ -25936,99 +25100,65 @@ fn explainWhyTypeIsComptimeInner(
25936 .noreturn,25100 .noreturn,
25937 .undefined,25101 .undefined,
25938 .null,25102 .null,
25939 => return,25103 => return, // no explanation needed
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 },
2597325104
25974 .@"struct" => {25105 .array, .vector => try sema.explainWhyTypeIsComptime(msg, src, ty.childType(zcu)),
25975 if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return;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| {25109 .@"fn" => try sema.errNote(src, msg, "use '*const {f}' for a function pointer type", .{ty.fmt(pt)}),
25978 for (0..struct_type.field_types.len) |i| {25110 .type => try sema.errNote(src, msg, "types are not available at runtime", .{}),
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 };
2598425111
25985 if (try field_ty.comptimeOnlySema(pt)) {25112 .@"struct" => if (zcu.typeToStruct(ty)) |struct_type| {
25986 try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});25113 ty.assertHasLayout(zcu);
25987 try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set);25114 for (0..struct_type.field_types.len) |i| {
25988 }25115 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
25989 }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);
25990 }25133 }
25991 // TODO tuples25134 unreachable;
25992 },25135 },
2599325136
25994 .@"union" => {25137 .@"union" => {
25995 if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return;25138 const union_obj = zcu.typeToUnion(ty).?;
2599625139 for (0..union_obj.field_types.len) |i| {
25997 if (zcu.typeToUnion(ty)) |union_obj| {25140 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);
25998 for (0..union_obj.field_types.len) |i| {25141 if (!field_ty.comptimeOnly(zcu)) continue;
25999 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);25142 const field_src: LazySrcLoc = .{
26000 const field_src: LazySrcLoc = .{25143 .base_node_inst = union_obj.zir_index,
26001 .base_node_inst = union_obj.zir_index,25144 .offset = .{ .container_field_type = @intCast(i) },
26002 .offset = .{ .container_field_type = @intCast(i) },25145 };
26003 };25146 try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});
2600425147 return sema.explainWhyTypeIsComptime(msg, field_src, field_ty);
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 }
26010 }25148 }
25149 unreachable;
26011 },25150 },
26012 }25151 }
26013}25152}
2601425153
26015const ExternPosition = enum {25154/// Keep in sync with `Type.validateExtern`.
26016 ret_ty,25155pub fn explainWhyTypeIsNotExtern(
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(
26028 sema: *Sema,25156 sema: *Sema,
25157 msg: *Zcu.ErrorMsg,
25158 src_loc: LazySrcLoc,
26029 ty: Type,25159 ty: Type,
26030 position: ExternPosition,25160 position: Type.ExternPosition,
26031) !bool {25161) SemaError!void {
26032 const pt = sema.pt;25162 const pt = sema.pt;
26033 const zcu = pt.zcu;25163 const zcu = pt.zcu;
26034 switch (ty.zigTypeTag(zcu)) {25164 switch (ty.zigTypeTag(zcu)) {
...@@ -26041,217 +25171,122 @@ fn validateExternType(...@@ -26041,217 +25171,122 @@ fn validateExternType(
26041 .error_union,25171 .error_union,
26042 .error_set,25172 .error_set,
26043 .frame,25173 .frame,
26044 => return false,25174 => return,
26045 .void => return position == .union_field or position == .ret_ty or position == .struct_field or position == .element,25175
26046 .noreturn => return position == .ret_ty,25176 .void => try sema.errNote(src_loc, msg, "'void' is a zero bit type", .{}),
26047 .@"opaque",25177 .noreturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
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}
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)) {
26104 .@"opaque",25179 .@"opaque",
26105 .bool,25180 .bool,
26106 .float,25181 .float,
26107 .@"anyframe",25182 .@"anyframe",
26108 => return,25183 => unreachable, // these *are* allowed
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,
2612025184
26121 .pointer => {25185 .pointer => if (ty.isSlice(zcu)) {
26122 if (ty.isSlice(zcu)) {25186 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
26123 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'", .{});
26124 } else {25191 } else {
26125 const pointee_ty = ty.childType(zcu);25192 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.childType(zcu), .other);
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);
26133 }25193 }
26134 },25194 },
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", .{}),
26137 .int => if (!std.math.isPowerOfTwo(ty.intInfo(zcu).bits)) {25195 .int => if (!std.math.isPowerOfTwo(ty.intInfo(zcu).bits)) {
26138 try sema.errNote(src_loc, msg, "only integers with 0 or power of two bits are extern compatible", .{});25196 try sema.errNote(src_loc, msg, "only integers with 0 or power of two bits are extern compatible", .{});
26139 } else {25197 } else {
26140 try sema.errNote(src_loc, msg, "only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible", .{});25198 try sema.errNote(src_loc, msg, "only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible", .{});
26141 },25199 },
26142 .@"fn" => {25200 .@"fn" => if (position != .other) {
26143 if (position != .other) {25201 try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});
26144 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", .{});
26145 try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});25203 } else switch (ty.fnCallingConvention(zcu)) {
26146 return;25204 .auto => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}),
26147 }25205 else => |cc| try sema.errNote(src_loc, msg, "{t} function cannot be extern", .{cc}),
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 }
26154 },25206 },
26155 .@"enum" => {25207 .@"enum" => {
26156 const tag_ty = ty.intTagType(zcu);25208 const enum_obj = zcu.intern_pool.loadEnumType(ty.toIntern());
26157 try sema.errNote(src_loc, msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)});25209 switch (enum_obj.int_tag_mode) {
26158 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);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 }
26159 },25220 },
26160 .@"struct" => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),25221 .@"struct" => {
26161 .@"union" => try sema.errNote(src_loc, msg, "only extern unions and ABI sized packed unions are extern compatible", .{}),25222 const struct_obj = zcu.intern_pool.loadStructType(ty.toIntern());
26162 .array => {25223 switch (struct_obj.layout) {
26163 if (position == .ret_ty) {25224 .auto => try sema.errNote(src_loc, msg, "struct with automatic layout has no guaranteed in-memory representation", .{}),
26164 return sema.errNote(src_loc, msg, "arrays are not allowed as a return type", .{});25225 .@"extern" => unreachable,
26165 } else if (position == .param_ty) {25226 .@"packed" => switch (struct_obj.packed_backing_mode) {
26166 return sema.errNote(src_loc, msg, "arrays are not allowed as a parameter type", .{});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 },
26167 }25234 }
26168 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(zcu), .element);
26169 },25235 },
26170 .vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(zcu), .element),25236 .@"union" => {
26171 .optional => try sema.errNote(src_loc, msg, "only pointer like optionals are extern compatible", .{}),25237 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
26172 }25238 switch (union_obj.layout) {
26173}25239 .auto => try sema.errNote(src_loc, msg, "union with automatic layout has no guaranteed in-memory representation", .{}),
2617425240 .@"extern" => unreachable,
26175/// Returns true if `ty` is allowed in packed types.25241 .@"packed" => switch (union_obj.packed_backing_mode) {
26176/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.25242 .auto => try sema.errNote(src_loc, msg, "inferred backing integer of packed union has unspecified signedness", .{}),
26177fn validatePackedType(sema: *Sema, ty: Type) !bool {25243 .explicit => {
26178 const pt = sema.pt;25244 const backing_int_ty: Type = .fromInterned(union_obj.packed_backing_int_type);
26179 const zcu = pt.zcu;25245 try sema.errNote(src_loc, msg, "packed union backing integer type '{f}' is not extern compatible", .{backing_int_ty.fmt(pt)});
26180 return switch (ty.zigTypeTag(zcu)) {25246 try sema.explainWhyTypeIsNotExtern(msg, src_loc, backing_int_ty, position);
26181 .type,25247 },
26182 .comptime_float,25248 },
26183 .comptime_int,25249 }
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,
26206 },25250 },
26207 .pointer => !ty.isSlice(zcu) and !try ty.comptimeOnlySema(pt),25251 .array => switch (position) {
26208 .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed",25252 .ret_ty => try sema.errNote(src_loc, msg, "arrays are not allowed as a return type", .{}),
26209 };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 }
26210}25259}
2621125260
26212fn explainWhyTypeIsNotPacked(25261pub fn explainWhyTypeIsUnpackable(
26213 sema: *Sema,25262 sema: *Sema,
26214 msg: *Zcu.ErrorMsg,25263 msg: *Zcu.ErrorMsg,
26215 src_loc: LazySrcLoc,25264 src: LazySrcLoc,
26216 ty: Type,25265 reason: Type.UnpackableReason,
26217) CompileError!void {25266) CompileError!void {
26218 const pt = sema.pt;25267 const pt = sema.pt;
26219 const zcu = pt.zcu;25268 const zcu = pt.zcu;
26220 switch (ty.zigTypeTag(zcu)) {25269 switch (reason) {
26221 .void,25270 .comptime_only => try sema.errNote(src, msg, "comptime-only types have no bit-packed representation", .{}),
26222 .bool,25271 .pointer => {
26223 .float,25272 try sema.errNote(src, msg, "pointers cannot be directly bitpacked", .{});
26224 .int,25273 try sema.errNote(src, msg, "consider using 'usize' and '@intFromPtr'", .{});
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);
26248 },25274 },
26249 .@"fn" => {25275 .enum_inferred_int_tag => |enum_ty| {
26250 try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});25276 const enum_src = enum_ty.srcLoc(zcu);
26251 try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});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);
26252 },25287 },
26253 .@"struct" => try sema.errNote(src_loc, msg, "only packed structs layout are allowed in packed types", .{}),25288 .slice => try sema.errNote(src, msg, "slices do not have a bit-packed representation", .{}),
26254 .@"union" => try sema.errNote(src_loc, msg, "only packed unions layout are allowed in packed types", .{}),25289 .other => try sema.errNote(src, msg, "type does not have a bit-packed representation", .{}),
26255 }25290 }
26256}25291}
2625725292
...@@ -26277,7 +25312,14 @@ fn getPanicIdFunc(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.SimplePanicId) !In...@@ -26277,7 +25312,14 @@ fn getPanicIdFunc(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.SimplePanicId) !In
26277 try sema.ensureMemoizedStateResolved(src, .panic);25312 try sema.ensureMemoizedStateResolved(src, .panic);
26278 const panic_fn_index = zcu.builtin_decl_values.get(panic_id.toBuiltin());25313 const panic_fn_index = zcu.builtin_decl_values.get(panic_id.toBuiltin());
26279 switch (sema.owner.unwrap()) {25314 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
26281 .func => |owner_func| zcu.intern_pool.funcSetHasErrorTrace(io, owner_func, true),25323 .func => |owner_func| zcu.intern_pool.funcSetHasErrorTrace(io, owner_func, true),
26282 }25324 }
26283 return panic_fn_index;25325 return panic_fn_index;
...@@ -26297,7 +25339,7 @@ fn addSafetyCheck(...@@ -26297,7 +25339,7 @@ fn addSafetyCheck(
26297 .parent = parent_block,25339 .parent = parent_block,
26298 .sema = sema,25340 .sema = sema,
26299 .namespace = parent_block.namespace,25341 .namespace = parent_block.namespace,
26300 .instructions = .{},25342 .instructions = .empty,
26301 .inlining = parent_block.inlining,25343 .inlining = parent_block.inlining,
26302 .comptime_reason = null,25344 .comptime_reason = null,
26303 .src_base_inst = parent_block.src_base_inst,25345 .src_base_inst = parent_block.src_base_inst,
...@@ -26391,7 +25433,7 @@ fn addSafetyCheckUnwrapError(...@@ -26391,7 +25433,7 @@ fn addSafetyCheckUnwrapError(
26391 .parent = parent_block,25433 .parent = parent_block,
26392 .sema = sema,25434 .sema = sema,
26393 .namespace = parent_block.namespace,25435 .namespace = parent_block.namespace,
26394 .instructions = .{},25436 .instructions = .empty,
26395 .inlining = parent_block.inlining,25437 .inlining = parent_block.inlining,
26396 .comptime_reason = null,25438 .comptime_reason = null,
26397 .src_base_inst = parent_block.src_base_inst,25439 .src_base_inst = parent_block.src_base_inst,
...@@ -26458,21 +25500,39 @@ fn addSafetyCheckSentinelMismatch(...@@ -26458,21 +25500,39 @@ fn addSafetyCheckSentinelMismatch(
26458 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());25500 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());
2645925501
26460 const ptr_ty = sema.typeOf(ptr);25502 const ptr_ty = sema.typeOf(ptr);
26461 const actual_sentinel = if (ptr_ty.isSlice(zcu))25503 const ptr_info = ptr_ty.ptrInfo(zcu);
26462 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)25504 const actual_sentinel: Air.Inst.Ref = switch (ptr_ty.ptrSize(zcu)) {
26463 else blk: {25505 .slice => try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index),
26464 const elem_ptr_ty = try ptr_ty.elemPtrType(null, pt);25506 .one => s: {
26465 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);25507 const array_ty: Type = .fromInterned(ptr_info.child);
26466 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);25508 assert(array_ty.zigTypeTag(zcu) == .array);
26467 };25509 assert(array_ty.childType(zcu).toIntern() == sentinel_ty.toIntern());
2646825510 const many_ptr_ty = try pt.ptrType(.{
26469 const ok = if (sentinel_ty.zigTypeTag(zcu) == .vector) ok: {25511 .child = sentinel_ty.toIntern(),
26470 const eql = try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);25512 .flags = .{
26471 break :ok try parent_block.addReduce(eql, .And);25513 .size = .many,
26472 } else ok: {25514 .is_const = ptr_info.flags.is_const,
26473 assert(sentinel_ty.isSelfComparable(zcu, true));25515 .is_volatile = ptr_info.flags.is_volatile,
26474 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);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,
26475 };25529 };
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
26477 return addSafetyCheckCall(sema, parent_block, src, ok, .@"panic.sentinelMismatch", &.{25537 return addSafetyCheckCall(sema, parent_block, src, ok, .@"panic.sentinelMismatch", &.{
26478 expected_sentinel, actual_sentinel,25538 expected_sentinel, actual_sentinel,
...@@ -26496,7 +25556,7 @@ fn addSafetyCheckCall(...@@ -26496,7 +25556,7 @@ fn addSafetyCheckCall(
26496 .parent = parent_block,25556 .parent = parent_block,
26497 .sema = sema,25557 .sema = sema,
26498 .namespace = parent_block.namespace,25558 .namespace = parent_block.namespace,
26499 .instructions = .{},25559 .instructions = .empty,
26500 .inlining = parent_block.inlining,25560 .inlining = parent_block.inlining,
26501 .comptime_reason = null,25561 .comptime_reason = null,
26502 .src_base_inst = parent_block.src_base_inst,25562 .src_base_inst = parent_block.src_base_inst,
...@@ -26554,8 +25614,10 @@ fn fieldPtrLoad(...@@ -26554,8 +25614,10 @@ fn fieldPtrLoad(
26554 const pt = sema.pt;25614 const pt = sema.pt;
26555 const zcu = pt.zcu;25615 const zcu = pt.zcu;
26556 const object_ptr_ty = sema.typeOf(object_ptr);25616 const object_ptr_ty = sema.typeOf(object_ptr);
25617 assert(object_ptr_ty.zigTypeTag(zcu) == .pointer);
26557 const pointee_ty = object_ptr_ty.childType(zcu);25618 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| {
26559 const object: Air.Inst.Ref = .fromValue(opv);25621 const object: Air.Inst.Ref = .fromValue(opv);
26560 return fieldVal(sema, block, src, object, field_name, field_name_src);25622 return fieldVal(sema, block, src, object, field_name, field_name_src);
26561 }25623 }
...@@ -26603,7 +25665,7 @@ fn fieldVal(...@@ -26603,7 +25665,7 @@ fn fieldVal(
26603 return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern());25665 return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern());
26604 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {25666 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
26605 const ptr_info = object_ty.ptrInfo(zcu);25667 const ptr_info = object_ty.ptrInfo(zcu);
26606 const result_ty = try pt.ptrTypeSema(.{25668 const result_ty = try pt.ptrType(.{
26607 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),25669 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),
26608 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,25670 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,
26609 .flags = .{25671 .flags = .{
...@@ -26663,37 +25725,34 @@ fn fieldVal(...@@ -26663,37 +25725,34 @@ fn fieldVal(
2666325725
26664 switch (child_type.zigTypeTag(zcu)) {25726 switch (child_type.zigTypeTag(zcu)) {
26665 .error_set => {25727 .error_set => {
26666 switch (ip.indexToKey(child_type.toIntern())) {25728 const err_set_ty: Type = err_set: switch (ip.indexToKey(child_type.toIntern())) {
26667 .error_set_type => |error_set_type| blk: {25729 .inferred_error_set_type => |func_index| {
26668 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;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) {
26669 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{25735 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{
26670 field_name.fmt(ip), child_type.fmt(pt),25736 field_name.fmt(ip), child_type.fmt(pt),
26671 });25737 });
26672 },25738 } else child_type,
26673 .inferred_error_set_type => {
26674 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
26675 },
26676 .simple_type => |t| {25739 .simple_type => |t| {
26677 assert(t == .anyerror);25740 assert(t == .anyerror);
26678 _ = try pt.getErrorValue(field_name);25741 _ = try pt.getErrorValue(field_name);
25742 break :err_set try pt.singleErrorSetType(field_name);
26679 },25743 },
26680 else => unreachable,25744 else => unreachable,
26681 }25745 };
2668225746 return .fromIntern(try pt.intern(.{ .err = .{
26683 const error_set_type = if (!child_type.isAnyError(zcu))25747 .ty = err_set_ty.toIntern(),
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(),
26689 .name = field_name,25748 .name = field_name,
26690 } })));25749 } }));
26691 },25750 },
26692 .@"union" => {25751 .@"union" => {
26693 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25752 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
26694 return inst;25753 return inst;
26695 }25754 }
26696 try child_type.resolveFields(pt);25755 try sema.ensureLayoutResolved(child_type, src, .field_used);
26697 if (child_type.unionTagType(zcu)) |enum_ty| {25756 if (child_type.unionTagType(zcu)) |enum_ty| {
26698 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {25757 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {
26699 const field_index: u32 = @intCast(field_index_usize);25758 const field_index: u32 = @intCast(field_index_usize);
...@@ -26706,6 +25765,7 @@ fn fieldVal(...@@ -26706,6 +25765,7 @@ fn fieldVal(
26706 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25765 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
26707 return inst;25766 return inst;
26708 }25767 }
25768 try sema.ensureLayoutResolved(child_type, src, .field_used);
26709 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse25769 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse
26710 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);25770 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
26711 const field_index: u32 = @intCast(field_index_usize);25771 const field_index: u32 = @intCast(field_index_usize);
...@@ -26731,13 +25791,15 @@ fn fieldVal(...@@ -26731,13 +25791,15 @@ fn fieldVal(
26731 },25791 },
26732 .@"struct" => if (is_pointer_to) {25792 .@"struct" => if (is_pointer_to) {
26733 // Avoid loading the entire struct by fetching a pointer and loading that25793 // 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);
26735 return sema.analyzeLoad(block, src, field_ptr, object_src);25796 return sema.analyzeLoad(block, src, field_ptr, object_src);
26736 } else {25797 } else {
26737 return sema.structFieldVal(block, object, field_name, field_name_src, inner_ty);25798 return sema.structFieldVal(block, object, field_name, field_name_src, inner_ty);
26738 },25799 },
26739 .@"union" => if (is_pointer_to) {25800 .@"union" => if (is_pointer_to) {
26740 // Avoid loading the entire union by fetching a pointer and loading that25801 // Avoid loading the entire union by fetching a pointer and loading that
25802 try sema.ensureLayoutResolved(inner_ty, src, .ptr_access);
26741 const field_ptr = try sema.unionFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);25803 const field_ptr = try sema.unionFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
26742 return sema.analyzeLoad(block, src, field_ptr, object_src);25804 return sema.analyzeLoad(block, src, field_ptr, object_src);
26743 } else {25805 } else {
...@@ -26784,10 +25846,10 @@ fn fieldPtr(...@@ -26784,10 +25846,10 @@ fn fieldPtr(
26784 .array => {25846 .array => {
26785 if (field_name.eqlSlice("len", ip)) {25847 if (field_name.eqlSlice("len", ip)) {
26786 const int_val = try pt.intValue(.usize, inner_ty.arrayLen(zcu));25848 const int_val = try pt.intValue(.usize, inner_ty.arrayLen(zcu));
26787 return uavRef(sema, int_val.toIntern());25849 return uavRef(sema, int_val);
26788 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {25850 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
26789 const ptr_info = object_ty.ptrInfo(zcu);25851 const ptr_info = object_ty.ptrInfo(zcu);
26790 const new_ptr_ty = try pt.ptrTypeSema(.{25852 const new_ptr_ty = try pt.ptrType(.{
26791 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),25853 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),
26792 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,25854 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,
26793 .flags = .{25855 .flags = .{
...@@ -26802,10 +25864,11 @@ fn fieldPtr(...@@ -26802,10 +25864,11 @@ fn fieldPtr(
26802 .packed_offset = ptr_info.packed_offset,25864 .packed_offset = ptr_info.packed_offset,
26803 });25865 });
26804 const ptr_ptr_info = object_ptr_ty.ptrInfo(zcu);25866 const ptr_ptr_info = object_ptr_ty.ptrInfo(zcu);
26805 const result_ty = try pt.ptrTypeSema(.{25867 const result_ty = try pt.ptrType(.{
26806 .child = new_ptr_ty.toIntern(),25868 .child = new_ptr_ty.toIntern(),
26807 .sentinel = if (object_ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none,25869 .sentinel = if (object_ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none,
26808 .flags = .{25870 .flags = .{
25871 .size = .one,
26809 .alignment = ptr_ptr_info.flags.alignment,25872 .alignment = ptr_ptr_info.flags.alignment,
26810 .is_const = ptr_ptr_info.flags.is_const,25873 .is_const = ptr_ptr_info.flags.is_const,
26811 .is_volatile = ptr_ptr_info.flags.is_volatile,25874 .is_volatile = ptr_ptr_info.flags.is_volatile,
...@@ -26836,7 +25899,7 @@ fn fieldPtr(...@@ -26836,7 +25899,7 @@ fn fieldPtr(
26836 if (field_name.eqlSlice("ptr", ip)) {25899 if (field_name.eqlSlice("ptr", ip)) {
26837 const slice_ptr_ty = inner_ty.slicePtrFieldType(zcu);25900 const slice_ptr_ty = inner_ty.slicePtrFieldType(zcu);
2683825901
26839 const result_ty = try pt.ptrTypeSema(.{25902 const result_ty = try pt.ptrType(.{
26840 .child = slice_ptr_ty.toIntern(),25903 .child = slice_ptr_ty.toIntern(),
26841 .flags = .{25904 .flags = .{
26842 .is_const = !attr_ptr_ty.ptrIsMutable(zcu),25905 .is_const = !attr_ptr_ty.ptrIsMutable(zcu),
...@@ -26854,7 +25917,7 @@ fn fieldPtr(...@@ -26854,7 +25917,7 @@ fn fieldPtr(
26854 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);25917 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
26855 return field_ptr;25918 return field_ptr;
26856 } else if (field_name.eqlSlice("len", ip)) {25919 } else if (field_name.eqlSlice("len", ip)) {
26857 const result_ty = try pt.ptrTypeSema(.{25920 const result_ty = try pt.ptrType(.{
26858 .child = .usize_type,25921 .child = .usize_type,
26859 .flags = .{25922 .flags = .{
26860 .is_const = !attr_ptr_ty.ptrIsMutable(zcu),25923 .is_const = !attr_ptr_ty.ptrIsMutable(zcu),
...@@ -26881,7 +25944,6 @@ fn fieldPtr(...@@ -26881,7 +25944,6 @@ fn fieldPtr(
26881 }25944 }
26882 },25945 },
26883 .type => {25946 .type => {
26884 _ = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, object_ptr, undefined);
26885 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);25947 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
26886 const inner = if (is_pointer_to)25948 const inner = if (is_pointer_to)
26887 try sema.analyzeLoad(block, src, result, object_ptr_src)25949 try sema.analyzeLoad(block, src, result, object_ptr_src)
...@@ -26893,44 +25955,39 @@ fn fieldPtr(...@@ -26893,44 +25955,39 @@ fn fieldPtr(
2689325955
26894 switch (child_type.zigTypeTag(zcu)) {25956 switch (child_type.zigTypeTag(zcu)) {
26895 .error_set => {25957 .error_set => {
26896 switch (ip.indexToKey(child_type.toIntern())) {25958 const err_set_ty: Type = err_set: switch (ip.indexToKey(child_type.toIntern())) {
26897 .error_set_type => |error_set_type| blk: {25959 .inferred_error_set_type => |func_index| {
26898 if (error_set_type.nameIndex(ip, field_name) != null) {25960 try sema.ensureFuncIesResolved(block, src, func_index);
26899 break :blk;25961 const resolved_ies = ip.funcIesResolvedUnordered(func_index);
26900 }25962 continue :err_set ip.indexToKey(resolved_ies);
25963 },
25964 .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) {
26901 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{25965 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{
26902 field_name.fmt(ip), child_type.fmt(pt),25966 field_name.fmt(ip), child_type.fmt(pt),
26903 });25967 });
26904 },25968 } else child_type,
26905 .inferred_error_set_type => {
26906 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
26907 },
26908 .simple_type => |t| {25969 .simple_type => |t| {
26909 assert(t == .anyerror);25970 assert(t == .anyerror);
26910 _ = try pt.getErrorValue(field_name);25971 _ = try pt.getErrorValue(field_name);
25972 break :err_set try pt.singleErrorSetType(field_name);
26911 },25973 },
26912 else => unreachable,25974 else => unreachable,
26913 }25975 };
2691425976 return uavRef(sema, .fromInterned(try pt.intern(.{ .err = .{
26915 const error_set_type = if (!child_type.isAnyError(zcu))25977 .ty = err_set_ty.toIntern(),
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(),
26921 .name = field_name,25978 .name = field_name,
26922 } }));25979 } })));
26923 },25980 },
26924 .@"union" => {25981 .@"union" => {
26925 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25982 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
26926 return inst;25983 return inst;
26927 }25984 }
26928 try child_type.resolveFields(pt);25985 try sema.ensureLayoutResolved(child_type, src, .field_used);
26929 if (child_type.unionTagType(zcu)) |enum_ty| {25986 if (child_type.unionTagType(zcu)) |enum_ty| {
26930 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| {25987 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| {
26931 const field_index_u32: u32 = @intCast(field_index);25988 const field_index_u32: u32 = @intCast(field_index);
26932 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);25989 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
26933 return uavRef(sema, idx_val.toIntern());25990 return uavRef(sema, idx_val);
26934 }25991 }
26935 }25992 }
26936 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);25993 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
...@@ -26939,12 +25996,13 @@ fn fieldPtr(...@@ -26939,12 +25996,13 @@ fn fieldPtr(
26939 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25996 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
26940 return inst;25997 return inst;
26941 }25998 }
25999 try sema.ensureLayoutResolved(child_type, src, .field_used);
26942 const field_index = child_type.enumFieldIndex(field_name, zcu) orelse {26000 const field_index = child_type.enumFieldIndex(field_name, zcu) orelse {
26943 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);26001 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
26944 };26002 };
26945 const field_index_u32: u32 = @intCast(field_index);26003 const field_index_u32: u32 = @intCast(field_index);
26946 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);26004 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
26947 return uavRef(sema, idx_val.toIntern());26005 return uavRef(sema, idx_val);
26948 },26006 },
26949 .@"struct", .@"opaque" => {26007 .@"struct", .@"opaque" => {
26950 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {26008 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
...@@ -26960,7 +26018,8 @@ fn fieldPtr(...@@ -26960,7 +26018,8 @@ fn fieldPtr(
26960 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)26018 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
26961 else26019 else
26962 object_ptr;26020 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);
26964 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);26023 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
26965 return field_ptr;26024 return field_ptr;
26966 },26025 },
...@@ -26969,6 +26028,7 @@ fn fieldPtr(...@@ -26969,6 +26028,7 @@ fn fieldPtr(
26969 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)26028 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
26970 else26029 else
26971 object_ptr;26030 object_ptr;
26031 try sema.ensureLayoutResolved(inner_ty, src, .ptr_access);
26972 const field_ptr = try sema.unionFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);26032 const field_ptr = try sema.unionFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
26973 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);26033 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
26974 return field_ptr;26034 return field_ptr;
...@@ -27012,6 +26072,7 @@ fn fieldCallBind(...@@ -27012,6 +26072,7 @@ fn fieldCallBind(
27012 // Optionally dereference a second pointer to get the concrete type.26072 // Optionally dereference a second pointer to get the concrete type.
27013 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;26073 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;
27014 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;26074 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;
26075 try sema.ensureLayoutResolved(concrete_ty, src, .ptr_access);
27015 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;26076 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
27016 const object_ptr = if (is_double_ptr)26077 const object_ptr = if (is_double_ptr)
27017 try sema.analyzeLoad(block, src, raw_ptr, src)26078 try sema.analyzeLoad(block, src, raw_ptr, src)
...@@ -27021,10 +26082,8 @@ fn fieldCallBind(...@@ -27021,10 +26082,8 @@ fn fieldCallBind(
27021 find_field: {26082 find_field: {
27022 switch (concrete_ty.zigTypeTag(zcu)) {26083 switch (concrete_ty.zigTypeTag(zcu)) {
27023 .@"struct" => {26084 .@"struct" => {
27024 try concrete_ty.resolveFields(pt);
27025 if (zcu.typeToStruct(concrete_ty)) |struct_type| {26085 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
27026 const field_index = struct_type.nameIndex(ip, field_name) orelse26086 const field_index = struct_type.nameIndex(ip, field_name) orelse break :find_field;
27027 break :find_field;
27028 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);26087 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
2702926088
27030 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);26089 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
...@@ -27047,9 +26106,9 @@ fn fieldCallBind(...@@ -27047,9 +26106,9 @@ fn fieldCallBind(
27047 }26106 }
27048 },26107 },
27049 .@"union" => {26108 .@"union" => {
27050 try concrete_ty.resolveFields(pt);
27051 const union_obj = zcu.typeToUnion(concrete_ty).?;26109 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;
27053 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);26112 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
27054 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };26113 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };
27055 },26114 },
...@@ -27163,7 +26222,7 @@ fn finishFieldCallBind(...@@ -27163,7 +26222,7 @@ fn finishFieldCallBind(
27163) CompileError!ResolvedFieldCallee {26222) CompileError!ResolvedFieldCallee {
27164 const pt = sema.pt;26223 const pt = sema.pt;
27165 const zcu = pt.zcu;26224 const zcu = pt.zcu;
27166 const ptr_field_ty = try pt.ptrTypeSema(.{26225 const ptr_field_ty = try pt.ptrType(.{
27167 .child = field_ty.toIntern(),26226 .child = field_ty.toIntern(),
27168 .flags = .{26227 .flags = .{
27169 .is_const = !ptr_ty.ptrIsMutable(zcu),26228 .is_const = !ptr_ty.ptrIsMutable(zcu),
...@@ -27174,7 +26233,6 @@ fn finishFieldCallBind(...@@ -27174,7 +26233,6 @@ fn finishFieldCallBind(
27174 const container_ty = ptr_ty.childType(zcu);26233 const container_ty = ptr_ty.childType(zcu);
27175 if (container_ty.zigTypeTag(zcu) == .@"struct") {26234 if (container_ty.zigTypeTag(zcu) == .@"struct") {
27176 if (container_ty.structFieldIsComptime(field_index, zcu)) {26235 if (container_ty.structFieldIsComptime(field_index, zcu)) {
27177 try container_ty.resolveStructFieldInits(pt);
27178 const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?;26236 const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?;
27179 return .{ .direct = Air.internedToRef(default_val.toIntern()) };26237 return .{ .direct = Air.internedToRef(default_val.toIntern()) };
27180 }26238 }
...@@ -27239,6 +26297,7 @@ fn namespaceLookupVal(...@@ -27239,6 +26297,7 @@ fn namespaceLookupVal(
27239 return try sema.analyzeNavVal(block, src, nav);26297 return try sema.analyzeNavVal(block, src, nav);
27240}26298}
2724126299
26300/// Asserts that the layout of `struct_ty` is already resolved.
27242fn structFieldPtr(26301fn structFieldPtr(
27243 sema: *Sema,26302 sema: *Sema,
27244 block: *Block,26303 block: *Block,
...@@ -27247,33 +26306,33 @@ fn structFieldPtr(...@@ -27247,33 +26306,33 @@ fn structFieldPtr(
27247 field_name: InternPool.NullTerminatedString,26306 field_name: InternPool.NullTerminatedString,
27248 field_name_src: LazySrcLoc,26307 field_name_src: LazySrcLoc,
27249 struct_ty: Type,26308 struct_ty: Type,
27250 initializing: bool,
27251) CompileError!Air.Inst.Ref {26309) CompileError!Air.Inst.Ref {
27252 const pt = sema.pt;26310 const pt = sema.pt;
27253 const zcu = pt.zcu;26311 const zcu = pt.zcu;
27254 const ip = &zcu.intern_pool;26312 const ip = &zcu.intern_pool;
27255 assert(struct_ty.zigTypeTag(zcu) == .@"struct");
2725626313
27257 try struct_ty.resolveFields(pt);26314 assert(struct_ty.zigTypeTag(zcu) == .@"struct");
27258 try struct_ty.resolveLayout(pt);26315 struct_ty.assertHasLayout(zcu);
2725926316
27260 if (struct_ty.isTuple(zcu)) {26317 const field_index: u32 = if (struct_ty.isTuple(zcu)) field_index: {
27261 if (field_name.eqlSlice("len", ip)) {26318 if (field_name.eqlSlice("len", ip)) {
27262 const len_inst = try pt.intRef(.usize, struct_ty.structFieldCount(zcu));26319 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);
27264 }26321 }
27265 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);26322 break :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);26323 } else field_index: {
27267 }26324 const struct_type = zcu.typeToStruct(struct_ty).?;
2726826325 break :field_index struct_type.nameIndex(ip, field_name) orelse {
27269 const struct_type = zcu.typeToStruct(struct_ty).?;26326 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
2727026327 };
27271 const field_index = struct_type.nameIndex(ip, field_name) orelse26328 };
27272 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
2727326329
27274 return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, struct_ty);26330 return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, struct_ty);
27275}26331}
2727626332
26333/// Supports both structs and unions.
26334///
26335/// Asserts that the layout of `struct_ty` is already resolved.
27277fn structFieldPtrByIndex(26336fn structFieldPtrByIndex(
27278 sema: *Sema,26337 sema: *Sema,
27279 block: *Block,26338 block: *Block,
...@@ -27284,79 +26343,24 @@ fn structFieldPtrByIndex(...@@ -27284,79 +26343,24 @@ fn structFieldPtrByIndex(
27284) CompileError!Air.Inst.Ref {26343) CompileError!Air.Inst.Ref {
27285 const pt = sema.pt;26344 const pt = sema.pt;
27286 const zcu = pt.zcu;26345 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 later26347 struct_ty.assertHasLayout(zcu);
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];
27301 const struct_ptr_ty = sema.typeOf(struct_ptr);26348 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)26350 if (struct_ty.structFieldIsComptime(field_index, zcu)) {
27314 struct_ptr_ty_info.flags.alignment26351 const field_ptr_ty = try struct_ptr_ty.fieldPtrType(field_index, pt);
27315 else26352 return .fromIntern(try pt.intern(.{ .ptr = .{
27316 try Type.fromInterned(struct_ptr_ty_info.child).abiAlignmentSema(pt);26353 .ty = field_ptr_ty.toIntern(),
2731726354 .base_addr = .{ .comptime_field = struct_ty.structFieldDefaultValue(field_index, zcu).?.toIntern() },
27318 if (struct_type.layout == .@"packed") {26355 .byte_offset = 0,
27319 assert(!field_is_comptime);26356 } }));
27320 const packed_offset = struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt);26357 } else if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
27321 ptr_ty_data.flags.alignment = parent_align;26358 return .fromValue(try struct_ptr_val.ptrField(field_index, pt));
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)));
27333 } else {26359 } else {
27334 // Our alignment is capped at the field alignment.26360 const field_ptr_ty = try struct_ptr_ty.fieldPtrType(field_index, pt);
27335 const field_align = try Type.fromInterned(field_ty).structFieldAlignmentSema(26361 return block.addStructFieldPtr(struct_ptr, field_index, field_ptr_ty);
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);
27344 }26362 }
2734526363}
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}
2736026364
27361fn structFieldVal(26365fn structFieldVal(
27362 sema: *Sema,26366 sema: *Sema,
...@@ -27370,8 +26374,8 @@ fn structFieldVal(...@@ -27370,8 +26374,8 @@ fn structFieldVal(
27370 const zcu = pt.zcu;26374 const zcu = pt.zcu;
27371 const ip = &zcu.intern_pool;26375 const ip = &zcu.intern_pool;
27372 assert(struct_ty.zigTypeTag(zcu) == .@"struct");26376 assert(struct_ty.zigTypeTag(zcu) == .@"struct");
2737326377 assert(sema.typeOf(struct_byval).toIntern() == struct_ty.toIntern());
27374 try struct_ty.resolveFields(pt);26378 struct_ty.assertHasLayout(zcu);
2737526379
27376 switch (ip.indexToKey(struct_ty.toIntern())) {26380 switch (ip.indexToKey(struct_ty.toIntern())) {
27377 .struct_type => {26381 .struct_type => {
...@@ -27379,24 +26383,19 @@ fn structFieldVal(...@@ -27379,24 +26383,19 @@ fn structFieldVal(
2737926383
27380 const field_index = struct_type.nameIndex(ip, field_name) orelse26384 const field_index = struct_type.nameIndex(ip, field_name) orelse
27381 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);26385 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
27382 if (struct_type.fieldIsComptime(ip, field_index)) {26386 if (struct_type.field_is_comptime_bits.get(ip, field_index)) {
27383 try struct_ty.resolveStructFieldInits(pt);26387 return .fromIntern(struct_type.field_defaults.get(ip)[field_index]);
27384 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
27385 }26388 }
2738626389
27387 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);26390 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
27388 if (try sema.typeHasOnePossibleValue(field_ty)) |field_val|26391 if (try field_ty.onePossibleValue(pt)) |field_val|
27389 return Air.internedToRef(field_val.toIntern());26392 return .fromValue(field_val);
2739026393
27391 if (try sema.resolveValue(struct_byval)) |struct_val| {26394 if (sema.resolveValue(struct_byval)) |struct_val| {
27392 if (struct_val.isUndef(zcu)) return pt.undefRef(field_ty);26395 if (struct_val.isUndef(zcu)) return pt.undefRef(field_ty);
27393 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {26396 return .fromValue(try struct_val.fieldValue(pt, field_index));
27394 return Air.internedToRef(opv.toIntern());
27395 }
27396 return Air.internedToRef((try struct_val.fieldValue(pt, field_index)).toIntern());
27397 }26397 }
2739826398
27399 try field_ty.resolveLayout(pt);
27400 return block.addStructFieldVal(struct_byval, field_index, field_ty);26399 return block.addStructFieldVal(struct_byval, field_index, field_ty);
27401 },26400 },
27402 .tuple_type => {26401 .tuple_type => {
...@@ -27457,16 +26456,13 @@ fn tupleFieldValByIndex(...@@ -27457,16 +26456,13 @@ fn tupleFieldValByIndex(
27457 const zcu = pt.zcu;26456 const zcu = pt.zcu;
27458 const field_ty = tuple_ty.fieldType(field_index, zcu);26457 const field_ty = tuple_ty.fieldType(field_index, zcu);
2745926458
27460 if (tuple_ty.structFieldIsComptime(field_index, zcu))
27461 try tuple_ty.resolveStructFieldInits(pt);
27462 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {26459 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
27463 return Air.internedToRef(default_value.toIntern());26460 return Air.internedToRef(default_value.toIntern());
27464 }26461 }
2746526462
27466 if (try sema.resolveValue(tuple_byval)) |tuple_val| {26463 if (try field_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
27467 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {26464
27468 return Air.internedToRef(opv.toIntern());26465 if (sema.resolveValue(tuple_byval)) |tuple_val| {
27469 }
27470 return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) {26466 return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) {
27471 .undef => pt.undefRef(field_ty),26467 .undef => pt.undefRef(field_ty),
27472 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {26468 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {
...@@ -27478,10 +26474,10 @@ fn tupleFieldValByIndex(...@@ -27478,10 +26474,10 @@ fn tupleFieldValByIndex(
27478 };26474 };
27479 }26475 }
2748026476
27481 try field_ty.resolveLayout(pt);
27482 return block.addStructFieldVal(tuple_byval, field_index, field_ty);26477 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
27483}26478}
2748426479
26480/// Asserts that the layout of `union_ty` is already resolved.
27485fn unionFieldPtr(26481fn unionFieldPtr(
27486 sema: *Sema,26482 sema: *Sema,
27487 block: *Block,26483 block: *Block,
...@@ -27497,35 +26493,17 @@ fn unionFieldPtr(...@@ -27497,35 +26493,17 @@ fn unionFieldPtr(
27497 const ip = &zcu.intern_pool;26493 const ip = &zcu.intern_pool;
2749826494
27499 assert(union_ty.zigTypeTag(zcu) == .@"union");26495 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);
27504 const union_obj = zcu.typeToUnion(union_ty).?;26498 const union_obj = zcu.typeToUnion(union_ty).?;
26499 const tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
26500
27505 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);26501 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
27506 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);26502 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) {
27527 const msg = msg: {26505 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)});
27529 errdefer msg.destroy(sema.gpa);26507 errdefer msg.destroy(sema.gpa);
2753026508
27531 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{26509 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
...@@ -27538,30 +26516,24 @@ fn unionFieldPtr(...@@ -27538,30 +26516,24 @@ fn unionFieldPtr(
27538 }26516 }
2753926517
27540 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {26518 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {
27541 switch (union_obj.flagsUnordered(ip).layout) {26519 switch (union_obj.layout) {
27542 .auto => if (initializing) {26520 .auto => if (initializing) {
27543 if (!sema.isComptimeMutablePtr(union_ptr_val)) {26521 if (!sema.isComptimeMutablePtr(union_ptr_val)) {
27544 // The initialization is a runtime operation.26522 // The initialization is a runtime operation.
27545 break :ct;26523 break :ct;
27546 }26524 }
27547 // Store to the union to initialize the tag.26525 // Store to the union to initialize the tag.
27548 const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);26526 const field_tag = try pt.enumValueFieldIndex(tag_ty, field_index);
27549 const payload_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);26527 const payload_val = try field_ty.onePossibleValue(pt) orelse try pt.undefValue(field_ty);
27550 const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty));26528 const new_union_val = try pt.unionValue(union_ty, field_tag, payload_val);
27551 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);26529 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);
27552 } else {26530 } else {
27553 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse26531 const union_val = try sema.pointerDeref(block, src, union_ptr_val, union_ptr_val.typeOf(zcu)) orelse break :ct;
27554 break :ct;26532 if (union_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);
27555 if (union_val.isUndef(zcu)) {26533 const active_index = tag_ty.enumTagFieldIndex(union_val.unionTag(zcu).?, zcu).?;
27556 return sema.failWithUseOfUndef(block, src, null);26534 if (active_index != field_index) {
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) {
27562 const msg = msg: {26535 const msg = msg: {
27563 const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;26536 const active_field_name = tag_ty.enumFieldName(active_index, zcu);
27564 const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);
27565 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{26537 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
27566 field_name.fmt(ip),26538 field_name.fmt(ip),
27567 active_field_name.fmt(ip),26539 active_field_name.fmt(ip),
...@@ -27575,34 +26547,34 @@ fn unionFieldPtr(...@@ -27575,34 +26547,34 @@ fn unionFieldPtr(
27575 },26547 },
27576 .@"packed", .@"extern" => {},26548 .@"packed", .@"extern" => {},
27577 }26549 }
27578 const field_ptr_val = try union_ptr_val.ptrField(field_index, pt);26550 return .fromValue(try union_ptr_val.ptrField(field_index, pt));
27579 return Air.internedToRef(field_ptr_val.toIntern());
27580 }26551 }
2758126552
27582 // If the union has a tag, we must either set or or safety check it depending on `initializing`.26553 // If the union has a tag, we must either set or or safety check it depending on `initializing`.
27583 tag: {26554 tag: {
27584 if (union_ty.containerLayout(zcu) != .auto) break :tag;26555 if (union_ty.containerLayout(zcu) != .auto) break :tag;
27585 const tag_ty: Type = .fromInterned(union_obj.enum_tag_ty);26556 if (tag_ty.classify(zcu) == .one_possible_value) break :tag;
27586 if (try sema.typeHasOnePossibleValue(tag_ty) != null) break :tag;
27587 // There is a hypothetical non-trivial tag. We must set it even if not there at runtime, but26557 // There is a hypothetical non-trivial tag. We must set it even if not there at runtime, but
27588 // only emit a safety check if it's available at runtime (i.e. it's safety-tagged).26558 // 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);
27590 if (initializing) {26560 if (initializing) {
27591 const set_tag_inst = try block.addBinOp(.set_union_tag, union_ptr, .fromValue(want_tag));26561 const set_tag_inst = try block.addBinOp(.set_union_tag, union_ptr, .fromValue(want_tag));
27592 try sema.checkComptimeKnownStore(block, set_tag_inst, .unneeded); // `unneeded` since this isn't a "proper" store26562 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)) {26563 } else if (block.wantSafety() and union_obj.has_runtime_tag) {
27594 // The tag exists at runtime (safety tag), so emit a safety check.26564 // The tag exists at runtime (actual or safety tag), so emit a safety check.
27595 // TODO would it be better if get_union_tag supported pointers to unions?26565 // TODO would it be better if get_union_tag supported pointers to unions?
27596 const union_val = try block.addTyOp(.load, union_ty, union_ptr);26566 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
27597 const active_tag = try block.addTyOp(.get_union_tag, tag_ty, union_val);26567 const active_tag = try block.addTyOp(.get_union_tag, tag_ty, union_val);
27598 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, .fromValue(want_tag));26568 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, .fromValue(want_tag));
27599 }26569 }
27600 }26570 }
27601 if (field_ty.zigTypeTag(zcu) == .noreturn) {26571 if (field_ty.classify(zcu) == .no_possible_value) {
27602 _ = try block.addNoOp(.unreach);26572 _ = try block.addNoOp(.unreach);
27603 return .unreachable_value;26573 return .unreachable_value;
27604 }26574 }
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);
27606}26578}
2760726579
27608fn unionFieldVal(26580fn unionFieldVal(
...@@ -27618,71 +26590,57 @@ fn unionFieldVal(...@@ -27618,71 +26590,57 @@ fn unionFieldVal(
27618 const zcu = pt.zcu;26590 const zcu = pt.zcu;
27619 const ip = &zcu.intern_pool;26591 const ip = &zcu.intern_pool;
27620 assert(union_ty.zigTypeTag(zcu) == .@"union");26592 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);
27623 const union_obj = zcu.typeToUnion(union_ty).?;26596 const union_obj = zcu.typeToUnion(union_ty).?;
27624 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);26597 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
27625 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);26598 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| {
27629 if (union_val.isUndef(zcu)) return pt.undefRef(field_ty);26602 if (union_val.isUndef(zcu)) return pt.undefRef(field_ty);
2763026603 switch (union_obj.layout) {
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) {
27635 .auto => {26604 .auto => {
27636 if (tag_matches) {26605 const active_tag_val = union_val.unionTag(zcu).?;
27637 return Air.internedToRef(un.val);26606 const active_index = enum_tag_ty.enumTagFieldIndex(active_tag_val, zcu).?;
27638 } else {26607 if (active_index == field_index) return .fromValue(union_val.unionPayload(zcu));
27639 const msg = msg: {26608 return sema.failWithOwnedErrorMsg(block, msg: {
27640 const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;26609 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
27641 const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);26610 field_name.fmt(ip), enum_tag_ty.enumFieldName(active_index, zcu).fmt(ip),
27642 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{26611 });
27643 field_name.fmt(ip), active_field_name.fmt(ip),26612 errdefer msg.destroy(zcu.comp.gpa);
27644 });26613 try sema.addDeclaredHereNote(msg, union_ty);
27645 errdefer msg.destroy(sema.gpa);26614 break :msg msg;
27646 try sema.addDeclaredHereNote(msg, union_ty);26615 });
27647 break :msg msg;
27648 };
27649 return sema.failWithOwnedErrorMsg(block, msg);
27650 }
27651 },26616 },
27652 .@"extern" => if (tag_matches) {26617 .@"extern" => if (try sema.bitCastVal(union_val, field_ty, 0, 0, 0)) |field_val| {
27653 // Fast path - no need to use bitcast logic.26618 return .fromValue(field_val);
27654 return Air.internedToRef(un.val);26619 } else {
27655 } else if (try sema.bitCastVal(union_val, field_ty, 0, 0, 0)) |field_val| {26620 // Runtime-known due to a pointer-to-integer conversion.
27656 return Air.internedToRef(field_val.toIntern());
27657 },26621 },
27658 .@"packed" => if (tag_matches) {26622 .@"packed" => {
27659 // Fast path - no need to use bitcast logic.26623 const field_val = try sema.bitCastVal(union_val, field_ty, 0, union_ty.bitSize(zcu), 0) orelse {
27660 return Air.internedToRef(un.val);26624 unreachable; // `null` is only possible if the input value contains a pointer, which a packed union cannot.
27661 } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeSema(pt), 0)) |field_val| {26625 };
27662 return Air.internedToRef(field_val.toIntern());26626 return .fromValue(field_val);
27663 },26627 },
27664 }26628 }
27665 }26629 }
2766626630
27667 if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and26631 if (union_obj.layout == .auto and block.wantSafety() and union_obj.has_runtime_tag) {
27668 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)26632 const wanted_tag_val = try pt.enumValueFieldIndex(enum_tag_ty, field_index);
27669 {26633 const active_tag = try block.addTyOp(.get_union_tag, enum_tag_ty, union_byval);
27670 const wanted_tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);26634 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, .fromValue(wanted_tag_val));
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);
27674 }26635 }
2767526636
27676 if (field_ty.zigTypeTag(zcu) == .noreturn) {26637 if (field_ty.classify(zcu) == .no_possible_value) {
27677 _ = try block.addNoOp(.unreach);26638 _ = try block.addNoOp(.unreach);
27678 return .unreachable_value;26639 return .unreachable_value;
27679 }26640 }
2768026641
27681 if (try sema.typeHasOnePossibleValue(field_ty)) |field_only_value| {26642 if (try field_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
27682 return Air.internedToRef(field_only_value.toIntern());
27683 }
2768426643
27685 try field_ty.resolveLayout(pt);
27686 return block.addStructFieldVal(union_byval, field_index, field_ty);26644 return block.addStructFieldVal(union_byval, field_index, field_ty);
27687}26645}
2768826646
...@@ -27706,17 +26664,15 @@ fn elemPtr(...@@ -27706,17 +26664,15 @@ fn elemPtr(
27706 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),26664 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),
27707 };26665 };
27708 try sema.checkIndexable(block, src, indexable_ty);26666 try sema.checkIndexable(block, src, indexable_ty);
26667 try sema.ensureLayoutResolved(indexable_ty, src, .ptr_access);
2770926668
27710 const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) {26669 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),26670 .vector => try sema.elemPtrVector(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init),
27712 .@"struct" => blk: {26671 .array => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
27713 // Tuple field access.26672 .@"struct" => try sema.tupleElemPtr(block, src, indexable_ptr, elem_index, elem_index_src),
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 },
27718 else => {26673 else => {
27719 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);26674 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);
27720 return elemPtrOneLayerOnly(sema, block, src, indexable, elem_index, elem_index_src, init, oob_safety);26676 return elemPtrOneLayerOnly(sema, block, src, indexable, elem_index, elem_index_src, init, oob_safety);
27721 },26677 },
27722 };26678 };
...@@ -27725,7 +26681,7 @@ fn elemPtr(...@@ -27725,7 +26681,7 @@ fn elemPtr(
27725 return elem_ptr;26681 return elem_ptr;
27726}26682}
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.
27729fn elemPtrOneLayerOnly(26685fn elemPtrOneLayerOnly(
27730 sema: *Sema,26686 sema: *Sema,
27731 block: *Block,26687 block: *Block,
...@@ -27741,28 +26697,31 @@ fn elemPtrOneLayerOnly(...@@ -27741,28 +26697,31 @@ fn elemPtrOneLayerOnly(
27741 const pt = sema.pt;26697 const pt = sema.pt;
27742 const zcu = pt.zcu;26698 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
27746 switch (indexable_ty.ptrSize(zcu)) {26705 switch (indexable_ty.ptrSize(zcu)) {
27747 .slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),26706 .slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
27748 .many, .c => {26707 .many, .c => {
27749 const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_src, indexable);26708 const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
27750 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);26709 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;
27751 ct: {26711 ct: {
27752 const ptr_val = maybe_ptr_val orelse break :ct;26712 const ptr_val = maybe_ptr_val orelse break :ct;
27753 const index_val = maybe_index_val orelse break :ct;26713 const index: usize = @intCast(maybe_index orelse break :ct);
27754 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));26714 return .fromValue(try ptr_val.ptrElem(index, pt));
27755 const elem_ptr = try ptr_val.ptrElem(index, pt);
27756 return Air.internedToRef(elem_ptr.toIntern());
27757 }26715 }
2775826716
27759 try sema.checkLogicalPtrOperation(block, src, indexable_ty);26717 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
27762 try sema.validateRuntimeElemAccess(block, elem_index_src, result_ty, indexable_ty, indexable_src);26721 try sema.validateRuntimeElemAccess(block, elem_index_src, result_ty, indexable_ty, indexable_src);
27763 try sema.validateRuntimeValue(block, indexable_src, indexable);26722 try sema.validateRuntimeValue(block, indexable_src, indexable);
2776426723
27765 if (!try result_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) {26724 if (child_ty.abiSize(zcu) == 0) {
27766 // zero-bit child type; just bitcast the pointer26725 // zero-bit child type; just bitcast the pointer
27767 return block.addBitCast(result_ty, indexable);26726 return block.addBitCast(result_ty, indexable);
27768 }26727 }
...@@ -27770,15 +26729,10 @@ fn elemPtrOneLayerOnly(...@@ -27770,15 +26729,10 @@ fn elemPtrOneLayerOnly(
27770 return block.addPtrElemPtr(indexable, elem_index, result_ty);26729 return block.addPtrElemPtr(indexable, elem_index, result_ty);
27771 },26730 },
27772 .one => {26731 .one => {
27773 const child_ty = indexable_ty.childType(zcu);
27774 const elem_ptr = switch (child_ty.zigTypeTag(zcu)) {26732 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),26733 .vector => try sema.elemPtrVector(block, indexable_src, indexable, elem_index_src, elem_index, init),
27776 .@"struct" => blk: {26734 .array => try sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety),
27777 assert(child_ty.isTuple(zcu));26735 .@"struct" => try sema.tupleElemPtr(block, indexable_src, indexable, elem_index, elem_index_src),
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 },
27782 else => unreachable, // Guaranteed by checkIndexable26736 else => unreachable, // Guaranteed by checkIndexable
27783 };26737 };
27784 try sema.checkKnownAllocPtr(block, indexable, elem_ptr);26738 try sema.checkKnownAllocPtr(block, indexable, elem_ptr);
...@@ -27808,45 +26762,51 @@ fn elemVal(...@@ -27808,45 +26762,51 @@ fn elemVal(
27808 const elem_index = try sema.coerce(block, .usize, elem_index_uncasted, elem_index_src);26762 const elem_index = try sema.coerce(block, .usize, elem_index_uncasted, elem_index_src);
2780926763
27810 switch (indexable_ty.zigTypeTag(zcu)) {26764 switch (indexable_ty.zigTypeTag(zcu)) {
27811 .pointer => switch (indexable_ty.ptrSize(zcu)) {26765 .pointer => {
27812 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),26766 const child_ty = indexable_ty.childType(zcu);
27813 .many, .c => {26767 try sema.ensureLayoutResolved(child_ty, src, .ptr_access);
27814 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);26768 switch (indexable_ty.ptrSize(zcu)) {
27815 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);26769 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
27816 const elem_ty = indexable_ty.elemType2(zcu);26770 .many, .c => {
2781726771 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
27818 ct: {26772 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
27819 const indexable_val = maybe_indexable_val orelse break :ct;26773
27820 const index_val = maybe_index_val orelse break :ct;26774 ct: {
27821 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));26775 const indexable_val = maybe_indexable_val orelse break :ct;
27822 const many_ptr_ty = try pt.manyConstPtrType(elem_ty);26776 const index_val = maybe_index_val orelse break :ct;
27823 const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty);26777 const index: usize = @intCast(index_val.toUnsignedInt(zcu));
27824 const elem_ptr_ty = try pt.singleConstPtrType(elem_ty);26778 const many_ptr_ty = try pt.manyConstPtrType(child_ty);
27825 const elem_ptr_val = try many_ptr_val.ptrElem(index, pt);26779 const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty);
27826 const elem_val = try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty) orelse break :ct;26780 const elem_ptr_val = try many_ptr_val.ptrElem(index, pt);
27827 return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern());26781 return sema.analyzeLoad(block, src, .fromValue(elem_ptr_val), indexable_src);
27828 }26782 }
2782926783
27830 if (try sema.typeHasOnePossibleValue(elem_ty)) |elem_only_value| {26784 try sema.validateRuntimeElemAccess(block, elem_index_src, child_ty, indexable_ty, src);
27831 return Air.internedToRef(elem_only_value.toIntern());26785 switch (child_ty.classify(zcu)) {
27832 }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);26795 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
27835 return block.addBinOp(.ptr_elem_val, indexable, elem_index);26796 },
27836 },26797 .one => {
27837 .one => {26798 arr_sent: {
27838 arr_sent: {26799 if (child_ty.zigTypeTag(zcu) != .array) break :arr_sent;
27839 const inner_ty = indexable_ty.childType(zcu);26800 const sentinel = child_ty.sentinel(zcu) orelse break :arr_sent;
27840 if (inner_ty.zigTypeTag(zcu) != .array) break :arr_sent;26801 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;
27841 const sentinel = inner_ty.sentinel(zcu) orelse break :arr_sent;26802 const index = try sema.usizeCast(block, src, index_val.toUnsignedInt(zcu));
27842 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;26803 if (index != child_ty.arrayLen(zcu)) break :arr_sent;
27843 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(pt));26804 return .fromValue(sentinel);
27844 if (index != inner_ty.arrayLen(zcu)) break :arr_sent;26805 }
27845 return Air.internedToRef(sentinel.toIntern());26806 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);
27846 }26807 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
27847 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);26808 },
27848 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);26809 }
27849 },
27850 },26810 },
27851 .array => return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),26811 .array => return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
27852 .vector => {26812 .vector => {
...@@ -27856,7 +26816,7 @@ fn elemVal(...@@ -27856,7 +26816,7 @@ fn elemVal(
27856 .@"struct" => {26816 .@"struct" => {
27857 // Tuple field access.26817 // Tuple field access.
27858 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ .simple = .tuple_field_index });26818 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));
27860 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);26820 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
27861 },26821 },
27862 else => unreachable,26822 else => unreachable,
...@@ -27864,6 +26824,7 @@ fn elemVal(...@@ -27864,6 +26824,7 @@ fn elemVal(
27864}26824}
2786526825
27866/// Called when the index or indexable is runtime known.26826/// Called when the index or indexable is runtime known.
26827/// Asserts that the layout of `elem_ty` is already resolved.
27867fn validateRuntimeElemAccess(26828fn validateRuntimeElemAccess(
27868 sema: *Sema,26829 sema: *Sema,
27869 block: *Block,26830 block: *Block,
...@@ -27875,16 +26836,16 @@ fn validateRuntimeElemAccess(...@@ -27875,16 +26836,16 @@ fn validateRuntimeElemAccess(
27875 const pt = sema.pt;26836 const pt = sema.pt;
27876 const zcu = pt.zcu;26837 const zcu = pt.zcu;
2787726838
27878 if (try elem_ty.comptimeOnlySema(sema.pt)) {26839 if (elem_ty.comptimeOnly(zcu)) {
27879 const msg = msg: {26840 const msg = msg: {
27880 const msg = try sema.errMsg(26841 const msg = try sema.errMsg(
27881 elem_index_src,26842 elem_index_src,
27882 "values of type '{f}' must be comptime-known, but index value is runtime-known",26843 "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)},
27884 );26845 );
27885 errdefer msg.destroy(sema.gpa);26846 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
27889 break :msg msg;26850 break :msg msg;
27890 };26851 };
...@@ -27900,71 +26861,38 @@ fn validateRuntimeElemAccess(...@@ -27900,71 +26861,38 @@ fn validateRuntimeElemAccess(
27900 }26861 }
27901}26862}
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(
27904 sema: *Sema,26868 sema: *Sema,
27905 block: *Block,26869 block: *Block,
27906 tuple_ptr_src: LazySrcLoc,26870 src: LazySrcLoc,
27907 tuple_ptr: Air.Inst.Ref,26871 tuple_ptr: Air.Inst.Ref,
27908 field_index_src: LazySrcLoc,26872 elem_index: Air.Inst.Ref,
27909 field_index: u32,26873 elem_index_src: LazySrcLoc,
27910 init: bool,
27911) CompileError!Air.Inst.Ref {26874) CompileError!Air.Inst.Ref {
27912 const pt = sema.pt;26875 const pt = sema.pt;
27913 const zcu = pt.zcu;26876 const zcu = pt.zcu;
27914 const tuple_ptr_ty = sema.typeOf(tuple_ptr);26877 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
27915 const tuple_ptr_info = tuple_ptr_ty.ptrInfo(zcu);26878 assert(tuple_ptr_ty.isSinglePointer(zcu));
27916 const tuple_ty: Type = .fromInterned(tuple_ptr_info.child);26879 const tuple_ty = tuple_ptr_ty.childType(zcu);
27917 try tuple_ty.resolveFields(pt);26880 assert(tuple_ty.isTuple(zcu));
27918 const field_count = tuple_ty.structFieldCount(zcu);
2791926881
26882 const field_count = tuple_ty.structFieldCount(zcu);
27920 if (field_count == 0) {26883 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", .{});
27922 }26885 }
2792326886
27924 if (field_index >= field_count) {26887 const elem_index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ .simple = .tuple_field_index });
27925 return sema.fail(block, field_index_src, "index {d} outside tuple of length {d}", .{26888 const index = elem_index_val.getUnsignedInt(zcu);
27926 field_index, field_count,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),
27927 });26892 });
27928 }26893 }
2792926894
27930 const field_ty = tuple_ty.fieldType(field_index, zcu);26895 return sema.structFieldPtrByIndex(block, src, tuple_ptr, @intCast(index.?), tuple_ty);
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);
27968}26896}
2796926897
27970fn tupleField(26898fn tupleField(
...@@ -27978,7 +26906,6 @@ fn tupleField(...@@ -27978,7 +26906,6 @@ fn tupleField(
27978 const pt = sema.pt;26906 const pt = sema.pt;
27979 const zcu = pt.zcu;26907 const zcu = pt.zcu;
27980 const tuple_ty = sema.typeOf(tuple);26908 const tuple_ty = sema.typeOf(tuple);
27981 try tuple_ty.resolveFields(pt);
27982 const field_count = tuple_ty.structFieldCount(zcu);26909 const field_count = tuple_ty.structFieldCount(zcu);
2798326910
27984 if (field_count == 0) {26911 if (field_count == 0) {
...@@ -27993,20 +26920,17 @@ fn tupleField(...@@ -27993,20 +26920,17 @@ fn tupleField(
2799326920
27994 const field_ty = tuple_ty.fieldType(field_index, zcu);26921 const field_ty = tuple_ty.fieldType(field_index, zcu);
2799526922
27996 if (tuple_ty.structFieldIsComptime(field_index, zcu))
27997 try tuple_ty.resolveStructFieldInits(pt);
27998 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {26923 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
27999 return Air.internedToRef(default_value.toIntern()); // comptime field26924 return Air.internedToRef(default_value.toIntern()); // comptime field
28000 }26925 }
2800126926
28002 if (try sema.resolveValue(tuple)) |tuple_val| {26927 if (sema.resolveValue(tuple)) |tuple_val| {
28003 if (tuple_val.isUndef(zcu)) return pt.undefRef(field_ty);26928 if (tuple_val.isUndef(zcu)) return pt.undefRef(field_ty);
28004 return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern());26929 return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern());
28005 }26930 }
2800626931
28007 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);26932 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
2800826933
28009 try field_ty.resolveLayout(pt);
28010 return block.addStructFieldVal(tuple, field_index, field_ty);26934 return block.addStructFieldVal(tuple, field_index, field_ty);
28011}26935}
2801226936
...@@ -28032,12 +26956,12 @@ fn elemValArray(...@@ -28032,12 +26956,12 @@ fn elemValArray(
28032 return sema.fail(block, array_src, "indexing into empty array is not allowed", .{});26956 return sema.fail(block, array_src, "indexing into empty array is not allowed", .{});
28033 }26957 }
2803426958
28035 const maybe_undef_array_val = try sema.resolveValue(array);26959 const maybe_undef_array_val = sema.resolveValue(array);
28036 // index must be defined since it can access out of bounds26960 // index must be defined since it can access out of bounds
28037 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);26961 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2803826962
28039 if (maybe_index_val) |index_val| {26963 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));
28041 if (array_sent) |s| {26965 if (array_sent) |s| {
28042 if (index == array_len) {26966 if (index == array_len) {
28043 return Air.internedToRef(s.toIntern());26967 return Air.internedToRef(s.toIntern());
...@@ -28053,10 +26977,11 @@ fn elemValArray(...@@ -28053,10 +26977,11 @@ fn elemValArray(
28053 return pt.undefRef(elem_ty);26977 return pt.undefRef(elem_ty);
28054 }26978 }
28055 if (maybe_index_val) |index_val| {26979 if (maybe_index_val) |index_val| {
28056 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));26980 const index: usize = @intCast(index_val.toUnsignedInt(zcu));
28057 const elem_val = try array_val.elemValue(pt, index);26981 return .fromValue(try array_val.elemValue(pt, index));
28058 return Air.internedToRef(elem_val.toIntern());
28059 }26982 }
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);
28060 }26985 }
2806126986
28062 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src);26987 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src);
...@@ -28071,12 +26996,105 @@ fn elemValArray(...@@ -28071,12 +26996,105 @@ fn elemValArray(
28071 }26996 }
28072 }26997 }
2807326998
28074 if (try sema.typeHasOnePossibleValue(elem_ty)) |elem_val|
28075 return Air.internedToRef(elem_val.toIntern());
28076
28077 return block.addBinOp(.array_elem_val, array, elem_index);26999 return block.addBinOp(.array_elem_val, array, elem_index);
28078}27000}
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.
28080fn elemPtrArray(27098fn elemPtrArray(
28081 sema: *Sema,27099 sema: *Sema,
28082 block: *Block,27100 block: *Block,
...@@ -28091,19 +27109,21 @@ fn elemPtrArray(...@@ -28091,19 +27109,21 @@ fn elemPtrArray(
28091 const pt = sema.pt;27109 const pt = sema.pt;
28092 const zcu = pt.zcu;27110 const zcu = pt.zcu;
28093 const array_ptr_ty = sema.typeOf(array_ptr);27111 const array_ptr_ty = sema.typeOf(array_ptr);
27112 assert(array_ptr_ty.ptrSize(zcu) == .one);
28094 const array_ty = array_ptr_ty.childType(zcu);27113 const array_ty = array_ptr_ty.childType(zcu);
27114 assert(array_ty.zigTypeTag(zcu) == .array);
28095 const array_sent = array_ty.sentinel(zcu) != null;27115 const array_sent = array_ty.sentinel(zcu) != null;
28096 const array_len = array_ty.arrayLen(zcu);27116 const array_len = array_ty.arrayLen(zcu);
28097 const array_len_s = array_len + @intFromBool(array_sent);27117 const array_len_s = array_len + @intFromBool(array_sent);
2809827118
28099 if (array_len_s == 0) {27119 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", .{});
28101 }27121 }
2810227122
28103 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);27123 const maybe_undef_array_ptr_val = sema.resolveValue(array_ptr);
28104 // The index must not be undefined since it can be out of bounds.27124 // 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: {27125 const maybe_index: ?u64 = 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));27126 const index = index_val.toUnsignedInt(zcu);
28107 if (index >= array_len_s) {27127 if (index >= array_len_s) {
28108 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";27128 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
28109 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });27129 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(...@@ -28111,37 +27131,39 @@ fn elemPtrArray(
28111 break :o index;27131 break :o index;
28112 } else null;27132 } else null;
2811327133
28114 if (offset == null and array_ty.zigTypeTag(zcu) == .vector) {27134 array_ty.assertHasLayout(zcu);
28115 return sema.fail(block, elem_index_src, "vector index not comptime known", .{});27135 const elem_ptr_ty = try array_ptr_ty.elemPtrType(maybe_index, pt);
28116 }
28117
28118 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, pt);
2811927136
28120 if (maybe_undef_array_ptr_val) |array_ptr_val| {27137 if (maybe_undef_array_ptr_val) |array_ptr_val| {
28121 if (array_ptr_val.isUndef(zcu)) {27138 if (array_ptr_val.isUndef(zcu)) {
28122 return pt.undefRef(elem_ptr_ty);27139 return pt.undefRef(elem_ptr_ty);
28123 }27140 }
28124 if (offset) |index| {27141 if (maybe_index) |index| {
28125 const elem_ptr = try array_ptr_val.ptrElem(index, pt);27142 return .fromValue(try array_ptr_val.ptrElem(index, pt));
28126 return Air.internedToRef(elem_ptr.toIntern());
28127 }27143 }
28128 }27144 }
2812927145
28130 if (!init) {27146 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);
28132 try sema.validateRuntimeValue(block, array_ptr_src, array_ptr);27148 try sema.validateRuntimeValue(block, array_ptr_src, array_ptr);
28133 }27149 }
2813427150
28135 // Runtime check is only needed if unable to comptime check.27151 // 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) {
28137 const len_inst = try pt.intRef(.usize, array_len);27153 const len_inst = try pt.intRef(.usize, array_len);
28138 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;27154 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;
28139 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);27155 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
28140 }27156 }
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
28142 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);27163 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);
28143}27164}
2814427165
27166/// Asserts that the layout of the slice element type is already resolved.
28145fn elemValSlice(27167fn elemValSlice(
28146 sema: *Sema,27168 sema: *Sema,
28147 block: *Block,27169 block: *Block,
...@@ -28155,9 +27177,11 @@ fn elemValSlice(...@@ -28155,9 +27177,11 @@ fn elemValSlice(
28155 const pt = sema.pt;27177 const pt = sema.pt;
28156 const zcu = pt.zcu;27178 const zcu = pt.zcu;
28157 const slice_ty = sema.typeOf(slice);27179 const slice_ty = sema.typeOf(slice);
27180 assert(slice_ty.isSlice(zcu));
28158 const slice_sent = slice_ty.sentinel(zcu) != null;27181 const slice_sent = slice_ty.sentinel(zcu) != null;
28159 const elem_ty = slice_ty.elemType2(zcu);27182 const elem_ty = slice_ty.childType(zcu);
28160 var runtime_src = slice_src;27183
27184 elem_ty.assertHasLayout(zcu);
2816127185
28162 // slice must be defined since it can dereferenced as null27186 // slice must be defined since it can dereferenced as null
28163 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);27187 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
...@@ -28165,37 +27189,30 @@ fn elemValSlice(...@@ -28165,37 +27189,30 @@ fn elemValSlice(
28165 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);27189 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2816627190
28167 if (maybe_slice_val) |slice_val| {27191 if (maybe_slice_val) |slice_val| {
28168 runtime_src = elem_index_src;27192 const slice_len = slice_val.sliceLen(zcu);
28169 const slice_len = try slice_val.sliceLen(pt);
28170 const slice_len_s = slice_len + @intFromBool(slice_sent);27193 const slice_len_s = slice_len + @intFromBool(slice_sent);
28171 if (slice_len_s == 0) {27194 if (slice_len_s == 0) {
28172 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});27195 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
28173 }27196 }
28174 if (maybe_index_val) |index_val| {27197 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));
28176 if (index >= slice_len_s) {27199 if (index >= slice_len_s) {
28177 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";27200 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28178 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });27201 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28179 }27202 }
28180 const elem_ptr_ty = try slice_ty.elemPtrType(index, pt);
28181 const elem_ptr_val = try slice_val.ptrElem(index, pt);27203 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| {27204 return sema.analyzeLoad(block, src, .fromValue(elem_ptr_val), slice_src);
28183 return Air.internedToRef(elem_val.toIntern());
28184 }
28185 runtime_src = slice_src;
28186 }27205 }
28187 }27206 }
2818827207
28189 if (try sema.typeHasOnePossibleValue(elem_ty)) |elem_only_value| {27208 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
28190 return Air.internedToRef(elem_only_value.toIntern());
28191 }
2819227209
28193 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src);27210 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src);
28194 try sema.validateRuntimeValue(block, slice_src, slice);27211 try sema.validateRuntimeValue(block, slice_src, slice);
2819527212
28196 if (oob_safety and block.wantSafety()) {27213 if (oob_safety and block.wantSafety()) {
28197 const len_inst = if (maybe_slice_val) |slice_val|27214 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))
28199 else27216 else
28200 try block.addTyOp(.slice_len, .usize, slice);27217 try block.addTyOp(.slice_len, .usize, slice);
28201 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;27218 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -28204,6 +27221,7 @@ fn elemValSlice(...@@ -28204,6 +27221,7 @@ fn elemValSlice(
28204 return block.addBinOp(.slice_elem_val, slice, elem_index);27221 return block.addBinOp(.slice_elem_val, slice, elem_index);
28205}27222}
2820627223
27224/// Asserts that the layout of the slice element type is already resolved.
28207fn elemPtrSlice(27225fn elemPtrSlice(
28208 sema: *Sema,27226 sema: *Sema,
28209 block: *Block,27227 block: *Block,
...@@ -28217,33 +27235,35 @@ fn elemPtrSlice(...@@ -28217,33 +27235,35 @@ fn elemPtrSlice(
28217 const pt = sema.pt;27235 const pt = sema.pt;
28218 const zcu = pt.zcu;27236 const zcu = pt.zcu;
28219 const slice_ty = sema.typeOf(slice);27237 const slice_ty = sema.typeOf(slice);
27238 assert(slice_ty.isSlice(zcu));
28220 const slice_sent = slice_ty.sentinel(zcu) != null;27239 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);
28223 // The index must not be undefined since it can be out of bounds.27244 // 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: {27245 const offset: ?u64 = 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));27246 break :o index_val.toUnsignedInt(zcu);
28226 break :o index;
28227 } else null;27247 } else null;
2822827248
28229 const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt);27249 const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt);
27250 assert(elem_ptr_ty.childType(zcu).toIntern() == elem_ty.toIntern());
2823027251
28231 if (maybe_undef_slice_val) |slice_val| {27252 if (maybe_undef_slice_val) |slice_val| {
28232 if (slice_val.isUndef(zcu)) {27253 if (slice_val.isUndef(zcu)) {
28233 return pt.undefRef(elem_ptr_ty);27254 return pt.undefRef(elem_ptr_ty);
28234 }27255 }
28235 const slice_len = try slice_val.sliceLen(pt);27256 const slice_len = slice_val.sliceLen(zcu);
28236 const slice_len_s = slice_len + @intFromBool(slice_sent);27257 const slice_len_s = slice_len + @intFromBool(slice_sent);
28237 if (slice_len_s == 0) {27258 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", .{});
28239 }27260 }
28240 if (offset) |index| {27261 if (offset) |index| {
28241 if (index >= slice_len_s) {27262 if (index >= slice_len_s) {
28242 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";27263 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28243 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });27264 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28244 }27265 }
28245 const elem_ptr_val = try slice_val.ptrElem(index, pt);27266 return .fromValue(try slice_val.ptrElem(index, pt));
28246 return Air.internedToRef(elem_ptr_val.toIntern());
28247 }27267 }
28248 }27268 }
2824927269
...@@ -28254,13 +27274,13 @@ fn elemPtrSlice(...@@ -28254,13 +27274,13 @@ fn elemPtrSlice(
28254 const len_inst = len: {27274 const len_inst = len: {
28255 if (maybe_undef_slice_val) |slice_val|27275 if (maybe_undef_slice_val) |slice_val|
28256 if (!slice_val.isUndef(zcu))27276 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));
28258 break :len try block.addTyOp(.slice_len, .usize, slice);27278 break :len try block.addTyOp(.slice_len, .usize, slice);
28259 };27279 };
28260 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;27280 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
28261 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);27281 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
28262 }27282 }
28263 if (!try slice_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) {27283 if (elem_ty.abiSize(zcu) == 0) {
28264 // zero-bit child type; just extract the pointer and bitcast it27284 // zero-bit child type; just extract the pointer and bitcast it
28265 const slice_ptr = try block.addTyOp(.slice_ptr, slice_ty.slicePtrFieldType(zcu), slice);27285 const slice_ptr = try block.addTyOp(.slice_ptr, slice_ty.slicePtrFieldType(zcu), slice);
28266 return block.addBitCast(elem_ptr_ty, slice_ptr);27286 return block.addBitCast(elem_ptr_ty, slice_ptr);
...@@ -28331,15 +27351,17 @@ fn coerceExtra(...@@ -28331,15 +27351,17 @@ fn coerceExtra(
28331 if (dest_ty.isGenericPoison()) return inst;27351 if (dest_ty.isGenericPoison()) return inst;
2833227352
28333 const dest_ty_src = inst_src; // TODO better source location27353 const dest_ty_src = inst_src; // TODO better source location
28334 try dest_ty.resolveFields(pt);
28335 const inst_ty = sema.typeOf(inst);27354 const inst_ty = sema.typeOf(inst);
28336 try inst_ty.resolveFields(pt);
28337 const target = zcu.getTarget();27355 const target = zcu.getTarget();
27356
27357 inst_ty.assertHasLayout(zcu);
27358 try sema.ensureLayoutResolved(dest_ty, inst_src, .coerce);
27359
28338 // If the types are the same, we can return the operand.27360 // If the types are the same, we can return the operand.
28339 if (dest_ty.eql(inst_ty, zcu))27361 if (dest_ty.eql(inst_ty, zcu))
28340 return inst;27362 return inst;
2834127363
28342 const maybe_inst_val = try sema.resolveValue(inst);27364 const maybe_inst_val = sema.resolveValue(inst);
2834327365
28344 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);27366 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
28345 if (in_memory_result == .ok) {27367 if (in_memory_result == .ok) {
...@@ -28357,7 +27379,7 @@ fn coerceExtra(...@@ -28357,7 +27379,7 @@ fn coerceExtra(
28357 if (maybe_inst_val) |val| {27379 if (maybe_inst_val) |val| {
28358 // undefined sets the optional bit also to undefined.27380 // undefined sets the optional bit also to undefined.
28359 if (val.toIntern() == .undef) {27381 if (val.toIntern() == .undef) {
28360 return pt.undefRef(dest_ty);27382 return .fromValue(try dest_ty.onePossibleValue(pt) orelse try pt.undefValue(dest_ty));
28361 }27383 }
2836227384
28363 // null to ?T27385 // null to ?T
...@@ -28372,11 +27394,11 @@ fn coerceExtra(...@@ -28372,11 +27394,11 @@ fn coerceExtra(
28372 // cast from ?*T and ?[*]T to ?*anyopaque27394 // cast from ?*T and ?[*]T to ?*anyopaque
28373 // but don't do it if the source type is a double pointer27395 // but don't do it if the source type is a double pointer
28374 if (dest_ty.isPtrLikeOptional(zcu) and27396 if (dest_ty.isPtrLikeOptional(zcu) and
28375 dest_ty.elemType2(zcu).toIntern() == .anyopaque_type and27397 dest_ty.nullablePtrElem(zcu).toIntern() == .anyopaque_type and
28376 inst_ty.isPtrAtRuntime(zcu))27398 inst_ty.isPtrAtRuntime(zcu))
28377 anyopaque_check: {27399 anyopaque_check: {
28378 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;27400 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);
28380 if (elem_ty.zigTypeTag(zcu) == .pointer or elem_ty.isPtrLikeOptional(zcu)) {27402 if (elem_ty.zigTypeTag(zcu) == .pointer or elem_ty.isPtrLikeOptional(zcu)) {
28381 in_memory_result = .{ .double_ptr_to_anyopaque = .{27403 in_memory_result = .{ .double_ptr_to_anyopaque = .{
28382 .actual = inst_ty,27404 .actual = inst_ty,
...@@ -28409,7 +27431,7 @@ fn coerceExtra(...@@ -28409,7 +27431,7 @@ fn coerceExtra(
2840927431
28410 // Function body to function pointer.27432 // Function body to function pointer.
28411 if (inst_ty.zigTypeTag(zcu) == .@"fn") {27433 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).?;
28413 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {27435 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
28414 .func => |f| f.owner_nav,27436 .func => |f| f.owner_nav,
28415 .@"extern" => |e| e.owner_nav,27437 .@"extern" => |e| e.owner_nav,
...@@ -28430,7 +27452,7 @@ fn coerceExtra(...@@ -28430,7 +27452,7 @@ fn coerceExtra(
28430 const array_elem_ty = array_ty.childType(zcu);27452 const array_elem_ty = array_ty.childType(zcu);
28431 if (array_ty.arrayLen(zcu) != 1) break :single_item;27453 if (array_ty.arrayLen(zcu) != 1) break :single_item;
28432 const dest_is_mut = !dest_info.flags.is_const;27454 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)) {
28434 .ok => {},27456 .ok => {},
28435 else => break :single_item,27457 else => break :single_item,
28436 }27458 }
...@@ -28448,7 +27470,7 @@ fn coerceExtra(...@@ -28448,7 +27470,7 @@ fn coerceExtra(
28448 const dest_is_mut = !dest_info.flags.is_const;27470 const dest_is_mut = !dest_info.flags.is_const;
2844927471
28450 const dst_elem_type: Type = .fromInterned(dest_info.child);27472 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);
28452 switch (elem_res) {27474 switch (elem_res) {
28453 .ok => {},27475 .ok => {},
28454 else => {27476 else => {
...@@ -28509,7 +27531,7 @@ fn coerceExtra(...@@ -28509,7 +27531,7 @@ fn coerceExtra(
28509 const src_elem_ty = inst_ty.childType(zcu);27531 const src_elem_ty = inst_ty.childType(zcu);
28510 const dest_is_mut = !dest_info.flags.is_const;27532 const dest_is_mut = !dest_info.flags.is_const;
28511 const dst_elem_type: Type = .fromInterned(dest_info.child);27533 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)) {
28513 .ok => {},27535 .ok => {},
28514 else => break :src_c_ptr,27536 else => break :src_c_ptr,
28515 }27537 }
...@@ -28520,7 +27542,7 @@ fn coerceExtra(...@@ -28520,7 +27542,7 @@ fn coerceExtra(
28520 // but don't do it if the source type is a double pointer27542 // but don't do it if the source type is a double pointer
28521 if (dest_info.child == .anyopaque_type and inst_ty.zigTypeTag(zcu) == .pointer) to_anyopaque: {27543 if (dest_info.child == .anyopaque_type and inst_ty.zigTypeTag(zcu) == .pointer) to_anyopaque: {
28522 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;27544 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);
28524 if (elem_ty.zigTypeTag(zcu) == .pointer or elem_ty.isPtrLikeOptional(zcu)) {27546 if (elem_ty.zigTypeTag(zcu) == .pointer or elem_ty.isPtrLikeOptional(zcu)) {
28525 in_memory_result = .{ .double_ptr_to_anyopaque = .{27547 in_memory_result = .{ .double_ptr_to_anyopaque = .{
28526 .actual = inst_ty,27548 .actual = inst_ty,
...@@ -28580,7 +27602,7 @@ fn coerceExtra(...@@ -28580,7 +27602,7 @@ fn coerceExtra(
28580 target,27602 target,
28581 dest_ty_src,27603 dest_ty_src,
28582 inst_src,27604 inst_src,
28583 maybe_inst_val,27605 null,
28584 )) {27606 )) {
28585 .ok => {},27607 .ok => {},
28586 else => break :p,27608 else => break :p,
...@@ -28616,16 +27638,14 @@ fn coerceExtra(...@@ -28616,16 +27638,14 @@ fn coerceExtra(
28616 // empty tuple to zero-length slice27638 // empty tuple to zero-length slice
28617 // note that this allows coercing to a mutable slice.27639 // note that this allows coercing to a mutable slice.
28618 if (inst_child_ty.structFieldCount(zcu) == 0) {27640 if (inst_child_ty.structFieldCount(zcu) == 0) {
28619 const align_val = try dest_ty.ptrAlignmentSema(pt);27641 const empty_array_ty = try pt.arrayType(.{
28620 return Air.internedToRef(try pt.intern(.{ .slice = .{27642 .len = 0,
28621 .ty = dest_ty.toIntern(),27643 .child = dest_info.child,
28622 .ptr = try pt.intern(.{ .ptr = .{27644 .sentinel = dest_info.sentinel,
28623 .ty = dest_ty.slicePtrFieldType(zcu).toIntern(),27645 });
28624 .base_addr = .int,27646 const empty_array_val = try pt.aggregateValue(empty_array_ty, &.{});
28625 .byte_offset = align_val.toByteUnits().?,27647 const empty_array_ptr = try sema.uavRef(empty_array_val);
28626 } }),27648 return sema.coerceArrayPtrToSlice(block, dest_ty, empty_array_ptr, inst_src);
28627 .len = .zero_usize,
28628 } }));
28629 }27649 }
2863027650
28631 // pointer to tuple to slice27651 // pointer to tuple to slice
...@@ -28653,7 +27673,7 @@ fn coerceExtra(...@@ -28653,7 +27673,7 @@ fn coerceExtra(
28653 target,27673 target,
28654 dest_ty_src,27674 dest_ty_src,
28655 inst_src,27675 inst_src,
28656 maybe_inst_val,27676 null,
28657 )) {27677 )) {
28658 .ok => {},27678 .ok => {},
28659 else => break :p,27679 else => break :p,
...@@ -28684,12 +27704,12 @@ fn coerceExtra(...@@ -28684,12 +27704,12 @@ fn coerceExtra(
28684 .int, .comptime_int => {27704 .int, .comptime_int => {
28685 if (maybe_inst_val) |val| {27705 if (maybe_inst_val) |val| {
28686 // comptime-known integer to other number27706 // comptime-known integer to other number
28687 if (!(try sema.intFitsInType(val, dest_ty, null))) {27707 if (!val.intFitsInType(dest_ty, null, zcu)) {
28688 if (!opts.report_err) return error.NotCoercible;27708 if (!opts.report_err) return error.NotCoercible;
28689 return sema.fail(block, inst_src, "type '{f}' cannot represent integer value '{f}'", .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) });27709 return sema.fail(block, inst_src, "type '{f}' cannot represent integer value '{f}'", .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) });
28690 }27710 }
28691 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {27711 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)),
28693 .int => |int| Air.internedToRef(27713 .int => |int| Air.internedToRef(
28694 try zcu.intern_pool.getCoercedInts(gpa, io, pt.tid, int, dest_ty.toIntern()),27714 try zcu.intern_pool.getCoercedInts(gpa, io, pt.tid, int, dest_ty.toIntern()),
28695 ),27715 ),
...@@ -28717,7 +27737,7 @@ fn coerceExtra(...@@ -28717,7 +27737,7 @@ fn coerceExtra(
28717 },27737 },
28718 .float, .comptime_float => switch (inst_ty.zigTypeTag(zcu)) {27738 .float, .comptime_float => switch (inst_ty.zigTypeTag(zcu)) {
28719 .comptime_float => {27739 .comptime_float => {
28720 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);27740 const val = sema.resolveValue(inst).?;
28721 const result_val = try val.floatCast(dest_ty, pt);27741 const result_val = try val.floatCast(dest_ty, pt);
28722 return Air.internedToRef(result_val.toIntern());27742 return Air.internedToRef(result_val.toIntern());
28723 },27743 },
...@@ -28768,28 +27788,26 @@ fn coerceExtra(...@@ -28768,28 +27788,26 @@ fn coerceExtra(
28768 }27788 }
28769 break :int;27789 break :int;
28770 };27790 };
28771 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, pt, .sema);27791 if (val.isUndef(zcu)) {
28772 const fits: bool = switch (ip.indexToKey(result_val.toIntern())) {27792 return .fromValue(try pt.undefValue(dest_ty));
28773 else => unreachable,27793 }
28774 .undef => true,27794 const result_val = try pt.floatValue(dest_ty, val.toFloat(f128, zcu));
28775 .float => |float| fits: {27795 const float = ip.indexToKey(result_val.toIntern()).float;
28776 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;27796 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
28777 const operand_big_int = val.toBigInt(&buffer, zcu);27797 const operand_big_int = val.toBigInt(&buffer, zcu);
28778 switch (float.storage) {27798 const fits = switch (float.storage) {
28779 inline else => |x| {27799 inline else => |x| fits: {
28780 if (!std.math.isFinite(x)) break :fits false;27800 if (!std.math.isFinite(x)) break :fits false;
28781 var result_big_int: std.math.big.int.Mutable = .{27801 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)),27802 .limbs = try sema.arena.alloc(std.math.big.Limb, std.math.big.int.calcLimbLen(x)),
28783 .len = undefined,27803 .len = undefined,
28784 .positive = undefined,27804 .positive = undefined,
28785 };27805 };
28786 switch (result_big_int.setFloat(x, .nearest_even)) {27806 switch (result_big_int.setFloat(x, .nearest_even)) {
28787 .inexact => break :fits false,27807 .inexact => break :fits false,
28788 .exact => {},27808 .exact => {},
28789 }
28790 break :fits result_big_int.toConst().eql(operand_big_int);
28791 },
28792 }27809 }
27810 break :fits result_big_int.toConst().eql(operand_big_int);
28793 },27811 },
28794 };27812 };
28795 if (!fits) return sema.fail(27813 if (!fits) return sema.fail(
...@@ -28805,7 +27823,7 @@ fn coerceExtra(...@@ -28805,7 +27823,7 @@ fn coerceExtra(
28805 .@"enum" => switch (inst_ty.zigTypeTag(zcu)) {27823 .@"enum" => switch (inst_ty.zigTypeTag(zcu)) {
28806 .enum_literal => {27824 .enum_literal => {
28807 // enum literal to enum27825 // enum literal to enum
28808 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);27826 const val = sema.resolveValue(inst).?;
28809 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;27827 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
28810 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {27828 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
28811 return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{27829 return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{
...@@ -28814,33 +27832,36 @@ fn coerceExtra(...@@ -28814,33 +27832,36 @@ fn coerceExtra(
28814 };27832 };
28815 return Air.internedToRef((try pt.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());27833 return Air.internedToRef((try pt.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());
28816 },27834 },
28817 .@"union" => blk: {27835 .@"union" => if (inst_ty.unionTagType(zcu)) |enum_tag_ty| {
28818 // union to its own tag type27836 // union to its own tag type
28819 const union_tag_ty = inst_ty.unionTagType(zcu) orelse break :blk;27837 if (enum_tag_ty.toIntern() == dest_ty.toIntern()) {
28820 if (union_tag_ty.eql(dest_ty, zcu)) {27838 return sema.unionToTag(block, inst);
28821 return sema.unionToTag(block, dest_ty, inst, inst_src);
28822 }27839 }
28823 },27840 },
28824 else => {},27841 else => {},
28825 },27842 },
28826 .error_union => switch (inst_ty.zigTypeTag(zcu)) {27843 .error_union => switch (inst_ty.zigTypeTag(zcu)) {
28827 .error_set => {27844 // E to E!T
28828 // E to E!T27845 .error_set => if (sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src)) |res| {
28829 return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src);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,
28830 },27854 },
28831 else => eu: {27855 // T to E!T
28832 // T to E!T27856 else => if (sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src)) |res| {
28833 return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) {27857 return res;
28834 error.NotCoercible => {27858 } else |err| switch (err) {
28835 if (in_memory_result == .no_match) {27859 error.NotCoercible => if (in_memory_result == .no_match) {
28836 const payload_type = dest_ty.errorUnionPayload(zcu);27860 // Try to give more useful notes
28837 // Try to give more useful notes27861 const payload_type = dest_ty.errorUnionPayload(zcu);
28838 in_memory_result = try sema.coerceInMemoryAllowed(block, payload_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);27862 in_memory_result = try sema.coerceInMemoryAllowed(block, payload_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
28839 }27863 },
28840 break :eu;27864 else => |e| return e,
28841 },
28842 else => |e| return e,
28843 };
28844 },27865 },
28845 },27866 },
28846 .@"union" => switch (inst_ty.zigTypeTag(zcu)) {27867 .@"union" => switch (inst_ty.zigTypeTag(zcu)) {
...@@ -28858,7 +27879,7 @@ fn coerceExtra(...@@ -28858,7 +27879,7 @@ fn coerceExtra(
28858 target,27879 target,
28859 dest_ty_src,27880 dest_ty_src,
28860 inst_src,27881 inst_src,
28861 maybe_inst_val,27882 null,
28862 )) {27883 )) {
28863 break :array_to_array;27884 break :array_to_array;
28864 }27885 }
...@@ -28900,18 +27921,16 @@ fn coerceExtra(...@@ -28900,18 +27921,16 @@ fn coerceExtra(
28900 else => {},27921 else => {},
28901 }27922 }
2890227923
28903 const can_coerce_to = switch (dest_ty.zigTypeTag(zcu)) {27924 const dest_is_npv = switch (dest_ty.classify(zcu)) {
28904 .noreturn, .@"opaque" => false,27925 .no_possible_value => true,
28905 else => 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,
28906 };27932 };
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
28915 if (!opts.report_err) return error.NotCoercible;27934 if (!opts.report_err) return error.NotCoercible;
2891627935
28917 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {27936 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {
...@@ -28933,13 +27952,13 @@ fn coerceExtra(...@@ -28933,13 +27952,13 @@ fn coerceExtra(
28933 const msg = try sema.typeMismatchErrMsg(inst_src, dest_ty, inst_ty);27952 const msg = try sema.typeMismatchErrMsg(inst_src, dest_ty, inst_ty);
28934 errdefer msg.destroy(sema.gpa);27953 errdefer msg.destroy(sema.gpa);
2893527954
28936 if (!can_coerce_to) {27955 if (dest_is_npv) {
28937 try sema.errNote(inst_src, msg, "cannot coerce to '{f}'", .{dest_ty.fmt(pt)});27956 try sema.errNote(inst_src, msg, "cannot coerce to uninstantiable type '{f}'", .{dest_ty.fmt(pt)});
28938 }27957 }
2893927958
28940 // E!T to T27959 // E!T to T
28941 if (inst_ty.zigTypeTag(zcu) == .error_union and27960 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)
28943 {27962 {
28944 try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});27963 try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});
28945 try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});27964 try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
...@@ -28947,7 +27966,7 @@ fn coerceExtra(...@@ -28947,7 +27966,7 @@ fn coerceExtra(
2894727966
28948 // ?T to T27967 // ?T to T
28949 if (inst_ty.zigTypeTag(zcu) == .optional and27968 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)
28951 {27970 {
28952 try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});27971 try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});
28953 try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});27972 try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
...@@ -29394,6 +28413,10 @@ pub fn coerceInMemoryAllowed(...@@ -29394,6 +28413,10 @@ pub fn coerceInMemoryAllowed(
29394 const pt = sema.pt;28413 const pt = sema.pt;
29395 const zcu = pt.zcu;28414 const zcu = pt.zcu;
2939628415
28416 if (src_val) |val| {
28417 assert(val.typeOf(zcu).toIntern() == src_ty.toIntern());
28418 }
28419
29397 if (dest_ty.eql(src_ty, zcu))28420 if (dest_ty.eql(src_ty, zcu))
29398 return .ok;28421 return .ok;
2939928422
...@@ -29428,7 +28451,7 @@ pub fn coerceInMemoryAllowed(...@@ -29428,7 +28451,7 @@ pub fn coerceInMemoryAllowed(
29428 // Comptime int to regular int.28451 // Comptime int to regular int.
29429 if (dest_tag == .int and src_tag == .comptime_int) {28452 if (dest_tag == .int and src_tag == .comptime_int) {
29430 if (src_val) |val| {28453 if (src_val) |val| {
29431 if (!(try sema.intFitsInType(val, dest_ty, null))) {28454 if (!val.intFitsInType(dest_ty, null, zcu)) {
29432 return .{ .comptime_int_not_coercible = .{ .wanted = dest_ty, .actual = val } };28455 return .{ .comptime_int_not_coercible = .{ .wanted = dest_ty, .actual = val } };
29433 }28456 }
29434 }28457 }
...@@ -29444,17 +28467,13 @@ pub fn coerceInMemoryAllowed(...@@ -29444,17 +28467,13 @@ pub fn coerceInMemoryAllowed(
29444 }28467 }
2944528468
29446 // Pointers / Pointer-like Optionals28469 // Pointers / Pointer-like Optionals
29447 const maybe_dest_ptr_ty = try sema.typePtrOrOptionalPtrTy(dest_ty);28470 if (dest_ty.isPtrAtRuntime(zcu) and src_ty.isPtrAtRuntime(zcu)) {
29448 const maybe_src_ptr_ty = try sema.typePtrOrOptionalPtrTy(src_ty);28471 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
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 }
29453 }28472 }
2945428473
29455 // Slices28474 // Slices
29456 if (dest_ty.isSlice(zcu) and src_ty.isSlice(zcu)) {28475 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);
29458 }28477 }
2945928478
29460 // Functions28479 // Functions
...@@ -29554,7 +28573,8 @@ pub fn coerceInMemoryAllowed(...@@ -29554,7 +28573,8 @@ pub fn coerceInMemoryAllowed(
2955428573
29555 // Optionals28574 // Optionals
29556 if (dest_tag == .optional and src_tag == .optional) {28575 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.
29558 return .{ .optional_shape = .{28578 return .{ .optional_shape = .{
29559 .actual = src_ty,28579 .actual = src_ty,
29560 .wanted = dest_ty,28580 .wanted = dest_ty,
...@@ -29581,7 +28601,6 @@ pub fn coerceInMemoryAllowed(...@@ -29581,7 +28601,6 @@ pub fn coerceInMemoryAllowed(
29581 const field_count = dest_ty.structFieldCount(zcu);28601 const field_count = dest_ty.structFieldCount(zcu);
29582 for (0..field_count) |field_idx| {28602 for (0..field_count) |field_idx| {
29583 if (dest_ty.structFieldIsComptime(field_idx, zcu) != src_ty.structFieldIsComptime(field_idx, zcu)) break :tuple;28603 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;
29585 const dest_field_ty = dest_ty.fieldType(field_idx, zcu);28604 const dest_field_ty = dest_ty.fieldType(field_idx, zcu);
29586 const src_field_ty = src_ty.fieldType(field_idx, zcu);28605 const src_field_ty = src_ty.fieldType(field_idx, zcu);
29587 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null);28606 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(...@@ -29609,89 +28628,62 @@ fn coerceInMemoryAllowedErrorSets(
29609 const gpa = sema.gpa;28628 const gpa = sema.gpa;
29610 const ip = &zcu.intern_pool;28629 const ip = &zcu.intern_pool;
2961128630
29612 // Coercion to `anyerror`. Note that this check can return false negatives28631 const dest_set: InternPool.Key.ErrorSetType = err_set: switch (dest_ty.toIntern()) {
29613 // in case the error sets did not get resolved.28632 .anyerror_type => return .ok,
29614 if (dest_ty.isAnyError(zcu)) {28633 .adhoc_inferred_error_set_type => {
29615 return .ok;28634 // We are trying to coerce an error set to the current function's
29616 }28635 // inferred error set.
2961728636 const dst_ies = sema.fn_ret_ty_ies.?;
29618 if (dest_ty.toIntern() == .adhoc_inferred_error_set_type) {28637 try dst_ies.addErrorSet(src_ty, ip, sema.arena);
29619 // We are trying to coerce an error set to the current function's28638 return .ok;
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,
29652 },28639 },
2965328640 else => |err_set_ty| switch (ip.indexToKey(err_set_ty)) {
29654 else => switch (ip.indexToKey(src_ty.toIntern())) {28641 .inferred_error_set_type => |func_index| {
29655 .inferred_error_set_type => {28642 if (sema.fn_ret_ty_ies) |dst_ies| {
29656 const resolved_src_ty = try sema.resolveInferredErrorSet(block, src_src, src_ty.toIntern());28643 if (dst_ies.func == func_index) {
29657 // src anyerror status might have changed after the resolution.28644 // We are trying to coerce an error set to the current function's
29658 if (resolved_src_ty == .anyerror_type) {28645 // inferred error set.
29659 // dest_ty.isAnyError(zcu) == true is already checked for at this point.28646 try dst_ies.addErrorSet(src_ty, ip, sema.arena);
29660 return .from_anyerror;28647 return .ok;
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);
29666 }28648 }
29667 }28649 }
2966828650 try sema.ensureFuncIesResolved(block, dest_src, func_index);
29669 if (missing_error_buf.items.len != 0) {28651 continue :err_set ip.funcIesResolvedUnordered(func_index);
29670 return InMemoryCoercionResult{
29671 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
29672 };
29673 }
29674
29675 return .ok;
29676 },28652 },
29677 .error_set_type => |error_set_type| {28653 .error_set_type => |err_set| err_set,
29678 for (error_set_type.names.get(ip)) |name| {28654 else => unreachable,
29679 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), name)) {28655 },
29680 try missing_error_buf.append(name);28656 };
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 }
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);
29691 },28664 },
28665 .error_set_type => |err_set| err_set.names,
29692 else => unreachable,28666 else => unreachable,
29693 },28667 },
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 ) };
29694 }28684 }
28685
28686 return .ok;
29695}28687}
2969628688
29697fn coerceInMemoryAllowedFns(28689fn coerceInMemoryAllowedFns(
...@@ -29714,11 +28706,7 @@ fn coerceInMemoryAllowedFns(...@@ -29714,11 +28706,7 @@ fn coerceInMemoryAllowedFns(
2971428706
29715 {28707 {
29716 if (dest_info.is_var_args != src_info.is_var_args) {28708 if (dest_info.is_var_args != src_info.is_var_args) {
29717 return InMemoryCoercionResult{ .fn_var_args = dest_info.is_var_args };28709 return .{ .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 };
29722 }28710 }
2972328711
29724 const callconv_ok = callconvCoerceAllowed(target, src_info.cc, dest_info.cc) and28712 const callconv_ok = callconvCoerceAllowed(target, src_info.cc, dest_info.cc) and
...@@ -29731,6 +28719,12 @@ fn coerceInMemoryAllowedFns(...@@ -29731,6 +28719,12 @@ fn coerceInMemoryAllowedFns(
29731 } };28719 } };
29732 }28720 }
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
29734 if (!switch (src_info.return_type) {28728 if (!switch (src_info.return_type) {
29735 .generic_poison_type => true,28729 .generic_poison_type => true,
29736 .noreturn_type => !dest_is_mut,28730 .noreturn_type => !dest_is_mut,
...@@ -29780,7 +28774,7 @@ fn coerceInMemoryAllowedFns(...@@ -29780,7 +28774,7 @@ fn coerceInMemoryAllowedFns(
29780 const src_is_comptime = src_info.paramIsComptime(@intCast(param_i));28774 const src_is_comptime = src_info.paramIsComptime(@intCast(param_i));
29781 const dest_is_comptime = dest_info.paramIsComptime(@intCast(param_i));28775 const dest_is_comptime = dest_info.paramIsComptime(@intCast(param_i));
29782 if (src_is_comptime == dest_is_comptime) break :comptime_param;28776 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)) {
29784 // A parameter which is marked `comptime` can drop that annotation if the type is comptime-only.28778 // A parameter which is marked `comptime` can drop that annotation if the type is comptime-only.
29785 // The function remains generic, and the parameter is going to be comptime-resolved either way,28779 // The function remains generic, and the parameter is going to be comptime-resolved either way,
29786 // so this just affects whether or not the argument is comptime-evaluated at the call site.28780 // so this just affects whether or not the argument is comptime-evaluated at the call site.
...@@ -29861,8 +28855,6 @@ fn coerceInMemoryAllowedPtrs(...@@ -29861,8 +28855,6 @@ fn coerceInMemoryAllowedPtrs(
29861 block: *Block,28855 block: *Block,
29862 dest_ty: Type,28856 dest_ty: Type,
29863 src_ty: Type,28857 src_ty: Type,
29864 dest_ptr_ty: Type,
29865 src_ptr_ty: Type,
29866 /// If set, the coercion must be valid in both directions.28858 /// If set, the coercion must be valid in both directions.
29867 dest_is_mut: bool,28859 dest_is_mut: bool,
29868 target: *const std.Target,28860 target: *const std.Target,
...@@ -29875,8 +28867,8 @@ fn coerceInMemoryAllowedPtrs(...@@ -29875,8 +28867,8 @@ fn coerceInMemoryAllowedPtrs(
29875 const gpa = comp.gpa;28867 const gpa = comp.gpa;
29876 const io = comp.io;28868 const io = comp.io;
2987728869
29878 const dest_info = dest_ptr_ty.ptrInfo(zcu);28870 const dest_info = dest_ty.ptrInfo(zcu);
29879 const src_info = src_ptr_ty.ptrInfo(zcu);28871 const src_info = src_ty.ptrInfo(zcu);
2988028872
29881 const ok_ptr_size = src_info.flags.size == dest_info.flags.size or28873 const ok_ptr_size = src_info.flags.size == dest_info.flags.size or
29882 src_info.flags.size == .c or dest_info.flags.size == .c;28874 src_info.flags.size == .c or dest_info.flags.size == .c;
...@@ -30008,16 +29000,14 @@ fn coerceInMemoryAllowedPtrs(...@@ -30008,16 +29000,14 @@ fn coerceInMemoryAllowedPtrs(
30008 if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or29000 if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or
30009 dest_info.child != src_info.child)29001 dest_info.child != src_info.child)
30010 {29002 {
30011 const src_align = if (src_info.flags.alignment != .none)29003 const src_align = if (src_info.flags.alignment == .none) a: {
30012 src_info.flags.alignment29004 try sema.ensureLayoutResolved(src_child, src_src, .align_check);
30013 else29005 break :a src_child.abiAlignment(zcu);
30014 try Type.fromInterned(src_info.child).abiAlignmentSema(pt);29006 } else src_info.flags.alignment;
3001529007 const dest_align = if (dest_info.flags.alignment == .none) a: {
30016 const dest_align = if (dest_info.flags.alignment != .none)29008 try sema.ensureLayoutResolved(dest_child, dest_src, .align_check);
30017 dest_info.flags.alignment29009 break :a dest_child.abiAlignment(zcu);
30018 else29010 } else dest_info.flags.alignment;
30019 try Type.fromInterned(dest_info.child).abiAlignmentSema(pt);
30020
30021 if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) {29011 if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) {
30022 return InMemoryCoercionResult{ .ptr_alignment = .{29012 return InMemoryCoercionResult{ .ptr_alignment = .{
30023 .actual = src_align,29013 .actual = src_align,
...@@ -30049,7 +29039,7 @@ fn coerceVarArgParam(...@@ -30049,7 +29039,7 @@ fn coerceVarArgParam(
30049 .{},29039 .{},
30050 ),29040 ),
30051 .@"fn" => fn_ptr: {29041 .@"fn" => fn_ptr: {
30052 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);29042 const fn_val = sema.resolveValue(inst).?;
30053 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;29043 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
30054 break :fn_ptr try sema.analyzeNavRef(block, inst_src, fn_nav);29044 break :fn_ptr try sema.analyzeNavRef(block, inst_src, fn_nav);
30055 },29045 },
...@@ -30066,7 +29056,7 @@ fn coerceVarArgParam(...@@ -30066,7 +29056,7 @@ fn coerceVarArgParam(
30066 }29056 }
30067 },29057 },
30068 else => if (uncasted_ty.isAbiInt(zcu)) int: {29058 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;
30070 const target = zcu.getTarget();29060 const target = zcu.getTarget();
30071 const uncasted_info = uncasted_ty.intInfo(zcu);29061 const uncasted_info = uncasted_ty.intInfo(zcu);
30072 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {29062 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
...@@ -30095,7 +29085,7 @@ fn coerceVarArgParam(...@@ -30095,7 +29085,7 @@ fn coerceVarArgParam(
30095 };29085 };
3009629086
30097 const coerced_ty = sema.typeOf(coerced);29087 const coerced_ty = sema.typeOf(coerced);
30098 if (!try sema.validateExternType(coerced_ty, .param_ty)) {29088 if (!coerced_ty.validateExtern(.param_ty, zcu)) {
30099 const msg = msg: {29089 const msg = msg: {
30100 const msg = try sema.errMsg(inst_src, "cannot pass '{f}' to variadic function", .{coerced_ty.fmt(pt)});29090 const msg = try sema.errMsg(inst_src, "cannot pass '{f}' to variadic function", .{coerced_ty.fmt(pt)});
30101 errdefer msg.destroy(sema.gpa);29091 errdefer msg.destroy(sema.gpa);
...@@ -30140,38 +29130,20 @@ fn storePtr2(...@@ -30140,38 +29130,20 @@ fn storePtr2(
3014029130
30141 const elem_ty = ptr_ty.childType(zcu);29131 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
30168 const is_ret = air_tag == .ret_ptr;29133 const is_ret = air_tag == .ret_ptr;
3016929134
30170 const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) {29135 const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) {
30171 error.NotCoercible => unreachable,29136 error.NotCoercible => unreachable,
30172 else => |e| return e,29137 else => |e| return e,
30173 };29138 };
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
30176 const runtime_src = rs: {29148 const runtime_src = rs: {
30177 const ptr_val = try sema.resolveDefinedValue(block, ptr_src, ptr) orelse break :rs ptr_src;29149 const ptr_val = try sema.resolveDefinedValue(block, ptr_src, ptr) orelse break :rs ptr_src;
...@@ -30180,22 +29152,13 @@ fn storePtr2(...@@ -30180,22 +29152,13 @@ fn storePtr2(
30180 return sema.storePtrVal(block, src, ptr_val, operand_val, elem_ty);29152 return sema.storePtrVal(block, src, ptr_val, operand_val, elem_ty);
30181 };29153 };
3018229154
30183 // We're performing the store at runtime; as such, we need to make sure the pointee type29155 // We're performing the store at runtime, so the pointee type must not be comptime-only.
30184 // is not comptime-only. We can hit this case with a `@ptrFromInt` pointer.29156 if (comptime_only) return sema.failWithOwnedErrorMsg(block, msg: {
30185 if (try elem_ty.comptimeOnlySema(pt)) {29157 const msg = try sema.errMsg(src, "cannot store comptime-only type '{f}' at runtime", .{elem_ty.fmt(pt)});
30186 return sema.failWithOwnedErrorMsg(block, msg: {29158 errdefer msg.destroy(sema.gpa);
30187 const msg = try sema.errMsg(src, "cannot store comptime-only type '{f}' at runtime", .{elem_ty.fmt(pt)});29159 try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{});
30188 errdefer msg.destroy(sema.gpa);29160 break :msg msg;
30189 try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{});29161 });
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 }
3019929162
30200 try sema.requireRuntimeBlock(block, src, runtime_src);29163 try sema.requireRuntimeBlock(block, src, runtime_src);
3020129164
...@@ -30223,7 +29186,7 @@ fn checkComptimeKnownStore(sema: *Sema, block: *Block, store_inst_ref: Air.Inst....@@ -30223,7 +29186,7 @@ fn checkComptimeKnownStore(sema: *Sema, block: *Block, store_inst_ref: Air.Inst.
30223 const maybe_base_alloc = sema.base_allocs.get(ptr) orelse break :known;29186 const maybe_base_alloc = sema.base_allocs.get(ptr) orelse break :known;
30224 const maybe_comptime_alloc = sema.maybe_comptime_allocs.getPtr(maybe_base_alloc) orelse break :known;29187 const maybe_comptime_alloc = sema.maybe_comptime_allocs.getPtr(maybe_base_alloc) orelse break :known;
3022529188
30226 if ((try sema.resolveValue(operand)) != null and29189 if (sema.resolveValue(operand) != null and
30227 block.runtime_index == maybe_comptime_alloc.runtime_index)29190 block.runtime_index == maybe_comptime_alloc.runtime_index)
30228 {29191 {
30229 try maybe_comptime_alloc.stores.append(sema.arena, .{29192 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...@@ -30272,7 +29235,7 @@ fn checkKnownAllocPtr(sema: *Sema, block: *Block, base_ptr: Air.Inst.Ref, new_pt
3027229235
30273 // If the index value is runtime-known, this pointer is also runtime-known, so29236 // If the index value is runtime-known, this pointer is also runtime-known, so
30274 // we must in turn make the alloc value runtime-known.29237 // 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)) {
30276 try sema.markMaybeComptimeAllocRuntime(block, alloc_inst);29239 try sema.markMaybeComptimeAllocRuntime(block, alloc_inst);
30277 }29240 }
30278 },29241 },
...@@ -30361,10 +29324,10 @@ fn bitCast(...@@ -30361,10 +29324,10 @@ fn bitCast(
30361) CompileError!Air.Inst.Ref {29324) CompileError!Air.Inst.Ref {
30362 const pt = sema.pt;29325 const pt = sema.pt;
30363 const zcu = pt.zcu;29326 const zcu = pt.zcu;
30364 try dest_ty.resolveLayout(pt);
30365
30366 const old_ty = sema.typeOf(inst);29327 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
30369 const dest_bits = dest_ty.bitSize(zcu);29332 const dest_bits = dest_ty.bitSize(zcu);
30370 const old_bits = old_ty.bitSize(zcu);29333 const old_bits = old_ty.bitSize(zcu);
...@@ -30378,7 +29341,7 @@ fn bitCast(...@@ -30378,7 +29341,7 @@ fn bitCast(
30378 });29341 });
30379 }29342 }
3038029343
30381 if (try sema.resolveValue(inst)) |val| {29344 if (sema.resolveValue(inst)) |val| {
30382 if (val.isUndef(zcu))29345 if (val.isUndef(zcu))
30383 return pt.undefRef(dest_ty);29346 return pt.undefRef(dest_ty);
30384 if (old_ty.zigTypeTag(zcu) == .error_set and dest_ty.zigTypeTag(zcu) == .error_set) {29347 if (old_ty.zigTypeTag(zcu) == .error_set and dest_ty.zigTypeTag(zcu) == .error_set) {
...@@ -30404,7 +29367,7 @@ fn coerceArrayPtrToSlice(...@@ -30404,7 +29367,7 @@ fn coerceArrayPtrToSlice(
30404) CompileError!Air.Inst.Ref {29367) CompileError!Air.Inst.Ref {
30405 const pt = sema.pt;29368 const pt = sema.pt;
30406 const zcu = pt.zcu;29369 const zcu = pt.zcu;
30407 if (try sema.resolveValue(inst)) |val| {29370 if (sema.resolveValue(inst)) |val| {
30408 const ptr_array_ty = sema.typeOf(inst);29371 const ptr_array_ty = sema.typeOf(inst);
30409 const array_ty = ptr_array_ty.childType(zcu);29372 const array_ty = ptr_array_ty.childType(zcu);
30410 const slice_ptr_ty = dest_ty.slicePtrFieldType(zcu);29373 const slice_ptr_ty = dest_ty.slicePtrFieldType(zcu);
...@@ -30499,7 +29462,7 @@ fn coerceCompatiblePtrs(...@@ -30499,7 +29462,7 @@ fn coerceCompatiblePtrs(
30499 const pt = sema.pt;29462 const pt = sema.pt;
30500 const zcu = pt.zcu;29463 const zcu = pt.zcu;
30501 const inst_ty = sema.typeOf(inst);29464 const inst_ty = sema.typeOf(inst);
30502 if (try sema.resolveValue(inst)) |val| {29465 if (sema.resolveValue(inst)) |val| {
30503 if (!val.isUndef(zcu) and val.isNull(zcu) and !dest_ty.isAllowzeroPtr(zcu)) {29466 if (!val.isUndef(zcu) and val.isNull(zcu) and !dest_ty.isAllowzeroPtr(zcu)) {
30504 return sema.fail(block, inst_src, "null pointer casted to type '{f}'", .{dest_ty.fmt(pt)});29467 return sema.fail(block, inst_src, "null pointer casted to type '{f}'", .{dest_ty.fmt(pt)});
30505 }29468 }
...@@ -30510,9 +29473,7 @@ fn coerceCompatiblePtrs(...@@ -30510,9 +29473,7 @@ fn coerceCompatiblePtrs(
30510 }29473 }
30511 try sema.requireRuntimeBlock(block, inst_src, null);29474 try sema.requireRuntimeBlock(block, inst_src, null);
30512 const inst_allows_zero = inst_ty.zigTypeTag(zcu) != .pointer or inst_ty.ptrAllowsZero(zcu);29475 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) and29476 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu)) {
30514 (try dest_ty.elemType2(zcu).hasRuntimeBitsSema(pt) or dest_ty.elemType2(zcu).zigTypeTag(zcu) == .@"fn"))
30515 {
30516 try sema.checkLogicalPtrOperation(block, inst_src, inst_ty);29477 try sema.checkLogicalPtrOperation(block, inst_src, inst_ty);
30517 const actual_ptr = if (inst_ty.isSlice(zcu))29478 const actual_ptr = if (inst_ty.isSlice(zcu))
30518 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)29479 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
...@@ -30532,6 +29493,7 @@ fn coerceCompatiblePtrs(...@@ -30532,6 +29493,7 @@ fn coerceCompatiblePtrs(
30532 return new_ptr;29493 return new_ptr;
30533}29494}
3053429495
29496/// Asserts that the layout of `union_ty` is already resolved.
30535fn coerceEnumToUnion(29497fn coerceEnumToUnion(
30536 sema: *Sema,29498 sema: *Sema,
30537 block: *Block,29499 block: *Block,
...@@ -30545,18 +29507,21 @@ fn coerceEnumToUnion(...@@ -30545,18 +29507,21 @@ fn coerceEnumToUnion(
30545 const ip = &zcu.intern_pool;29507 const ip = &zcu.intern_pool;
30546 const inst_ty = sema.typeOf(inst);29508 const inst_ty = sema.typeOf(inst);
3054729509
30548 const tag_ty = union_ty.unionTagType(zcu) orelse {29510 union_ty.assertHasLayout(zcu);
30549 const msg = msg: {29511
30550 const msg = try sema.typeMismatchErrMsg(inst_src, union_ty, inst_ty);29512 const union_obj = zcu.typeToUnion(union_ty).?;
30551 errdefer msg.destroy(sema.gpa);29513 const enum_ty: Type = .fromInterned(union_obj.enum_tag_type);
30552 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});29514 const enum_obj = ip.loadEnumType(enum_ty.toIntern());
30553 try sema.addDeclaredHereNote(msg, union_ty);29515
30554 break :msg msg;29516 if (union_obj.tag_usage != .tagged) return sema.failWithOwnedErrorMsg(block, msg: {
30555 };29517 const msg = try sema.typeMismatchErrMsg(inst_src, union_ty, inst_ty);
30556 return sema.failWithOwnedErrorMsg(block, msg);29518 errdefer msg.destroy(sema.gpa);
30557 };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);
30560 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {29525 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
30561 const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {29526 const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {
30562 return sema.fail(block, inst_src, "union '{f}' has no tag with value '{f}'", .{29527 return sema.fail(block, inst_src, "union '{f}' has no tag with value '{f}'", .{
...@@ -30564,101 +29529,88 @@ fn coerceEnumToUnion(...@@ -30564,101 +29529,88 @@ fn coerceEnumToUnion(
30564 });29529 });
30565 };29530 };
3056629531
30567 const union_obj = zcu.typeToUnion(union_ty).?;29532 const field_name = enum_obj.field_names.get(ip)[field_index];
30568 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);29533 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
30569 try field_ty.resolveFields(pt);29534 switch (field_ty.classify(zcu)) {
30570 if (field_ty.zigTypeTag(zcu) == .noreturn) {29535 .one_possible_value => return .fromValue(try pt.unionValue(
30571 const msg = msg: {29536 union_ty,
30572 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});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)});
30573 errdefer msg.destroy(sema.gpa);29543 errdefer msg.destroy(sema.gpa);
30574
30575 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
30576 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{29544 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
30577 field_name.fmt(ip),29545 field_name.fmt(ip),
30578 });29546 });
30579 try sema.addDeclaredHereNote(msg, union_ty);29547 try sema.addDeclaredHereNote(msg, union_ty);
30580 break :msg msg;29548 break :msg msg;
30581 };29549 }),
30582 return sema.failWithOwnedErrorMsg(block, msg);29550
30583 }29551 else => return sema.failWithOwnedErrorMsg(block, msg: {
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];
30587 const msg = try sema.errMsg(inst_src, "coercion from enum '{f}' to union '{f}' must initialize '{f}' field '{f}'", .{29552 const msg = try sema.errMsg(inst_src, "coercion from enum '{f}' to union '{f}' must initialize '{f}' field '{f}'", .{
30588 inst_ty.fmt(pt), union_ty.fmt(pt),29553 inst_ty.fmt(pt), union_ty.fmt(pt),
30589 field_ty.fmt(pt), field_name.fmt(ip),29554 field_ty.fmt(pt), field_name.fmt(ip),
30590 });29555 });
30591 errdefer msg.destroy(sema.gpa);29556 errdefer msg.destroy(sema.gpa);
3059229557
30593 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{29558 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{field_name.fmt(ip)});
30594 field_name.fmt(ip),
30595 });
30596 try sema.addDeclaredHereNote(msg, union_ty);29559 try sema.addDeclaredHereNote(msg, union_ty);
30597 break :msg msg;29560 break :msg msg;
30598 };29561 }),
30599 return sema.failWithOwnedErrorMsg(block, msg);29562 }
30600 };
30601
30602 return Air.internedToRef((try pt.unionValue(union_ty, val, opv)).toIntern());
30603 }29563 }
3060429564
30605 try sema.requireRuntimeBlock(block, inst_src, null);29565 try sema.requireRuntimeBlock(block, inst_src, null);
3060629566
30607 if (tag_ty.isNonexhaustiveEnum(zcu)) {29567 if (enum_ty.isNonexhaustiveEnum(zcu)) {
30608 const msg = msg: {29568 const msg = msg: {
30609 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{f}' from non-exhaustive enum", .{29569 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{f}' from non-exhaustive enum", .{
30610 union_ty.fmt(pt),29570 union_ty.fmt(pt),
30611 });29571 });
30612 errdefer msg.destroy(sema.gpa);29572 errdefer msg.destroy(sema.gpa);
30613 try sema.addDeclaredHereNote(msg, tag_ty);29573 try sema.addDeclaredHereNote(msg, enum_ty);
30614 break :msg msg;29574 break :msg msg;
30615 };29575 };
30616 return sema.failWithOwnedErrorMsg(block, msg);29576 return sema.failWithOwnedErrorMsg(block, msg);
30617 }29577 }
3061829578
30619 const union_obj = zcu.typeToUnion(union_ty).?;29579 for (union_obj.field_types.get(ip)) |field_ty_ip| {
30620 {29580 if (Type.fromInterned(field_ty_ip).classify(zcu) != .one_possible_value) break;
30621 var msg: ?*Zcu.ErrorMsg = null;29581 } else {
30622 errdefer if (msg) |some| some.destroy(sema.gpa);29582 // All fields are OPV, so the coercion is okay.
3062329583 if (try union_ty.onePossibleValue(pt)) |opv| {
30624 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {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.
30625 if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .noreturn) {29585 return .fromValue(opv);
30626 const err_msg = msg orelse try sema.errMsg(29586 } else {
30627 inst_src,29587 // The union layout is just the tag, so we can bitcast the enum straight to the union.
30628 "runtime coercion from enum '{f}' to union '{f}' which has a 'noreturn' field",29588 return block.addBitCast(union_ty, enum_tag);
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);
30640 }29589 }
30641 }29590 }
3064229591
30643 // If the union has all fields 0 bits, the union value is just the enum value.29592 // The coercion is invalid because one or more fields is not OPV.
30644 if (union_ty.unionHasAllZeroBitFieldTypes(zcu)) {
30645 return block.addBitCast(union_ty, enum_tag);
30646 }
3064729593
30648 const msg = msg: {29594 const msg = msg: {
30649 const msg = try sema.errMsg(29595 const msg = try sema.errMsg(
30650 inst_src,29596 inst_src,
30651 "runtime coercion from enum '{f}' to union '{f}' which has non-void fields",29597 "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) },
30653 );29599 );
30654 errdefer msg.destroy(sema.gpa);29600 errdefer msg.destroy(sema.gpa);
3065529601
30656 for (0..union_obj.field_types.len) |field_index| {29602 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];
30658 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);29604 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
30659 if (!(try field_ty.hasRuntimeBitsSema(pt))) continue;29605 const ty_description: []const u8 = switch (field_ty.classify(zcu)) {
30660 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' has type '{f}'", .{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}'", .{
30661 field_name.fmt(ip),29612 field_name.fmt(ip),
29613 ty_description,
30662 field_ty.fmt(pt),29614 field_ty.fmt(pt),
30663 });29615 });
30664 }29616 }
...@@ -30685,7 +29637,7 @@ fn coerceArrayLike(...@@ -30685,7 +29637,7 @@ fn coerceArrayLike(
30685 // try coercion of the whole array29637 // try coercion of the whole array
30686 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, null);29638 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, null);
30687 if (in_memory_result == .ok) {29639 if (in_memory_result == .ok) {
30688 if (try sema.resolveValue(inst)) |inst_val| {29640 if (sema.resolveValue(inst)) |inst_val| {
30689 // These types share the same comptime value representation.29641 // These types share the same comptime value representation.
30690 return sema.coerceInMemory(inst_val, dest_ty);29642 return sema.coerceInMemory(inst_val, dest_ty);
30691 }29643 }
...@@ -30708,7 +29660,7 @@ fn coerceArrayLike(...@@ -30708,7 +29660,7 @@ fn coerceArrayLike(
30708 }29660 }
3070929661
30710 const dest_elem_ty = dest_ty.childType(zcu);29662 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) {
30712 const inst_elem_ty = inst_ty.childType(zcu);29664 const inst_elem_ty = inst_ty.childType(zcu);
30713 switch (dest_elem_ty.zigTypeTag(zcu)) {29665 switch (dest_elem_ty.zigTypeTag(zcu)) {
30714 .int => if (inst_elem_ty.isInt(zcu)) {29666 .int => if (inst_elem_ty.isInt(zcu)) {
...@@ -30748,7 +29700,7 @@ fn coerceArrayLike(...@@ -30748,7 +29700,7 @@ fn coerceArrayLike(
30748 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);29700 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);
30749 ref.* = coerced;29701 ref.* = coerced;
30750 if (runtime_src == null) {29702 if (runtime_src == null) {
30751 if (try sema.resolveValue(coerced)) |elem_val| {29703 if (sema.resolveValue(coerced)) |elem_val| {
30752 val.* = elem_val.toIntern();29704 val.* = elem_val.toIntern();
30753 } else {29705 } else {
30754 runtime_src = elem_src;29706 runtime_src = elem_src;
...@@ -30809,7 +29761,7 @@ fn coerceTupleToArray(...@@ -30809,7 +29761,7 @@ fn coerceTupleToArray(
30809 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);29761 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);
30810 ref.* = coerced;29762 ref.* = coerced;
30811 if (runtime_src == null) {29763 if (runtime_src == null) {
30812 if (try sema.resolveValue(coerced)) |elem_val| {29764 if (sema.resolveValue(coerced)) |elem_val| {
30813 val.* = elem_val.toIntern();29765 val.* = elem_val.toIntern();
30814 } else {29766 } else {
30815 runtime_src = elem_src;29767 runtime_src = elem_src;
...@@ -30845,10 +29797,7 @@ fn coerceTupleToSlicePtrs(...@@ -30845,10 +29797,7 @@ fn coerceTupleToSlicePtrs(
30845 .child = slice_info.child,29797 .child = slice_info.child,
30846 });29798 });
30847 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);29799 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
30848 if (slice_info.flags.alignment != .none) {29800 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst, slice_info.flags.alignment);
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);
30852 return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src);29801 return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src);
30853}29802}
3085429803
...@@ -30867,10 +29816,7 @@ fn coerceTupleToArrayPtrs(...@@ -30867,10 +29816,7 @@ fn coerceTupleToArrayPtrs(
30867 const ptr_info = ptr_array_ty.ptrInfo(zcu);29816 const ptr_info = ptr_array_ty.ptrInfo(zcu);
30868 const array_ty: Type = .fromInterned(ptr_info.child);29817 const array_ty: Type = .fromInterned(ptr_info.child);
30869 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);29818 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
30870 if (ptr_info.flags.alignment != .none) {29819 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst, ptr_info.flags.alignment);
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);
30874 return ptr_array;29820 return ptr_array;
30875}29821}
3087629822
...@@ -30904,24 +29850,21 @@ fn coerceTupleToTuple(...@@ -30904,24 +29850,21 @@ fn coerceTupleToTuple(
30904 const field_i: u32 = @intCast(field_index_usize);29850 const field_i: u32 = @intCast(field_index_usize);
30905 const field_src = inst_src; // TODO better source location29851 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
30918 const field_index: u32 = @intCast(field_index_usize);29853 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
30920 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);29863 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);
30921 const coerced = try sema.coerce(block, .fromInterned(field_ty), elem_ref, field_src);29864 const coerced = try sema.coerce(block, .fromInterned(field_ty), elem_ref, field_src);
30922 field_refs[field_index] = coerced;29865 field_refs[field_index] = coerced;
30923 if (default_val != .none) {29866 if (default_val != .none) {
30924 const init_val = (try sema.resolveValue(coerced)) orelse {29867 const init_val = sema.resolveValue(coerced) orelse {
30925 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });29868 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
30926 };29869 };
3092729870
...@@ -30930,7 +29873,7 @@ fn coerceTupleToTuple(...@@ -30930,7 +29873,7 @@ fn coerceTupleToTuple(
30930 }29873 }
30931 }29874 }
30932 if (runtime_src == null) {29875 if (runtime_src == null) {
30933 if (try sema.resolveValue(coerced)) |field_val| {29876 if (sema.resolveValue(coerced)) |field_val| {
30934 field_vals[field_index] = field_val.toIntern();29877 field_vals[field_index] = field_val.toIntern();
30935 } else {29878 } else {
30936 runtime_src = field_src;29879 runtime_src = field_src;
...@@ -30946,11 +29889,7 @@ fn coerceTupleToTuple(...@@ -30946,11 +29889,7 @@ fn coerceTupleToTuple(
30946 const i: u32 = @intCast(i_usize);29889 const i: u32 = @intCast(i_usize);
30947 if (field_ref.* != .none) continue;29890 if (field_ref.* != .none) continue;
3094829891
30949 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {29892 const default_val = ip.indexToKey(tuple_ty.toIntern()).tuple_type.values.get(ip)[i];
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 };
3095429893
30955 const field_src = inst_src; // TODO better source location29894 const field_src = inst_src; // TODO better source location
30956 if (default_val == .none) {29895 if (default_val == .none) {
...@@ -30993,7 +29932,7 @@ fn analyzeNavVal(...@@ -30993,7 +29932,7 @@ fn analyzeNavVal(
30993 return sema.analyzeLoad(block, src, ref, src);29932 return sema.analyzeLoad(block, src, ref, src);
30994}29933}
3099529934
30996fn addReferenceEntry(29935pub fn addReferenceEntry(
30997 sema: *Sema,29936 sema: *Sema,
30998 opt_block: ?*Block,29937 opt_block: ?*Block,
30999 src: LazySrcLoc,29938 src: LazySrcLoc,
...@@ -31005,7 +29944,6 @@ fn addReferenceEntry(...@@ -31005,7 +29944,6 @@ fn addReferenceEntry(
31005 .func => |f| assert(ip.unwrapCoercedFunc(f) == f), // for `.{ .func = f }`, `f` must be uncoerced29944 .func => |f| assert(ip.unwrapCoercedFunc(f) == f), // for `.{ .func = f }`, `f` must be uncoerced
31006 else => {},29945 else => {},
31007 }29946 }
31008 if (!zcu.comp.config.incremental and zcu.comp.reference_trace == 0) return;
31009 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);29947 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);
31010 if (gop.found_existing) return;29948 if (gop.found_existing) return;
31011 try zcu.addUnitReference(sema.owner, referenced_unit, src, inline_frame: {29949 try zcu.addUnitReference(sema.owner, referenced_unit, src, inline_frame: {
...@@ -31019,13 +29957,12 @@ fn addReferenceEntry(...@@ -31019,13 +29957,12 @@ fn addReferenceEntry(
31019pub fn addTypeReferenceEntry(29957pub fn addTypeReferenceEntry(
31020 sema: *Sema,29958 sema: *Sema,
31021 src: LazySrcLoc,29959 src: LazySrcLoc,
31022 referenced_type: InternPool.Index,29960 referenced_type: Type,
31023) !void {29961) !void {
31024 const zcu = sema.pt.zcu;29962 const zcu = sema.pt.zcu;
31025 if (!zcu.comp.config.incremental and zcu.comp.reference_trace == 0) return;29963 const gop = try sema.type_references.getOrPut(sema.gpa, referenced_type.toIntern());
31026 const gop = try sema.type_references.getOrPut(sema.gpa, referenced_type);
31027 if (gop.found_existing) return;29964 if (gop.found_existing) return;
31028 try zcu.addTypeReference(sema.owner, referenced_type, src);29965 try zcu.addTypeReference(sema.owner, referenced_type.toIntern(), src);
31029}29966}
3103029967
31031fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.MemoizedStateStage) SemaError!void {29968fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.MemoizedStateStage) SemaError!void {
...@@ -31035,10 +29972,11 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M...@@ -31035,10 +29972,11 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M
31035 try sema.addReferenceEntry(null, src, unit);29972 try sema.addReferenceEntry(null, src, unit);
31036 try sema.declareDependency(.{ .memoized_state = stage });29973 try sema.declareDependency(.{ .memoized_state = stage });
3103729974
29975 const reason: Zcu.DependencyReason = .{ .src = src, .type_layout_reason = undefined };
31038 if (pt.zcu.analysis_in_progress.contains(unit)) {29976 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);
31040 }29978 }
31041 try pt.ensureMemoizedStateUpToDate(stage);29979 try pt.ensureMemoizedStateUpToDate(stage, &reason);
31042}29980}
3104329981
31044pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {29982pub 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:...@@ -31052,11 +29990,6 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index:
31052 return;29990 return;
31053 }29991 }
3105429992
31055 try sema.declareDependency(switch (kind) {
31056 .type => .{ .nav_ty = nav_index },
31057 .fully => .{ .nav_val = nav_index },
31058 });
31059
31060 // Note that even if `nav.status == .resolved`, we must still trigger `ensureNavValUpToDate`29993 // Note that even if `nav.status == .resolved`, we must still trigger `ensureNavValUpToDate`
31061 // to make sure the value is up-to-date on incremental updates.29994 // 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:...@@ -31065,32 +29998,37 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index:
31065 .fully => .{ .nav_val = nav_index },29998 .fully => .{ .nav_val = nav_index },
31066 });29999 });
31067 try sema.addReferenceEntry(block, src, anal_unit);30000 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
31069 if (zcu.analysis_in_progress.contains(anal_unit)) {30008 if (zcu.analysis_in_progress.contains(anal_unit)) {
31070 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{30009 return sema.failWithDependencyLoop(anal_unit, &reason);
31071 .base_node_inst = nav.analysis.?.zir_index,
31072 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
31073 }, "dependency loop detected", .{}));
31074 }30010 }
3107530011
31076 switch (kind) {30012 switch (kind) {
31077 .type => {30013 .type => {
31078 try zcu.ensureNavValAnalysisQueued(nav_index);30014 try zcu.ensureNavValAnalysisQueued(nav_index);
31079 return pt.ensureNavTypeUpToDate(nav_index);30015 return pt.ensureNavTypeUpToDate(nav_index, &reason);
31080 },30016 },
31081 .fully => return pt.ensureNavValUpToDate(nav_index),30017 .fully => return pt.ensureNavValUpToDate(nav_index, &reason),
31082 }30018 }
31083}30019}
3108430020
31085fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {30021fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
31086 const pt = sema.pt;30022 const pt = sema.pt;
31087 const ptr_anyopaque_ty = try pt.singleConstPtrType(.anyopaque);30023 const ptr_anyopaque_ty = try pt.singleConstPtrType(.anyopaque);
31088 return Value.fromInterned(try pt.intern(.{ .opt = .{30024 const opt_ptr_anyopaque_ty = try pt.optionalType(ptr_anyopaque_ty.toIntern());
31089 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),30025 return .fromInterned(try pt.intern(.{ .opt = .{
31090 .val = if (opt_val) |val| (try pt.getCoerced(30026 .ty = opt_ptr_anyopaque_ty.toIntern(),
31091 Value.fromInterned(try pt.refValue(val.toIntern())),30027 .val = payload: {
31092 ptr_anyopaque_ty,30028 const val = opt_val orelse break :payload .none;
31093 )).toIntern() else .none,30029 const ptr_val = try pt.getCoerced(try pt.uavValue(val), ptr_anyopaque_ty);
30030 break :payload ptr_val.toIntern();
30031 },
31094 } }));30032 } }));
31095}30033}
3109630034
...@@ -31143,7 +30081,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde...@@ -31143,7 +30081,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde
31143 .type_resolved => |r| .{ r.type, r.alignment, r.@"addrspace", r.is_const },30081 .type_resolved => |r| .{ r.type, r.alignment, r.@"addrspace", r.is_const },
31144 .fully_resolved => |r| .{ ip.typeOf(r.val), r.alignment, r.@"addrspace", r.is_const },30082 .fully_resolved => |r| .{ ip.typeOf(r.val), r.alignment, r.@"addrspace", r.is_const },
31145 };30083 };
31146 const ptr_ty = try pt.ptrTypeSema(.{30084 const ptr_ty = try pt.ptrType(.{
31147 .child = ty,30085 .child = ty,
31148 .flags = .{30086 .flags = .{
31149 .alignment = alignment,30087 .alignment = alignment,
...@@ -31185,7 +30123,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i...@@ -31185,7 +30123,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i
31185 try sema.ensureNavResolved(block, src, nav_index, .type);30123 try sema.ensureNavResolved(block, src, nav_index, .type);
31186 const nav_ty: Type = .fromInterned(ip.getNav(nav_index).typeOf(ip));30124 const nav_ty: Type = .fromInterned(ip.getNav(nav_index).typeOf(ip));
31187 if (nav_ty.zigTypeTag(zcu) != .@"fn") return;30125 if (nav_ty.zigTypeTag(zcu) != .@"fn") return;
31188 if (!try nav_ty.fnHasRuntimeBitsSema(pt)) return;30126 if (!nav_ty.fnHasRuntimeBits(zcu)) return;
3118930127
31190 try sema.ensureNavResolved(block, src, nav_index, .fully);30128 try sema.ensureNavResolved(block, src, nav_index, .fully);
31191 const nav_val = zcu.navValue(nav_index);30129 const nav_val = zcu.navValue(nav_index);
...@@ -31201,34 +30139,48 @@ fn analyzeRef(...@@ -31201,34 +30139,48 @@ fn analyzeRef(
31201 block: *Block,30139 block: *Block,
31202 src: LazySrcLoc,30140 src: LazySrcLoc,
31203 operand: Air.Inst.Ref,30141 operand: Air.Inst.Ref,
30142 alignment: Alignment,
31204) CompileError!Air.Inst.Ref {30143) CompileError!Air.Inst.Ref {
31205 const pt = sema.pt;30144 const pt = sema.pt;
31206 const zcu = pt.zcu;30145 const zcu = pt.zcu;
31207 const operand_ty = sema.typeOf(operand);30146 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| {
31210 switch (zcu.intern_pool.indexToKey(val.toIntern())) {30159 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
31211 .@"extern" => |e| return sema.analyzeNavRef(block, src, e.owner_nav),30160 .@"extern" => |e| return sema.analyzeNavRef(block, src, e.owner_nav),
31212 .func => |f| return sema.analyzeNavRef(block, src, f.owner_nav),30161 .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 } })),
31214 }30170 }
31215 }30171 }
3121630172
31217 // No `requireRuntimeBlock`; it's okay to `ref` to a runtime value in a comptime context,30173 // No `requireRuntimeBlock`; it's okay to `ref` to a runtime value in a comptime context,
31218 // it's just that we can only use the *type* of the result, since the value is runtime-known.30174 // 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);30176 const mut_ptr_type = try pt.ptrType(.{
31221 const ptr_type = try pt.ptrTypeSema(.{
31222 .child = operand_ty.toIntern(),30177 .child = operand_ty.toIntern(),
31223 .flags = .{30178 .flags = .{
31224 .is_const = true,30179 .alignment = alignment,
30180 .is_const = false,
31225 .address_space = address_space,30181 .address_space = address_space,
31226 },30182 },
31227 });30183 });
31228 const mut_ptr_type = try pt.ptrTypeSema(.{
31229 .child = operand_ty.toIntern(),
31230 .flags = .{ .address_space = address_space },
31231 });
31232 const alloc = try block.addTy(.alloc, mut_ptr_type);30184 const alloc = try block.addTy(.alloc, mut_ptr_type);
3123330185
31234 // In a comptime context, the store would fail, since the operand is runtime-known. But that's30186 // In a comptime context, the store would fail, since the operand is runtime-known. But that's
...@@ -31257,13 +30209,18 @@ fn analyzeLoad(...@@ -31257,13 +30209,18 @@ fn analyzeLoad(
31257 .pointer => ptr_ty.childType(zcu),30209 .pointer => ptr_ty.childType(zcu),
31258 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),30210 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),
31259 };30211 };
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| {30213 try sema.ensureLayoutResolved(elem_ty, src, .ptr_access);
31265 return Air.internedToRef(opv.toIntern());30214
31266 }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
31268 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {30225 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
31269 if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| {30226 if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| {
...@@ -31271,6 +30228,13 @@ fn analyzeLoad(...@@ -31271,6 +30228,13 @@ fn analyzeLoad(
31271 }30228 }
31272 }30229 }
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
31274 return block.addTyOp(.load, elem_ty, ptr);30238 return block.addTyOp(.load, elem_ty, ptr);
31275}30239}
3127630240
...@@ -31284,7 +30248,7 @@ fn analyzeSlicePtr(...@@ -31284,7 +30248,7 @@ fn analyzeSlicePtr(
31284 const pt = sema.pt;30248 const pt = sema.pt;
31285 const zcu = pt.zcu;30249 const zcu = pt.zcu;
31286 const result_ty = slice_ty.slicePtrFieldType(zcu);30250 const result_ty = slice_ty.slicePtrFieldType(zcu);
31287 if (try sema.resolveValue(slice)) |val| {30251 if (sema.resolveValue(slice)) |val| {
31288 if (val.isUndef(zcu)) return pt.undefRef(result_ty);30252 if (val.isUndef(zcu)) return pt.undefRef(result_ty);
31289 return Air.internedToRef(val.slicePtr(zcu).toIntern());30253 return Air.internedToRef(val.slicePtr(zcu).toIntern());
31290 }30254 }
...@@ -31304,7 +30268,7 @@ fn analyzeOptionalSlicePtr(...@@ -31304,7 +30268,7 @@ fn analyzeOptionalSlicePtr(
31304 const slice_ty = opt_slice_ty.optionalChild(zcu);30268 const slice_ty = opt_slice_ty.optionalChild(zcu);
31305 const result_ty = slice_ty.slicePtrFieldType(zcu);30269 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| {
31308 if (opt_val.isUndef(zcu)) return pt.undefRef(result_ty);30272 if (opt_val.isUndef(zcu)) return pt.undefRef(result_ty);
31309 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(zcu)) |val|30273 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(zcu)) |val|
31310 val.slicePtr(zcu).toIntern()30274 val.slicePtr(zcu).toIntern()
...@@ -31328,11 +30292,11 @@ fn analyzeSliceLen(...@@ -31328,11 +30292,11 @@ fn analyzeSliceLen(
31328) CompileError!Air.Inst.Ref {30292) CompileError!Air.Inst.Ref {
31329 const pt = sema.pt;30293 const pt = sema.pt;
31330 const zcu = pt.zcu;30294 const zcu = pt.zcu;
31331 if (try sema.resolveValue(slice_inst)) |slice_val| {30295 if (sema.resolveValue(slice_inst)) |slice_val| {
31332 if (slice_val.isUndef(zcu)) {30296 if (slice_val.isUndef(zcu)) {
31333 return .undef_usize;30297 return .undef_usize;
31334 }30298 }
31335 return pt.intRef(.usize, try slice_val.sliceLen(pt));30299 return pt.intRef(.usize, slice_val.sliceLen(zcu));
31336 }30300 }
31337 try sema.requireRuntimeBlock(block, src, null);30301 try sema.requireRuntimeBlock(block, src, null);
31338 return block.addTyOp(.slice_len, .usize, slice_inst);30302 return block.addTyOp(.slice_len, .usize, slice_inst);
...@@ -31341,25 +30305,25 @@ fn analyzeSliceLen(...@@ -31341,25 +30305,25 @@ fn analyzeSliceLen(
31341fn analyzeIsNull(30305fn analyzeIsNull(
31342 sema: *Sema,30306 sema: *Sema,
31343 block: *Block,30307 block: *Block,
30308 src: LazySrcLoc,
31344 operand: Air.Inst.Ref,30309 operand: Air.Inst.Ref,
31345 invert_logic: bool,30310 invert_logic: bool,
31346) CompileError!Air.Inst.Ref {30311) CompileError!Air.Inst.Ref {
31347 const pt = sema.pt;30312 const pt = sema.pt;
31348 const zcu = pt.zcu;30313 const zcu = pt.zcu;
31349 const result_ty: Type = .bool;30314
31350 if (try sema.resolveValue(operand)) |opt_val| {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| {
31351 if (opt_val.isUndef(zcu)) {30320 if (opt_val.isUndef(zcu)) {
31352 return pt.undefRef(result_ty);30321 return pt.undefRef(.bool);
31353 }30322 }
31354 const is_null = opt_val.isNull(zcu);30323 const is_null = opt_val.isNull(zcu);
31355 const bool_value = if (invert_logic) !is_null else is_null;30324 return .fromValue(.makeBool(is_null != invert_logic)); // XOR
31356 return if (bool_value) .bool_true else .bool_false;
31357 }30325 }
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 }
31363 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;30327 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
31364 return block.addUnOp(air_tag, operand);30328 return block.addUnOp(air_tag, operand);
31365}30329}
...@@ -31381,7 +30345,7 @@ fn resolvePtrIsNonErrVal(...@@ -31381,7 +30345,7 @@ fn resolvePtrIsNonErrVal(
31381 }30345 }
31382 assert(child_ty.zigTypeTag(zcu) == .error_union);30346 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| {
31385 if (eu_ptr_val.isUndef(zcu)) return .undef_bool;30349 if (eu_ptr_val.isUndef(zcu)) return .undef_bool;
31386 if (try sema.pointerDeref(block, src, eu_ptr_val, ptr_ty)) |err_union| {30350 if (try sema.pointerDeref(block, src, eu_ptr_val, ptr_ty)) |err_union| {
31387 if (err_union.isUndef(zcu)) return .undef_bool;30351 if (err_union.isUndef(zcu)) return .undef_bool;
...@@ -31404,7 +30368,7 @@ fn resolveIsNonErrVal(...@@ -31404,7 +30368,7 @@ fn resolveIsNonErrVal(
31404 }30368 }
31405 assert(sema.typeOf(operand).zigTypeTag(zcu) == .error_union);30369 assert(sema.typeOf(operand).zigTypeTag(zcu) == .error_union);
3140630370
31407 if (try sema.resolveValue(operand)) |err_union| {30371 if (sema.resolveValue(operand)) |err_union| {
31408 if (err_union.isUndef(zcu)) return .undef_bool;30372 if (err_union.isUndef(zcu)) return .undef_bool;
31409 return .makeBool(err_union.getErrorName(zcu) == .none);30373 return .makeBool(err_union.getErrorName(zcu) == .none);
31410 }30374 }
...@@ -31412,6 +30376,35 @@ fn resolveIsNonErrVal(...@@ -31412,6 +30376,35 @@ fn resolveIsNonErrVal(
31412 return null;30376 return null;
31413}30377}
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
31415fn resolveIsNonErrFromType(30408fn resolveIsNonErrFromType(
31416 sema: *Sema,30409 sema: *Sema,
31417 block: *Block,30410 block: *Block,
...@@ -31420,89 +30413,71 @@ fn resolveIsNonErrFromType(...@@ -31420,89 +30413,71 @@ fn resolveIsNonErrFromType(
31420) CompileError!?Value {30413) CompileError!?Value {
31421 const pt = sema.pt;30414 const pt = sema.pt;
31422 const zcu = pt.zcu;30415 const zcu = pt.zcu;
31423 const ip = &zcu.intern_pool;
31424 const ot = operand_ty.zigTypeTag(zcu);30416 const ot = operand_ty.zigTypeTag(zcu);
31425 if (ot != .error_set and ot != .error_union) return .true;30417 if (ot != .error_set and ot != .error_union) return .true;
31426 if (ot == .error_set) return .false;30418 if (ot == .error_set) return .false;
31427 assert(ot == .error_union);30419 assert(ot == .error_union);
3142830420
31429 const payload_ty = operand_ty.errorUnionPayload(zcu);30421 const payload_ty = operand_ty.errorUnionPayload(zcu);
31430 if (payload_ty.zigTypeTag(zcu) == .noreturn) {30422 if (payload_ty.classify(zcu) == .no_possible_value) {
31431 return .false;30423 return .false;
31432 }30424 }
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,30431/// Returns `true` iff the error set type `orig_err_set_ty` contains no errors.
31435 // we allow the comparison but always make it comptime-known.30432///
31436 const set_ty = ip.errorUnionSet(operand_ty.toIntern());30433/// This is used to give comptime answers for whether `error{}!T` is an error or a payload, as well
31437 switch (set_ty) {30434/// as whether `?error{}` is null. The type `error{}` cannot be NPV, as it has runtime bits, but the
31438 .anyerror_type => {},30435/// only value of that type which can exist is `undefined`; semantically it has no "legal" value.
31439 .adhoc_inferred_error_set_type => if (sema.fn_ret_ty_ies) |ies| blk: {30436/// TODO: this runs into some unsolved language design questions about such types. Performing a
31440 // If the error set is empty, we must return a comptime true or false.30437/// coercion from `@as(E, undefined)` to `E!T` needs to semantically result in an `undefined` error
31441 // However we want to avoid unnecessarily resolving an inferred error set30438/// union if our implementation is to be legal, and likewise for coercing `@as(E, undefined)` to
31442 // in case it is already non-empty.30439/// `?E` (for an error set `E`) because our implementation uses the zero error value at runtime to
31443 switch (ies.resolved) {30440/// represent `null`. The unsolved problem is the exact rules for `undefined` propagation through
31444 .anyerror_type => break :blk,30441/// these types: for instance, what if `@as(u32, undfined)` is coerced to `?u32`? What about error
31445 .none => {},30442/// union *payloads*, i.e. `@as(u32, undefined)` to `E!u32`? That one is analagous to the optional
31446 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,30443/// example in some ways, but right now I believe there is code which relies on that coercion giving
31447 }30444/// a well-defined error union with an `undefined` payload.
3144830445/// Relevant issues/discussions:
31449 if (ies.errors.count() != 0) return null;30446/// * https://github.com/ziglang/zig/issues/1831
31450 switch (ies.resolved) {30447/// * https://github.com/ziglang/zig/issues/6762
31451 .anyerror_type => return null,30448/// * https://github.com/ziglang/zig/issues/1831#issuecomment-722129239
31452 .none => {},30449fn resolveErrSetIsEmpty(
31453 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {30450 sema: *Sema,
31454 0 => return .true,30451 block: *Block,
31455 else => return null,30452 src: LazySrcLoc,
31456 },30453 orig_err_set_ty: Type,
31457 }30454) CompileError!bool {
31458 // We do not have a comptime answer because this inferred error30455 const ip = &sema.pt.zcu.intern_pool;
31459 // set is not resolved, and an instruction later in this function30456 err_set: switch (orig_err_set_ty.toIntern()) {
31460 // body may or may not cause an error to be added to this set.30457 .anyerror_type => return false,
31461 return null;30458 .adhoc_inferred_error_set_type => {
31462 },30459 // This is *our* error set; that is, we're currently analyzing the function
31463 else => switch (ip.indexToKey(set_ty)) {30460 // which owns it. Trying to resolve it now would cause a dependency loop.
31464 .error_set_type => |error_set_type| {30461 // Instead, accept that we don't know.
31465 if (error_set_type.names.len == 0) return .true;30462 return false;
31466 },30463 },
31467 .inferred_error_set_type => |func_index| blk: {30464 else => |err_set_ty| switch (ip.indexToKey(err_set_ty)) {
31468 // If the error set is empty, we must return a comptime true or false.30465 .error_set_type => |es| return es.names.len == 0,
31469 // However we want to avoid unnecessarily resolving an inferred error set30466 .inferred_error_set_type => |func_index| {
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 }
31477 if (sema.fn_ret_ty_ies) |ies| {30467 if (sema.fn_ret_ty_ies) |ies| {
31478 if (ies.func == func_index) {30468 if (ies.func == func_index) {
31479 // Try to avoid resolving inferred error set if possible.30469 // This is *our* error set; that is, we're currently analyzing the function
31480 if (ies.errors.count() != 0) return null;30470 // which owns it. Trying to resolve it now would cause a dependency loop.
31481 switch (ies.resolved) {30471 // Instead, accept that we don't know.
31482 .anyerror_type => return null,30472 return false;
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;
31493 }30473 }
31494 }30474 }
31495 const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);30475 try sema.ensureFuncIesResolved(block, src, func_index);
31496 if (resolved_ty == .anyerror_type)30476 continue :err_set ip.funcIesResolvedUnordered(func_index);
31497 break :blk;
31498 if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0)
31499 return .true;
31500 },30477 },
31501 else => unreachable,30478 else => unreachable,
31502 },30479 },
31503 }30480 }
31504
31505 return null;
31506}30481}
3150730482
31508fn analyzeIsNonErr(30483fn analyzeIsNonErr(
...@@ -31682,6 +30657,8 @@ fn analyzeSlice(...@@ -31682,6 +30657,8 @@ fn analyzeSlice(
31682 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),30657 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),
31683 }30658 }
3168430659
30660 try sema.ensureLayoutResolved(elem_ty, src, .ptr_access);
30661
31685 const ptr = if (slice_ty.isSlice(zcu))30662 const ptr = if (slice_ty.isSlice(zcu))
31686 try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty)30663 try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty)
31687 else if (array_ty.zigTypeTag(zcu) == .array) ptr: {30664 else if (array_ty.zigTypeTag(zcu) == .array) ptr: {
...@@ -31690,11 +30667,11 @@ fn analyzeSlice(...@@ -31690,11 +30667,11 @@ fn analyzeSlice(
31690 assert(manyptr_ty_key.flags.size == .one);30667 assert(manyptr_ty_key.flags.size == .one);
31691 manyptr_ty_key.child = elem_ty.toIntern();30668 manyptr_ty_key.child = elem_ty.toIntern();
31692 manyptr_ty_key.flags.size = .many;30669 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);
31694 } else ptr_or_slice;30671 } else ptr_or_slice;
3169530672
31696 const start = try sema.coerce(block, .usize, uncasted_start, start_src);30673 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);
31698 const new_ptr_ty = sema.typeOf(new_ptr);30675 const new_ptr_ty = sema.typeOf(new_ptr);
3169930676
31700 // true if and only if the end index of the slice, implicitly or explicitly, equals30677 // true if and only if the end index of the slice, implicitly or explicitly, equals
...@@ -31754,12 +30731,12 @@ fn analyzeSlice(...@@ -31754,12 +30731,12 @@ fn analyzeSlice(
31754 break :end try sema.coerce(block, .usize, uncasted_end, end_src);30731 break :end try sema.coerce(block, .usize, uncasted_end, end_src);
31755 } else try sema.coerce(block, .usize, uncasted_end_opt, end_src);30732 } else try sema.coerce(block, .usize, uncasted_end_opt, end_src);
31756 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {30733 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| {
31758 if (slice_val.isUndef(zcu)) {30735 if (slice_val.isUndef(zcu)) {
31759 return sema.fail(block, src, "slice of undefined", .{});30736 return sema.fail(block, src, "slice of undefined", .{});
31760 }30737 }
31761 const has_sentinel = slice_ty.sentinel(zcu) != null;30738 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);
31763 const len_plus_sent = slice_len + @intFromBool(has_sentinel);30740 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
31764 const slice_len_val_with_sentinel = try pt.intValue(.usize, len_plus_sent);30741 const slice_len_val_with_sentinel = try pt.intValue(.usize, len_plus_sent);
31765 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, .usize))) {30742 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, .usize))) {
...@@ -31774,7 +30751,7 @@ fn analyzeSlice(...@@ -31774,7 +30751,7 @@ fn analyzeSlice(
31774 "end index {f} out of bounds for slice of length {d}{s}",30751 "end index {f} out of bounds for slice of length {d}{s}",
31775 .{30752 .{
31776 end_val.fmtValueSema(pt, sema),30753 end_val.fmtValueSema(pt, sema),
31777 try slice_val.sliceLen(pt),30754 slice_val.sliceLen(zcu),
31778 sentinel_label,30755 sentinel_label,
31779 },30756 },
31780 );30757 );
...@@ -31832,7 +30809,7 @@ fn analyzeSlice(...@@ -31832,7 +30809,7 @@ fn analyzeSlice(
31832 break :msg msg;30809 break :msg msg;
31833 });30810 });
31834 }30811 }
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);
31836 };30813 };
3183730814
31838 const sentinel = s: {30815 const sentinel = s: {
...@@ -31876,7 +30853,7 @@ fn analyzeSlice(...@@ -31876,7 +30853,7 @@ fn analyzeSlice(
31876 );30853 );
31877 }30854 }
31878 checked_start_lte_end = true;30855 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: {
31880 const expected_sentinel = sentinel orelse break :sentinel_check;30857 const expected_sentinel = sentinel orelse break :sentinel_check;
31881 const start_int = start_val.toUnsignedInt(zcu);30858 const start_int = start_val.toUnsignedInt(zcu);
31882 const end_int = end_val.toUnsignedInt(zcu);30859 const end_int = end_val.toUnsignedInt(zcu);
...@@ -31943,9 +30920,9 @@ fn analyzeSlice(...@@ -31943,9 +30920,9 @@ fn analyzeSlice(
31943 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(zcu) != .c;30920 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(zcu) != .c;
3194430921
31945 if (opt_new_len_val) |new_len_val| {30922 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(.{
31949 .child = (try pt.arrayType(.{30926 .child = (try pt.arrayType(.{
31950 .len = new_len_int,30927 .len = new_len_int,
31951 .sentinel = if (sentinel) |s| s.toIntern() else .none,30928 .sentinel = if (sentinel) |s| s.toIntern() else .none,
...@@ -31960,13 +30937,13 @@ fn analyzeSlice(...@@ -31960,13 +30937,13 @@ fn analyzeSlice(
31960 },30937 },
31961 });30938 });
3196230939
31963 const opt_new_ptr_val = try sema.resolveValue(new_ptr);30940 const opt_new_ptr_val = sema.resolveValue(new_ptr);
31964 const new_ptr_val = opt_new_ptr_val orelse {30941 const new_ptr_val = opt_new_ptr_val orelse {
31965 const result = try block.addBitCast(return_ty, new_ptr);30942 const result = try block.addBitCast(return_ty, new_ptr);
31966 if (block.wantSafety()) {30943 if (block.wantSafety()) {
31967 // requirement: slicing C ptr is non-null30944 // requirement: slicing C ptr is non-null
31968 if (ptr_ptr_child_ty.isCPtr(zcu)) {30945 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);
31970 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);30947 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
31971 }30948 }
3197230949
...@@ -32009,7 +30986,7 @@ fn analyzeSlice(...@@ -32009,7 +30986,7 @@ fn analyzeSlice(
32009 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});30986 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
32010 }30987 }
3201130988
32012 const return_ty = try pt.ptrTypeSema(.{30989 const return_ty = try pt.ptrType(.{
32013 .child = elem_ty.toIntern(),30990 .child = elem_ty.toIntern(),
32014 .sentinel = if (sentinel) |s| s.toIntern() else .none,30991 .sentinel = if (sentinel) |s| s.toIntern() else .none,
32015 .flags = .{30992 .flags = .{
...@@ -32026,7 +31003,7 @@ fn analyzeSlice(...@@ -32026,7 +31003,7 @@ fn analyzeSlice(
32026 if (block.wantSafety()) {31003 if (block.wantSafety()) {
32027 // requirement: slicing C ptr is non-null31004 // requirement: slicing C ptr is non-null
32028 if (ptr_ptr_child_ty.isCPtr(zcu)) {31005 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);
32030 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);31007 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
32031 }31008 }
3203231009
...@@ -32037,7 +31014,7 @@ fn analyzeSlice(...@@ -32037,7 +31014,7 @@ fn analyzeSlice(
32037 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {31014 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
32038 // we don't need to add one for sentinels because the31015 // we don't need to add one for sentinels because the
32039 // underlying value data includes the sentinel31016 // 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));
32041 }31018 }
3204231019
32043 const slice_len_inst = try block.addTyOp(.slice_len, .usize, ptr_or_slice);31020 const slice_len_inst = try block.addTyOp(.slice_len, .usize, ptr_or_slice);
...@@ -32107,8 +31084,8 @@ fn cmpNumeric(...@@ -32107,8 +31084,8 @@ fn cmpNumeric(
32107 else31084 else
32108 uncasted_rhs;31085 uncasted_rhs;
3210931086
32110 const maybe_lhs_val = try sema.resolveValue(lhs);31087 const maybe_lhs_val = sema.resolveValue(lhs);
32111 const maybe_rhs_val = try sema.resolveValue(rhs);31088 const maybe_rhs_val = sema.resolveValue(rhs);
3211231089
32113 // If the LHS is const, check if there is a guaranteed result which does not depend on ths RHS value.31090 // If the LHS is const, check if there is a guaranteed result which does not depend on ths RHS value.
32114 if (maybe_lhs_val) |lhs_val| {31091 if (maybe_lhs_val) |lhs_val| {
...@@ -32158,16 +31135,10 @@ fn cmpNumeric(...@@ -32158,16 +31135,10 @@ fn cmpNumeric(
3215831135
32159 const runtime_src: LazySrcLoc = if (maybe_lhs_val) |lhs_val| rs: {31136 const runtime_src: LazySrcLoc = if (maybe_lhs_val) |lhs_val| rs: {
32160 if (maybe_rhs_val) |rhs_val| {31137 if (maybe_rhs_val) |rhs_val| {
32161 const res = try Value.compareHeteroSema(lhs_val, op, rhs_val, pt);31138 return .fromValue(.makeBool(Value.compareHetero(lhs_val, op, rhs_val, zcu)));
32162 return if (res) .bool_true else .bool_false;
32163 } else break :rs rhs_src;31139 } else break :rs rhs_src;
32164 } else lhs_src;31140 } 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.
32171 try sema.requireRuntimeBlock(block, src, runtime_src);31142 try sema.requireRuntimeBlock(block, src, runtime_src);
3217231143
32173 // For floats, emit a float comparison instruction.31144 // For floats, emit a float comparison instruction.
...@@ -32207,11 +31178,11 @@ fn cmpNumeric(...@@ -32207,11 +31178,11 @@ fn cmpNumeric(
32207 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,31178 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,
32208 // add/subtract 1.31179 // add/subtract 1.
32209 const lhs_is_signed = if (maybe_lhs_val) |lhs_val|31180 const lhs_is_signed = if (maybe_lhs_val) |lhs_val|
32210 !(try lhs_val.compareAllWithZeroSema(.gte, pt))31181 !lhs_val.compareAllWithZero(.gte, zcu)
32211 else31182 else
32212 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(zcu));31183 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(zcu));
32213 const rhs_is_signed = if (maybe_rhs_val) |rhs_val|31184 const rhs_is_signed = if (maybe_rhs_val) |rhs_val|
32214 !(try rhs_val.compareAllWithZeroSema(.gte, pt))31185 !rhs_val.compareAllWithZero(.gte, zcu)
32215 else31186 else
32216 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(zcu));31187 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(zcu));
32217 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;31188 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
...@@ -32219,10 +31190,9 @@ fn cmpNumeric(...@@ -32219,10 +31190,9 @@ fn cmpNumeric(
32219 var dest_float_type: ?Type = null;31190 var dest_float_type: ?Type = null;
3222031191
32221 var lhs_bits: usize = undefined;31192 var lhs_bits: usize = undefined;
32222 if (maybe_lhs_val) |unresolved_lhs_val| {31193 if (maybe_lhs_val) |lhs_val| {
32223 const lhs_val = try sema.resolveLazyValue(unresolved_lhs_val);
32224 if (!rhs_is_signed) {31194 if (!rhs_is_signed) {
32225 switch (lhs_val.orderAgainstZero(zcu)) {31195 switch (Value.order(lhs_val, .zero_comptime_int, zcu)) {
32226 .gt => {},31196 .gt => {},
32227 .eq => switch (op) { // LHS = 0, RHS is unsigned31197 .eq => switch (op) { // LHS = 0, RHS is unsigned
32228 .lte => return .bool_true,31198 .lte => return .bool_true,
...@@ -32263,10 +31233,9 @@ fn cmpNumeric(...@@ -32263,10 +31233,9 @@ fn cmpNumeric(
32263 }31233 }
3226431234
32265 var rhs_bits: usize = undefined;31235 var rhs_bits: usize = undefined;
32266 if (maybe_rhs_val) |unresolved_rhs_val| {31236 if (maybe_rhs_val) |rhs_val| {
32267 const rhs_val = try sema.resolveLazyValue(unresolved_rhs_val);
32268 if (!lhs_is_signed) {31237 if (!lhs_is_signed) {
32269 switch (rhs_val.orderAgainstZero(zcu)) {31238 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
32270 .gt => {},31239 .gt => {},
32271 .eq => switch (op) { // RHS = 0, LHS is unsigned31240 .eq => switch (op) { // RHS = 0, LHS is unsigned
32272 .gte => return .bool_true,31241 .gte => return .bool_true,
...@@ -32328,7 +31297,7 @@ fn compareIntsOnlyPossibleResult(...@@ -32328,7 +31297,7 @@ fn compareIntsOnlyPossibleResult(
32328 lhs_val: Value,31297 lhs_val: Value,
32329 op: std.math.CompareOperator,31298 op: std.math.CompareOperator,
32330 rhs_ty: Type,31299 rhs_ty: Type,
32331) SemaError!?bool {31300) Allocator.Error!?bool {
32332 const pt = sema.pt;31301 const pt = sema.pt;
32333 const zcu = pt.zcu;31302 const zcu = pt.zcu;
3233431303
...@@ -32337,11 +31306,11 @@ fn compareIntsOnlyPossibleResult(...@@ -32337,11 +31306,11 @@ fn compareIntsOnlyPossibleResult(
3233731306
32338 if (min_rhs.toIntern() == max_rhs.toIntern()) {31307 if (min_rhs.toIntern() == max_rhs.toIntern()) {
32339 // RHS is effectively comptime-known.31308 // 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);
32341 }31310 }
3234231311
32343 const against_min = try lhs_val.orderAdvanced(min_rhs, .sema, zcu, pt.tid);31312 const against_min = lhs_val.order(min_rhs, zcu);
32344 const against_max = try lhs_val.orderAdvanced(max_rhs, .sema, zcu, pt.tid);31313 const against_max = lhs_val.order(max_rhs, zcu);
3234531314
32346 switch (op) {31315 switch (op) {
32347 .eq => {31316 .eq => {
...@@ -32401,8 +31370,8 @@ fn cmpVector(...@@ -32401,8 +31370,8 @@ fn cmpVector(
32401 .child = .bool_type,31370 .child = .bool_type,
32402 });31371 });
3240331372
32404 const maybe_lhs_val = try sema.resolveValue(casted_lhs);31373 const maybe_lhs_val = sema.resolveValue(casted_lhs);
32405 const maybe_rhs_val = try sema.resolveValue(casted_rhs);31374 const maybe_rhs_val = sema.resolveValue(casted_rhs);
32406 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(result_ty);31375 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(result_ty);
32407 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(result_ty);31376 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(result_ty);
3240831377
...@@ -32424,7 +31393,7 @@ fn wrapOptional(...@@ -32424,7 +31393,7 @@ fn wrapOptional(
32424 inst: Air.Inst.Ref,31393 inst: Air.Inst.Ref,
32425 inst_src: LazySrcLoc,31394 inst_src: LazySrcLoc,
32426) !Air.Inst.Ref {31395) !Air.Inst.Ref {
32427 if (try sema.resolveValue(inst)) |val| {31396 if (sema.resolveValue(inst)) |val| {
32428 return Air.internedToRef((try sema.pt.intern(.{ .opt = .{31397 return Air.internedToRef((try sema.pt.intern(.{ .opt = .{
32429 .ty = dest_ty.toIntern(),31398 .ty = dest_ty.toIntern(),
32430 .val = val.toIntern(),31399 .val = val.toIntern(),
...@@ -32446,7 +31415,7 @@ fn wrapErrorUnionPayload(...@@ -32446,7 +31415,7 @@ fn wrapErrorUnionPayload(
32446 const zcu = pt.zcu;31415 const zcu = pt.zcu;
32447 const dest_payload_ty = dest_ty.errorUnionPayload(zcu);31416 const dest_payload_ty = dest_ty.errorUnionPayload(zcu);
32448 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });31417 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| {
32450 return Air.internedToRef((try pt.intern(.{ .error_union = .{31419 return Air.internedToRef((try pt.intern(.{ .error_union = .{
32451 .ty = dest_ty.toIntern(),31420 .ty = dest_ty.toIntern(),
32452 .val = .{ .payload = val.toIntern() },31421 .val = .{ .payload = val.toIntern() },
...@@ -32466,80 +31435,40 @@ fn wrapErrorUnionSet(...@@ -32466,80 +31435,40 @@ fn wrapErrorUnionSet(
32466 const pt = sema.pt;31435 const pt = sema.pt;
32467 const zcu = pt.zcu;31436 const zcu = pt.zcu;
32468 const ip = &zcu.intern_pool;31437 const ip = &zcu.intern_pool;
32469 const inst_ty = sema.typeOf(inst);
32470 const dest_err_set_ty = dest_ty.errorUnionSet(zcu);31438 const dest_err_set_ty = dest_ty.errorUnionSet(zcu);
32471 if (try sema.resolveValue(inst)) |val| {31439 const coerced = try sema.coerceExtra(block, dest_err_set_ty, inst, inst_src, .{ .report_err = false });
32472 const expected_name = zcu.intern_pool.indexToKey(val.toIntern()).err.name;31440 if (try sema.resolveDefinedValue(block, inst_src, coerced)) |error_val| {
32473 switch (dest_err_set_ty.toIntern()) {31441 return .fromIntern(try pt.intern(.{ .error_union = .{
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 = .{
32513 .ty = dest_ty.toIntern(),31442 .ty = dest_ty.toIntern(),
32514 .val = .{ .err_name = expected_name },31443 .val = .{ .err_name = ip.indexToKey(error_val.toIntern()).err.name },
32515 } })));31444 } }));
31445 } else {
31446 return block.addTyOp(.wrap_errunion_err, dest_ty, coerced);
32516 }31447 }
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);
32521}31448}
3252231449
32523fn unionToTag(31450/// Returns the enum tag value for the active tag of a tagged union value.
32524 sema: *Sema,31451///
32525 block: *Block,31452/// Asserts that the type of `un` is a tagged union type.
32526 enum_ty: Type,31453fn unionToTag(sema: *Sema, block: *Block, un: Air.Inst.Ref) !Air.Inst.Ref {
32527 un: Air.Inst.Ref,
32528 un_src: LazySrcLoc,
32529) !Air.Inst.Ref {
32530 const pt = sema.pt;31454 const pt = sema.pt;
32531 const zcu = pt.zcu;31455 const zcu = pt.zcu;
32532 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {31456 const ip = &zcu.intern_pool;
32533 return Air.internedToRef(opv.toIntern());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).?);
32534 }31461 }
32535 if (try sema.resolveValue(un)) |un_val| {31462 const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
32536 const tag_val = un_val.unionTag(zcu).?;31463 if (!union_obj.has_runtime_tag) {
32537 if (tag_val.isUndef(zcu))31464 // This means that only one field is possible.
32538 return try pt.undefRef(enum_ty);31465 const field_index = for (union_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
32539 return Air.internedToRef(tag_val.toIntern());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)));
32540 }31470 }
32541 try sema.requireRuntimeBlock(block, un_src, null);31471 return block.addTyOp(.get_union_tag, enum_tag_ty, un);
32542 return block.addTyOp(.get_union_tag, enum_ty, un);
32543}31472}
3254431473
32545const PeerResolveStrategy = enum {31474const PeerResolveStrategy = enum {
...@@ -32879,7 +31808,7 @@ fn resolvePeerTypes(...@@ -32879,7 +31808,7 @@ fn resolvePeerTypes(
3287931808
32880 for (instructions, peer_tys, peer_vals) |inst, *ty, *val| {31809 for (instructions, peer_tys, peer_vals) |inst, *ty, *val| {
32881 ty.* = sema.typeOf(inst);31810 ty.* = sema.typeOf(inst);
32882 val.* = try sema.resolveValue(inst);31811 val.* = sema.resolveValue(inst);
32883 }31812 }
3288431813
32885 switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) {31814 switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) {
...@@ -33240,18 +32169,24 @@ fn resolvePeerTypesInner(...@@ -33240,18 +32169,24 @@ fn resolvePeerTypesInner(
33240 ptr_info.sentinel = .none;32169 ptr_info.sentinel = .none;
33241 }32170 }
3324232171
33243 // Note that the align can be always non-zero; Zcu.ptrType will canonicalize it32172 ptr_info.flags.alignment = a: {
33244 ptr_info.flags.alignment = InternPool.Alignment.min(32173 // If both alignments are implicit, the result alignment is implicit.
33245 if (ptr_info.flags.alignment != .none)32174 // e.g. '[*c]u32' + '[*c]c_uint' -> '[*c]u32'
33246 ptr_info.flags.alignment32175 if (ptr_info.flags.alignment == .none and peer_info.flags.alignment == .none) {
33247 else32176 break :a .none;
33248 Type.fromInterned(ptr_info.child).abiAlignment(zcu),32177 }
3324932178 // Otherwise (if either alignment is explicit), the result alignment is explicit.
33250 if (peer_info.flags.alignment != .none)32179 // e.g. '[*c]u32' + '[*c]align(4) c_uint' -> '[*c]align(4) u32'
33251 peer_info.flags.alignment32180 const cur_align = switch (ptr_info.flags.alignment) {
33252 else32181 .none => Type.fromInterned(ptr_info.child).abiAlignment(zcu),
33253 Type.fromInterned(peer_info.child).abiAlignment(zcu),32182 else => ptr_info.flags.alignment,
33254 );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 };
33255 if (ptr_info.flags.address_space != peer_info.flags.address_space) {32190 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
33256 return .{ .conflict = .{32191 return .{ .conflict = .{
33257 .peer_idx_a = first_idx,32192 .peer_idx_a = first_idx,
...@@ -33273,7 +32208,7 @@ fn resolvePeerTypesInner(...@@ -33273,7 +32208,7 @@ fn resolvePeerTypesInner(
3327332208
33274 opt_ptr_info = ptr_info;32209 opt_ptr_info = ptr_info;
33275 }32210 }
33276 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };32211 return .{ .success = try pt.ptrType(opt_ptr_info.?) };
33277 },32212 },
3327832213
33279 .ptr => {32214 .ptr => {
...@@ -33281,7 +32216,6 @@ fn resolvePeerTypesInner(...@@ -33281,7 +32216,6 @@ fn resolvePeerTypesInner(
33281 // if there were no actual slices. Else, we want the slice index to report a conflict.32216 // if there were no actual slices. Else, we want the slice index to report a conflict.
33282 var opt_slice_idx: ?usize = null;32217 var opt_slice_idx: ?usize = null;
3328332218
33284 var any_abi_aligned = false;
33285 var opt_ptr_info: ?InternPool.Key.PtrType = null;32219 var opt_ptr_info: ?InternPool.Key.PtrType = null;
33286 var first_idx: usize = undefined;32220 var first_idx: usize = undefined;
33287 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error32221 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
...@@ -33325,15 +32259,24 @@ fn resolvePeerTypesInner(...@@ -33325,15 +32259,24 @@ fn resolvePeerTypesInner(
33325 .peer_idx_b = i,32259 .peer_idx_b = i,
33326 } };32260 } };
3332732261
33328 // Note that the align can be always non-zero; Type.ptr will canonicalize it32262 ptr_info.flags.alignment = a: {
33329 if (peer_info.flags.alignment == .none) {32263 // If both alignments are implicit, the result alignment is implicit.
33330 any_abi_aligned = true;32264 // e.g. '*u32' + '*c_uint' -> '*u32'
33331 } else if (ptr_info.flags.alignment == .none) {32265 if (ptr_info.flags.alignment == .none and peer_info.flags.alignment == .none) {
33332 any_abi_aligned = true;32266 break :a .none;
33333 ptr_info.flags.alignment = peer_info.flags.alignment;32267 }
33334 } else {32268 // Otherwise (if either alignment is explicit), the result alignment is explicit.
33335 ptr_info.flags.alignment = ptr_info.flags.alignment.minStrict(peer_info.flags.alignment);32269 // e.g. '*u32' + '*align(4) c_uint' -> '*align(4) u32'
33336 }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
33338 if (ptr_info.flags.address_space != peer_info.flags.address_space) {32281 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
33339 return generic_err;32282 return generic_err;
...@@ -33582,13 +32525,7 @@ fn resolvePeerTypesInner(...@@ -33582,13 +32525,7 @@ fn resolvePeerTypesInner(
33582 },32525 },
33583 }32526 }
3358432527
33585 if (any_abi_aligned and opt_ptr_info.?.flags.alignment != .none) {32528 return .{ .success = try pt.ptrType(opt_ptr_info.?) };
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.?) };
33592 },32529 },
3359332530
33594 .func => {32531 .func => {
...@@ -33731,7 +32668,7 @@ fn resolvePeerTypesInner(...@@ -33731,7 +32668,7 @@ fn resolvePeerTypesInner(
33731 .peer_idx_b = i,32668 .peer_idx_b = i,
33732 } };32669 } };
33733 any_comptime_known = true;32670 any_comptime_known = true;
33734 ptr_opt_val.* = try sema.resolveLazyValue(opt_val.?);32671 ptr_opt_val.* = opt_val.?;
33735 continue;32672 continue;
33736 },32673 },
33737 .int => {},32674 .int => {},
...@@ -33924,7 +32861,6 @@ fn resolvePeerTypesInner(...@@ -33924,7 +32861,6 @@ fn resolvePeerTypesInner(
33924 var comptime_val: ?Value = null;32861 var comptime_val: ?Value = null;
33925 for (peer_tys) |opt_ty| {32862 for (peer_tys) |opt_ty| {
33926 const struct_ty = opt_ty orelse continue;32863 const struct_ty = opt_ty orelse continue;
33927 try struct_ty.resolveStructFieldInits(pt);
3392832864
33929 const uncoerced_field_val = try struct_ty.structFieldValueComptime(pt, field_index) orelse {32865 const uncoerced_field_val = try struct_ty.structFieldValueComptime(pt, field_index) orelse {
33930 comptime_val = null;32866 comptime_val = null;
...@@ -33939,2242 +32875,274 @@ fn resolvePeerTypesInner(...@@ -33939,2242 +32875,274 @@ fn resolvePeerTypesInner(
33939 },32875 },
33940 else => |e| return e,32876 else => |e| return e,
33941 };32877 };
33942 const coerced_val = (try sema.resolveValue(coerced_inst)) orelse continue;32878 const coerced_val = sema.resolveValue(coerced_inst) orelse continue;
33943 const existing = comptime_val orelse {32879 const existing = comptime_val orelse {
33944 comptime_val = coerced_val;32880 comptime_val = coerced_val;
33945 continue;32881 continue;
33946 };32882 };
33947 if (!coerced_val.eql(existing, .fromInterned(field_ty.*), zcu)) {32883 if (!coerced_val.eql(existing, .fromInterned(field_ty.*), zcu)) {
33948 comptime_val = null;32884 comptime_val = null;
33949 break;32885 break;
33950 }32886 }
33951 }32887 }
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;
3549432888
35495 const align_ref: Zir.Inst.Ref = if (has_align) blk: {32889 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
35496 const align_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);32890 }
35497 extra_index += 1;
35498 break :blk align_ref;
35499 } else .none;
3550032891
35501 const tag_ref: Air.Inst.Ref = if (has_tag) blk: {32892 const final_ty = try ip.getTupleType(gpa, io, pt.tid, .{
35502 const tag_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);32893 .types = field_types,
35503 extra_index += 1;32894 .values = field_vals,
35504 break :blk try sema.resolveInst(tag_ref);32895 });
35505 } else .none;
3550632896
35507 const name_src: LazySrcLoc = .{32897 return .{ .success = .fromInterned(final_ty) };
35508 .base_node_inst = union_type.zir_index,32898 },
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 };
3552332899
35524 if (enum_field_vals.capacity() > 0) {32900 .exact => {
35525 const enum_tag_val = if (tag_ref != .none) blk: {32901 var expect_ty: ?Type = null;
35526 const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, value_src);32902 var first_idx: usize = undefined;
35527 const val = try sema.resolveConstDefinedValue(&block_scope, value_src, coerced, .{ .simple = .enum_field_tag_value });32903 for (peer_tys, 0..) |opt_ty, i| {
35528 last_tag_val = val;32904 const ty = opt_ty orelse continue;
3552932905 if (expect_ty) |expect| {
35530 break :blk val;32906 if (!ty.eql(expect, zcu)) return .{ .conflict = .{
35531 } else blk: {32907 .peer_idx_a = first_idx,
35532 if (last_tag_val) |last_tag| {32908 .peer_idx_b = i,
35533 const result = try arith.incrementDefinedInt(sema, int_tag_ty, last_tag);32909 } };
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;
35541 } else {32910 } else {
35542 last_tag_val = try pt.intValue(int_tag_ty, 0);32911 expect_ty = ty;
32912 first_idx = i;
35543 }32913 }
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);
35563 }32914 }
35564 }32915 return .{ .success = expect_ty.? };
3556532916 },
35566 // This string needs to outlive the ZIR code.32917 }
35567 const field_name = try ip.getOrPutString(gpa, io, pt.tid, field_name_zir, .no_embedded_nulls);32918}
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 };
3558732919
35588 // No check for duplicate because the check already happened in order32920fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1: Type) !Type {
35589 // to create the enum type in the first place.32921 // e0 -> e1
35590 assert(!explicit_tags_seen[enum_index]);32922 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, e1, e0, src, src)) {
35591 explicit_tags_seen[enum_index] = true;32923 return e1;
32924 }
3559232925
35593 // Enforce the enum fields and the union fields being in the same order.32926 // e1 -> e0
35594 if (enum_index != field_i) {32927 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, e0, e1, src, src)) {
35595 const msg = msg: {32928 return e0;
35596 const enum_field_src: LazySrcLoc = .{32929 }
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 }
3561032930
35611 if (field_ty.zigTypeTag(zcu) == .@"opaque") {32931 return sema.errorSetMerge(e0, e1);
35612 const msg = msg: {32932}
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);
3561532933
35616 try sema.addDeclaredHereNote(msg, field_ty);32934fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {
35617 break :msg msg;32935 const target = sema.pt.zcu.getTarget();
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);
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);32942 // ty_a -> ty_b
35630 break :msg msg;32943 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, false, target, src, src, null)) {
35631 };32944 return ty_b;
35632 return sema.failWithOwnedErrorMsg(&block_scope, msg);32945 }
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);
3563932946
35640 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);32947 return null;
32948}
3564132949
35642 try sema.addDeclaredHereNote(msg, field_ty);32950const ArrayLike = struct {
35643 break :msg msg;32951 len: u64,
35644 };32952 /// `noreturn` indicates that this type is `struct{}` so can coerce to anything
35645 return sema.failWithOwnedErrorMsg(&block_scope, msg);32953 elem_ty: Type,
35646 }32954};
35647 const field_bits = try field_ty.bitSizeSema(pt);32955fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
35648 if (field_bits >= max_bits) {32956 const pt = sema.pt;
35649 max_bits = field_bits;32957 const zcu = pt.zcu;
35650 max_bits_src = type_src;32958 return switch (ty.zigTypeTag(zcu)) {
35651 max_bits_ty = field_ty;32959 .array => .{
35652 }32960 .len = ty.arrayLen(zcu),
35653 if (field_bits <= min_bits) {32961 .elem_ty = ty.childType(zcu),
35654 min_bits = field_bits;32962 },
35655 min_bits_src = type_src;32963 .@"struct" => {
35656 min_bits_ty = field_ty;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;
35657 }32974 }
35658 },32975 }
35659 .auto => {},32976 return .{
35660 }32977 .len = field_count,
3566132978 .elem_ty = elem_ty,
35662 field_types.appendAssumeCapacity(field_ty.toIntern());32979 };
3566332980 },
35664 if (small.any_aligned_fields) {32981 else => null,
35665 field_aligns.appendAssumeCapacity(if (align_ref != .none)32982 };
35666 try sema.resolveAlign(&block_scope, align_src, align_ref)32983}
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);
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)) {
35678 const msg = msg: {32988 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)});
35680 errdefer msg.destroy(sema.gpa);32990 errdefer msg.destroy(sema.gpa);
35681 try sema.errNote(min_bits_src, msg, "{d} bits here", .{min_bits});32991 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
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);
35685 break :msg msg;32992 break :msg msg;
35686 };32993 };
35687 return sema.failWithOwnedErrorMsg(&block_scope, msg);32994 return sema.failWithOwnedErrorMsg(block, msg);
35688 }32995 }
32996}
3568932997
35690 if (explicit_tags_seen.len > 0) {32998fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35691 const tag_ty = union_type.tagTypeUnordered(ip);32999 const pt = sema.pt;
35692 const tag_info = ip.loadEnumType(tag_ty);33000 const zcu = pt.zcu;
35693 if (tag_info.names.len > fields_len) {33001 if (ty.zigTypeTag(zcu) == .pointer) {
35694 const msg = msg: {33002 switch (ty.ptrSize(zcu)) {
35695 const msg = try sema.errMsg(src, "enum field(s) missing in union", .{});33003 .slice, .many, .c => return,
35696 errdefer msg.destroy(sema.gpa);33004 .one => {
3569733005 const elem_ty = ty.childType(zcu);
35698 for (tag_info.names.get(ip), 0..) |field_name, field_index| {33006 if (elem_ty.zigTypeTag(zcu) == .array) return;
35699 if (explicit_tags_seen[field_index]) continue;33007 // TODO https://github.com/ziglang/zig/issues/15479
35700 try sema.addFieldErrNote(.fromInterned(tag_ty), field_index, msg, "field '{f}' missing, declared here", .{33008 // if (elem_ty.isTuple()) return;
35701 field_name.fmt(ip),33009 },
35702 });
35703 }
35704 try sema.addDeclaredHereNote(msg, .fromInterned(tag_ty));
35705 break :msg msg;
35706 };
35707 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35708 }33010 }
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);
35715 }33011 }
3571633012 const msg = msg: {
35717 try sema.flushExports();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);
35718}33019}
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(
35721 sema: *Sema,33027 sema: *Sema,
35722 block: *Block,33028 block: *Block,
35723 enum_field_names: []const InternPool.NullTerminatedString,33029 src: LazySrcLoc,
35724 enum_field_vals: []const InternPool.Index,33030 func_index: InternPool.Index,
35725 union_type: InternPool.Index,33031) CompileError!void {
35726 union_name: InternPool.NullTerminatedString,
35727) !InternPool.Index {
35728 const pt = sema.pt;33032 const pt = sema.pt;
35729 const zcu = pt.zcu;33033 const zcu = pt.zcu;
35730 const comp = zcu.comp;
35731 const gpa = comp.gpa;
35732 const io = comp.io;
35733 const ip = &zcu.intern_pool;33034 const ip = &zcu.intern_pool;
3573433035
35735 const name = try ip.getOrPutStringFmt(33036 assert(ip.unwrapCoercedFunc(func_index) == func_index);
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}
3575933037
35760fn generateUnionTagTypeSimple(33038 try sema.declareDependency(.{ .func_ies = func_index });
35761 sema: *Sema,33039 try sema.addReferenceEntry(block, src, .wrap(.{ .func = func_index }));
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;
3577333040
35774 const name = try ip.getOrPutStringFmt(33041 const reason: Zcu.DependencyReason = .{ .src = src, .type_layout_reason = undefined };
35775 gpa,
35776 io,
35777 pt.tid,
35778 "@typeInfo({f}).@\"union\".tag_type.?",
35779 .{union_name.fmt(ip)},
35780 .no_embedded_nulls,
35781 );
3578233042
35783 const enum_ty = try ip.getGeneratedTagEnumType(gpa, io, pt.tid, .{33043 if (zcu.analysis_in_progress.contains(.wrap(.{ .func = func_index }))) {
35784 .name = name,33044 return sema.failWithDependencyLoop(.wrap(.{ .func = func_index }), &reason);
35785 .owner_union_ty = union_type,33045 }
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 });
3579233046
35793 return enum_ty;33047 try pt.ensureFuncBodyUpToDate(func_index, &reason);
35794}33048}
3579533049
35796/// There is another implementation of this in `Type.onePossibleValue`. This one33050pub fn resolveInferredErrorSetPtr(
35797/// in `Sema` is for calling during semantic analysis, and performs field resolution33051 sema: *Sema,
35798/// to get the answer. The one in `Type` is for calling during codegen and asserts33052 block: *Block,
35799/// that the types are already resolved.33053 src: LazySrcLoc,
35800/// TODO assert the return value matches `ty.onePossibleValue`33054 ies: *InferredErrorSet,
35801pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {33055) CompileError!void {
35802 const pt = sema.pt;33056 const pt = sema.pt;
35803 const zcu = pt.zcu;33057 const ip = &pt.zcu.intern_pool;
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 }
3608033058
36081 const field_vals = try sema.arena.alloc(33059 if (ies.resolved != .none) return;
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 }
3609833060
36099 return try pt.aggregateValue(ty, field_vals);33061 const ies_index = ip.errorUnionSet(sema.fn_ret_ty.toIntern());
36100 },
3610133062
36102 .union_type => {33063 for (ies.inferred_error_sets.keys()) |other_ies_index| {
36103 // Resolving the layout first helps to avoid loops.33064 if (ies_index == other_ies_index) continue;
36104 // If the type has a coherent layout, we can recurse through fields safely.33065 const other_func_index = ip.iesFuncIndex(other_ies_index);
36105 try ty.resolveLayout(pt);33066 try sema.ensureFuncIesResolved(block, src, other_func_index);
3610633067 switch (ip.funcIesResolvedUnordered(other_func_index)) {
36107 const union_obj = ip.loadUnionType(ty.toIntern());33068 .anyerror_type => {
36108 const tag_val = (try sema.typeHasOnePossibleValue(.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse33069 ies.resolved = .anyerror_type;
36109 return null;33070 return;
36110 if (union_obj.field_types.len == 0) {33071 },
36111 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });33072 else => |error_set_ty_index| {
36112 return Value.fromInterned(only);33073 const names = ip.indexToKey(error_set_ty_index).error_set_type.names;
36113 }33074 for (names.get(ip)) |name| {
36114 const only_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[0]);33075 try ies.errors.put(sema.arena, name, {});
36115 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse33076 }
36116 return null;33077 },
36117 const only = try pt.internUnion(.{33078 }
36118 .ty = ty.toIntern(),33079 }
36119 .tag = tag_val.toIntern(),
36120 .val = val_val.toIntern(),
36121 });
36122 return Value.fromInterned(only);
36123 },
3612433080
36125 .enum_type => {33081 const resolved_error_set_ty = try pt.errorSetFromUnsortedNames(ies.errors.keys());
36126 const enum_type = ip.loadEnumType(ty.toIntern());33082 ies.resolved = resolved_error_set_ty.toIntern();
36127 switch (enum_type.tag_mode) {33083}
36128 .nonexhaustive => {
36129 if (enum_type.tag_ty == .comptime_int_type) return null;
3613033084
36131 if (try sema.typeHasOnePossibleValue(.fromInterned(enum_type.tag_ty))) |int_opv| {33085fn resolveAdHocInferredErrorSet(
36132 const only = try pt.intern(.{ .enum_tag = .{33086 sema: *Sema,
36133 .ty = ty.toIntern(),33087 block: *Block,
36134 .int = int_opv.toIntern(),33088 src: LazySrcLoc,
36135 } });33089 value: InternPool.Index,
36136 return Value.fromInterned(only);33090) CompileError!InternPool.Index {
36137 }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;33098 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));
36140 },33099 if (new_ty == .none) return value;
36141 .auto, .explicit => {33100 return ip.getCoerced(gpa, io, pt.tid, value, new_ty);
36142 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;33101}
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 },
3616433102
36165 else => unreachable,33103fn resolveAdHocInferredErrorSetTy(
36166 },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 => {33120 try sema.resolveInferredErrorSetPtr(block, src, ies);
36169 const payload_ip = ip.indexToKey(ty.toIntern()).opt_type;33121 const new_ty = try pt.intern(.{ .error_union_type = .{
36170 // Although ?noreturn is handled above, the element type33122 .error_set_type = ies.resolved,
36171 // can be effectively noreturn for example via an empty33123 .payload_type = error_union_info.payload_type,
36172 // enum or error set.33124 } });
36173 if (ip.isNoReturn(payload_ip)) return try pt.nullValue(ty);33125 return new_ty;
36174 return null;33126}
36175 },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);
36176 },33143 },
36177 };33144 else => unreachable,
33145 }
36178}33146}
3617933147
36180/// Returns the type of the AIR instruction.33148/// Returns the type of the AIR instruction.
...@@ -36232,9 +33200,10 @@ fn isComptimeKnown(...@@ -36232,9 +33200,10 @@ fn isComptimeKnown(
36232 sema: *Sema,33200 sema: *Sema,
36233 inst: Air.Inst.Ref,33201 inst: Air.Inst.Ref,
36234) !bool {33202) !bool {
36235 return (try sema.resolveValue(inst)) != null;33203 return sema.resolveValue(inst) != null;
36236}33204}
3623733205
33206/// Asserts that the layout of `var_type` has already been resolved.
36238fn analyzeComptimeAlloc(33207fn analyzeComptimeAlloc(
36239 sema: *Sema,33208 sema: *Sema,
36240 block: *Block,33209 block: *Block,
...@@ -36245,10 +33214,9 @@ fn analyzeComptimeAlloc(...@@ -36245,10 +33214,9 @@ fn analyzeComptimeAlloc(
36245 const pt = sema.pt;33214 const pt = sema.pt;
36246 const zcu = pt.zcu;33215 const zcu = pt.zcu;
3624733216
36248 // Needed to make an anon decl with type `var_type` (the `finish()` call below).33217 var_type.assertHasLayout(zcu);
36249 _ = try sema.typeHasOnePossibleValue(var_type);
3625033218
36251 const ptr_type = try pt.ptrTypeSema(.{33219 const ptr_type = try pt.ptrType(.{
36252 .child = var_type.toIntern(),33220 .child = var_type.toIntern(),
36253 .flags = .{33221 .flags = .{
36254 .alignment = alignment,33222 .alignment = alignment,
...@@ -36256,13 +33224,23 @@ fn analyzeComptimeAlloc(...@@ -36256,13 +33224,23 @@ fn analyzeComptimeAlloc(
36256 },33224 },
36257 });33225 });
3625833226
36259 const alloc = try sema.newComptimeAlloc(block, src, var_type, alignment);33227 if (try var_type.onePossibleValue(pt)) |opv| {
3626033228 return .fromIntern(try pt.intern(.{ .ptr = .{
36261 return Air.internedToRef((try pt.intern(.{ .ptr = .{33229 .ty = ptr_type.toIntern(),
36262 .ty = ptr_type.toIntern(),33230 .base_addr = .{ .uav = .{
36263 .base_addr = .{ .comptime_alloc = alloc },33231 .val = opv.toIntern(),
36264 .byte_offset = 0,33232 .orig_ty = ptr_type.toIntern(),
36265 } })));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 }
36266}33244}
3626733245
36268fn resolveAddressSpace(33246fn resolveAddressSpace(
...@@ -36272,7 +33250,7 @@ fn resolveAddressSpace(...@@ -36272,7 +33250,7 @@ fn resolveAddressSpace(
36272 zir_ref: Zir.Inst.Ref,33250 zir_ref: Zir.Inst.Ref,
36273 ctx: std.Target.AddressSpaceContext,33251 ctx: std.Target.AddressSpaceContext,
36274) !std.builtin.AddressSpace {33252) !std.builtin.AddressSpace {
36275 const air_ref = try sema.resolveInst(zir_ref);33253 const air_ref = sema.resolveInst(zir_ref);
36276 return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);33254 return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
36277}33255}
3627833256
...@@ -36363,40 +33341,7 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError...@@ -36363,40 +33341,7 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError
36363 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});33341 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});
36364}33342}
3636533343
36366/// For pointer-like optionals, it returns the pointer type. For pointers,33344/// Asserts that the layout of `union_ty` is already resolved.
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
36400fn unionFieldIndex(33345fn unionFieldIndex(
36401 sema: *Sema,33346 sema: *Sema,
36402 block: *Block,33347 block: *Block,
...@@ -36407,13 +33352,14 @@ fn unionFieldIndex(...@@ -36407,13 +33352,14 @@ fn unionFieldIndex(
36407 const pt = sema.pt;33352 const pt = sema.pt;
36408 const zcu = pt.zcu;33353 const zcu = pt.zcu;
36409 const ip = &zcu.intern_pool;33354 const ip = &zcu.intern_pool;
36410 try union_ty.resolveFields(pt);
36411 const union_obj = zcu.typeToUnion(union_ty).?;33355 const union_obj = zcu.typeToUnion(union_ty).?;
36412 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse33356 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
33357 const field_index = enum_obj.nameIndex(ip, field_name) orelse
36413 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);33358 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
36414 return @intCast(field_index);33359 return @intCast(field_index);
36415}33360}
3641633361
33362/// Asserts that the layout of `struct_ty` is already resolved.
36417fn structFieldIndex(33363fn structFieldIndex(
36418 sema: *Sema,33364 sema: *Sema,
36419 block: *Block,33365 block: *Block,
...@@ -36424,7 +33370,6 @@ fn structFieldIndex(...@@ -36424,7 +33370,6 @@ fn structFieldIndex(
36424 const pt = sema.pt;33370 const pt = sema.pt;
36425 const zcu = pt.zcu;33371 const zcu = pt.zcu;
36426 const ip = &zcu.intern_pool;33372 const ip = &zcu.intern_pool;
36427 try struct_ty.resolveFields(pt);
36428 const struct_type = zcu.typeToStruct(struct_ty).?;33373 const struct_type = zcu.typeToStruct(struct_ty).?;
36429 return struct_type.nameIndex(ip, field_name) orelse33374 return struct_type.nameIndex(ip, field_name) orelse
36430 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);33375 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);
...@@ -36509,102 +33454,25 @@ fn intFromFloatScalar(...@@ -36509,102 +33454,25 @@ fn intFromFloatScalar(
36509 return pt.getCoerced(cti_result, int_ty);33454 return pt.getCoerced(cti_result, int_ty);
36510}33455}
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
36589fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {33457fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
36590 const pt = sema.pt;33458 const pt = sema.pt;
36591 if (!(try int_val.compareAllWithZeroSema(.gte, pt))) return false;33459 if (!int_val.compareAllWithZero(.gte, pt.zcu)) return false;
36592 const end_val = try pt.intValue(tag_ty, end);33460 const end_val = try pt.intValue(tag_ty, end);
36593 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;33461 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
36594 return true;33462 return true;
36595}33463}
3659633464
36597/// Asserts the type is an enum.33465/// Asserts the type is an exhaustive enum.
36598fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {33466fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
36599 const pt = sema.pt;33467 const pt = sema.pt;
36600 const zcu = pt.zcu;33468 const zcu = pt.zcu;
36601 const enum_type = zcu.intern_pool.loadEnumType(ty.toIntern());33469 const enum_type = zcu.intern_pool.loadEnumType(ty.toIntern());
36602 assert(enum_type.tag_mode != .nonexhaustive);33470 assert(!enum_type.nonexhaustive);
36603 // The `tagValueIndex` function call below relies on the type being the integer tag type.33471 // The `tagValueIndex` function call below relies on the type being the integer tag type.
36604 // `getCoerced` assumes the value will fit the new type.33472 // `getCoerced` assumes the value will fit the new type.
36605 if (!(try sema.intFitsInType(int, .fromInterned(enum_type.tag_ty), null))) return false;33473 const int_tag_ty: Type = .fromInterned(enum_type.int_tag_type);
36606 const int_coerced = try pt.getCoerced(int, .fromInterned(enum_type.tag_ty));33474 if (!int.intFitsInType(int_tag_ty, null, zcu)) return false;
3660733475 const int_coerced = try pt.getCoerced(int, int_tag_ty);
36608 return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null;33476 return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null;
36609}33477}
3661033478
...@@ -36644,17 +33512,19 @@ fn compareScalar(...@@ -36644,17 +33512,19 @@ fn compareScalar(
36644 ty: Type,33512 ty: Type,
36645) CompileError!bool {33513) CompileError!bool {
36646 const pt = sema.pt;33514 const pt = sema.pt;
33515 const zcu = pt.zcu;
33516
36647 const coerced_lhs = try pt.getCoerced(lhs, ty);33517 const coerced_lhs = try pt.getCoerced(lhs, ty);
36648 const coerced_rhs = try pt.getCoerced(rhs, ty);33518 const coerced_rhs = try pt.getCoerced(rhs, ty);
3664933519
36650 // Equality comparisons of signed zero and NaN need to use floating point semantics33520 // 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))33521 if (coerced_lhs.isFloat(zcu) or coerced_rhs.isFloat(zcu))
36652 return Value.compareHeteroSema(coerced_lhs, op, coerced_rhs, pt);33522 return Value.compareHetero(coerced_lhs, op, coerced_rhs, zcu);
3665333523
36654 switch (op) {33524 switch (op) {
36655 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),33525 .eq => return Value.eql(coerced_lhs, coerced_rhs, ty, zcu),
36656 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),33526 .neq => return !Value.eql(coerced_lhs, coerced_rhs, ty, zcu),
36657 else => return Value.compareHeteroSema(coerced_lhs, op, coerced_rhs, pt),33527 else => return Value.compareHetero(coerced_lhs, op, coerced_rhs, zcu),
36658 }33528 }
36659}33529}
3666033530
...@@ -36716,25 +33586,6 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {...@@ -36716,25 +33586,6 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
36716 return pt.errorSetFromUnsortedNames(names.keys());33586 return pt.errorSetFromUnsortedNames(names.keys());
36717}33587}
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
36738pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {33589pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
36739 const pt = sema.pt;33590 const pt = sema.pt;
36740 if (!pt.zcu.comp.config.incremental) return;33591 if (!pt.zcu.comp.config.incremental) return;
...@@ -36742,23 +33593,6 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {...@@ -36742,23 +33593,6 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
36742 const gop = try sema.dependencies.getOrPut(sema.gpa, dependee);33593 const gop = try sema.dependencies.getOrPut(sema.gpa, dependee);
36743 if (gop.found_existing) return;33594 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
36762 try pt.addDependency(sema.owner, dependee);33596 try pt.addDependency(sema.owner, dependee);
36763}33597}
3676433598
...@@ -36799,7 +33633,7 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai...@@ -36799,7 +33633,7 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai
36799 });33633 });
36800}33634}
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 {
36803 return sema.failWithOwnedErrorMsg(block, msg: {33637 return sema.failWithOwnedErrorMsg(block, msg: {
36804 const msg = try sema.errMsg(src, "{s} contains reference to comptime var", .{kind_of_value});33638 const msg = try sema.errMsg(src, "{s} contains reference to comptime var", .{kind_of_value});
36805 errdefer msg.destroy(sema.gpa);33639 errdefer msg.destroy(sema.gpa);
...@@ -36867,11 +33701,7 @@ fn notePathToComptimeAllocPtr(...@@ -36867,11 +33701,7 @@ fn notePathToComptimeAllocPtr(
36867 else => {}, // there will be another stage33701 else => {}, // there will be another stage
36868 }33702 }
3686933703
36870 const derivation = comptime_ptr.pointerDerivationAdvanced(arena, pt, false, sema) catch |err| switch (err) {33704 const derivation = try comptime_ptr.pointerDerivation(arena, pt, sema);
36871 error.OutOfMemory => |e| return e,
36872 error.Canceled => @panic("TODO"), // pls don't be cancelable mlugg
36873 error.AnalysisFail => unreachable,
36874 };
3687533705
36876 var second_path_aw: std.Io.Writer.Allocating = .init(arena);33706 var second_path_aw: std.Io.Writer.Allocating = .init(arena);
36877 defer second_path_aw.deinit();33707 defer second_path_aw.deinit();
...@@ -36983,7 +33813,6 @@ fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {...@@ -36983,7 +33813,6 @@ fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {
36983 const zcu = pt.zcu;33813 const zcu = pt.zcu;
36984 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {33814 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
36985 .undef => true,33815 .undef => true,
36986 .simple_value => |v| v == .undefined,
36987 .slice => {33816 .slice => {
36988 // If the slice contents are runtime-known, reification will fail later on with a33817 // If the slice contents are runtime-known, reification will fail later on with a
36989 // specific error message.33818 // specific error message.
...@@ -37058,12 +33887,12 @@ fn maybeDerefSliceAsArray(...@@ -37058,12 +33887,12 @@ fn maybeDerefSliceAsArray(
37058 else => unreachable,33887 else => unreachable,
37059 };33888 };
37060 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);33889 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);
37062 const array_ty = try pt.arrayType(.{33891 const array_ty = try pt.arrayType(.{
37063 .child = elem_ty.toIntern(),33892 .child = elem_ty.toIntern(),
37064 .len = len,33893 .len = len,
37065 });33894 });
37066 const ptr_ty = try pt.ptrTypeSema(p: {33895 const ptr_ty = try pt.ptrType(p: {
37067 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);33896 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);
37068 p.flags.size = .one;33897 p.flags.size = .one;
37069 p.child = array_ty.toIntern();33898 p.child = array_ty.toIntern();
...@@ -37097,19 +33926,9 @@ pub fn flushExports(sema: *Sema) !void {...@@ -37097,19 +33926,9 @@ pub fn flushExports(sema: *Sema) !void {
37097 const zcu = sema.pt.zcu;33926 const zcu = sema.pt.zcu;
37098 const gpa = zcu.gpa;33927 const gpa = zcu.gpa;
3709933928
37100 // There may be existing exports. For instance, a struct may export33929 assert(!zcu.single_exports.contains(sema.owner));
37101 // things during both field type resolution and field default resolution.33930 assert(!zcu.multi_exports.contains(sema.owner));
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);
3711133931
37112 // `sema.exports` is completed; store the data into the `Zcu`.
37113 if (sema.exports.items.len == 1) {33932 if (sema.exports.items.len == 1) {
37114 try zcu.single_exports.ensureUnusedCapacity(gpa, 1);33933 try zcu.single_exports.ensureUnusedCapacity(gpa, 1);
37115 const export_idx: Zcu.Export.Index = zcu.free_exports.pop() orelse idx: {33934 const export_idx: Zcu.Export.Index = zcu.free_exports.pop() orelse idx: {
...@@ -37129,238 +33948,6 @@ pub fn flushExports(sema: *Sema) !void {...@@ -37129,238 +33948,6 @@ pub fn flushExports(sema: *Sema) !void {
37129 }33948 }
37130}33949}
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
37364pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;33951pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;
37365pub const bitCastSpliceVal = @import("Sema/bitcast.zig").bitCastSplice;33952pub const bitCastSpliceVal = @import("Sema/bitcast.zig").bitCastSplice;
3736633953
...@@ -37369,6 +33956,10 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR...@@ -37369,6 +33956,10 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
37369const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;33956const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
37370const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;33957const 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
37372pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!Type {33963pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!Type {
37373 assert(decl.kind() == .type);33964 assert(decl.kind() == .type);
37374 try sema.ensureMemoizedStateResolved(src, decl.stage());33965 try sema.ensureMemoizedStateResolved(src, decl.stage());
...@@ -37448,62 +34039,95 @@ pub fn resolveNavPtrModifiers(...@@ -37448,62 +34039,95 @@ pub fn resolveNavPtrModifiers(
37448 };34039 };
37449}34040}
3745034041
37451pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc, builtin_namespace: InternPool.NamespaceIndex, stage: InternPool.MemoizedStateStage) CompileError!bool {34042pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) CompileError!bool {
37452 const pt = sema.pt;34043 const pt = sema.pt;
37453 const zcu = pt.zcu;34044 const zcu = pt.zcu;
37454 const comp = zcu.comp;34045 const comp = zcu.comp;
37455 const gpa = comp.gpa;34046 const gpa = comp.gpa;
37456 const io = comp.io;34047 const io = comp.io;
37457 const ip = &zcu.intern_pool;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
37459 var any_changed = false;34085 var any_changed = false;
3746034086
37461 inline for (comptime std.enums.values(Zcu.BuiltinDecl)) |builtin_decl| {34087 inline for (comptime std.enums.values(Zcu.BuiltinDecl)) |builtin_decl| {
37462 if (stage == comptime builtin_decl.stage()) {34088 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()) {34089 const parent_ns_ty: Type, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) {
37464 .direct => |name| .{ builtin_namespace, "std.builtin", name },34090 .direct => |name| .{ std_builtin_ty, "std.builtin", name },
37465 .nested => |nested| access: {34091 .nested => |nested| access: {
37466 const parent_ty: Type = .fromInterned(zcu.builtin_decl_values.get(nested[0]));34092 const parent_decl, const name = nested;
37467 const parent_ns = parent_ty.getNamespace(zcu).unwrap() orelse {34093 const parent_ty: Type = .fromInterned(zcu.builtin_decl_values.get(parent_decl));
37468 return sema.fail(block, simple_src, "std.builtin.{s} is not a container type", .{@tagName(nested[0])});34094 break :access .{ parent_ty, "std.builtin." ++ @tagName(parent_decl), name };
37469 };
37470 break :access .{ parent_ns, "std.builtin." ++ @tagName(nested[0]), nested[1] };
37471 },34095 },
37472 };34096 };
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);
37474 const name_nts = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);34102 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) orelse34103 const nav = try sema.namespaceLookup(&block, parent_ty_src, parent_ns, name_nts) orelse {
37476 return sema.fail(block, simple_src, "{s} missing {s}", .{ parent_name, name });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 = .{
37479 .base_node_inst = ip.getNav(nav).srcInst(ip),34109 .base_node_inst = ip.getNav(nav).srcInst(ip),
37480 .offset = .nodeOffset(.zero),34110 .offset = .nodeOffset(.zero),
37481 };34111 };
3748234112
37483 const result = try sema.analyzeNavVal(block, src, nav);34113 const val: Value = switch (builtin_decl.kind()) {
3748434114 .type => val: {
37485 const uncoerced_val = try sema.resolveConstDefinedValue(block, src, result, null);34115 const ty = try sema.analyzeAsType(&block, decl_src, .std_builtin_decl, uncoerced_val);
37486 const maybe_lazy_val: Value = switch (builtin_decl.kind()) {34116 try sema.ensureLayoutResolved(ty, decl_src, .builtin_type);
37487 .type => if (uncoerced_val.typeOf(zcu).zigTypeTag(zcu) != .type) {34117 break :val ty.toValue();
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;
37492 },34118 },
37493 .func => val: {34119 .func => val: {
37494 const func_ty = try sema.getExpectedBuiltinFnType(builtin_decl);34120 const func_ty = try sema.getExpectedBuiltinFnType(builtin_decl);
37495 const coerced = try sema.coerce(block, func_ty, Air.internedToRef(uncoerced_val.toIntern()), src);34121 const coerced = try sema.coerce(&block, func_ty, uncoerced_val, decl_src);
37496 break :val .fromInterned(coerced.toInterned().?);34122 break :val try sema.resolveConstDefinedValue(&block, decl_src, coerced, .{ .simple = .std_builtin_decl });
37497 },34123 },
37498 .string => val: {34124 .string => val: {
37499 const coerced = try sema.coerce(block, .slice_const_u8, Air.internedToRef(uncoerced_val.toIntern()), src);34125 const coerced = try sema.coerce(&block, .slice_const_u8, uncoerced_val, decl_src);
37500 break :val .fromInterned(coerced.toInterned().?);34126 break :val try sema.resolveConstDefinedValue(&block, decl_src, coerced, .{ .simple = .std_builtin_decl });
37501 },34127 },
37502 };34128 };
37503 const val = try sema.resolveLazyValue(maybe_lazy_val);
3750434129
37505 const prev = zcu.builtin_decl_values.get(builtin_decl);34130 if (zcu.builtin_decl_values.get(builtin_decl) != val.toIntern()) {
37506 if (val.toIntern() != prev) {
37507 zcu.builtin_decl_values.set(builtin_decl, val.toIntern());34131 zcu.builtin_decl_values.set(builtin_decl, val.toIntern());
37508 any_changed = true;34132 any_changed = true;
37509 }34133 }
...@@ -37539,7 +34163,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ...@@ -37539,7 +34163,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ
37539 => try pt.funcType(.{34163 => try pt.funcType(.{
37540 .param_types = &.{ .generic_poison_type, .generic_poison_type },34164 .param_types = &.{ .generic_poison_type, .generic_poison_type },
37541 .return_type = .noreturn_type,34165 .return_type = .noreturn_type,
37542 .is_generic = true,
37543 }),34166 }),
3754434167
37545 // `fn (anyerror) noreturn`34168 // `fn (anyerror) noreturn`
...@@ -37590,3 +34213,372 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ...@@ -37590,3 +34213,372 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ
37590 else => unreachable,34213 else => unreachable,
37591 };34214 };
37592}34215}
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...@@ -129,84 +129,73 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
129 for (0..init.names.len) |i| {129 for (0..init.names.len) |i| {
130 elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));130 elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
131 }131 }
132 const struct_ty = switch (try ip.getStructType(132 const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
133 gpa,133 .zir_index = self.base_node_inst,
134 io,134 .type_hash = hash: {
135 pt.tid,135 var hasher: std.hash.Wyhash = .init(0);
136 .{136 hasher.update(std.mem.asBytes(&node));
137 .layout = .auto,137 hasher.update(std.mem.sliceAsBytes(elems));
138 .fields_len = @intCast(init.names.len),138 hasher.update(std.mem.sliceAsBytes(init.names));
139 .known_non_opv = false,139 break :hash hasher.final();
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 } },
155 },140 },
156 false,141 .fields_len = @intCast(init.names.len),
157 )) {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),
158 .wip => |wip| ty: {149 .wip => |wip| ty: {
159 errdefer wip.cancel(ip, pt.tid);150 errdefer wip.cancel(ip, pt.tid);
160 const type_name = try self.sema.createTypeName(151 const block = self.block;
161 self.block,152 const zcu = pt.zcu;
162 .anon,153 try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?);
163 "struct",154
164 self.base_node_inst.resolve(ip),155 // Reified structs have field information populated immediately.
165 wip.index,156 @memcpy(wip.field_values.get(ip), elems);
166 );157 if (init.names.len > 0) {
167 wip.setName(ip, type_name.name, type_name.nav);158 // All fields are comptime, but unused bits remain zeroed.
168159 const unused_bits = switch (init.names.len % 32) {
169 const struct_type = ip.loadStructType(wip.index);160 0 => 0,
170161 else => |n| 32 - n,
171 for (init.names, 0..) |name, field_idx| {162 };
172 const name_interned = try ip.getOrPutString(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(
173 gpa,174 gpa,
174 io,175 io,
175 pt.tid,176 pt.tid,
176 name.get(self.file.zoir.?),177 zoir_name.get(self.file.zoir.?),
177 .no_embedded_nulls,178 .no_embedded_nulls,
178 );179 );
179 assert(struct_type.addFieldName(ip, name_interned) == null);180 field_ty.* = ip.typeOf(field_val);
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();
187 }181 }
188182
189 const new_namespace_index = try pt.createNamespace(.{183 const new_namespace_index = try pt.createNamespace(.{
190 .parent = self.block.namespace.toOptional(),184 .parent = block.namespace.toOptional(),
191 .owner_type = wip.index,185 .owner_type = wip.index,
192 .file_scope = self.block.getFileScopeIndex(pt.zcu),186 .file_scope = block.getFileScopeIndex(zcu),
193 .generation = pt.zcu.generation,187 .generation = zcu.generation,
194 });188 });
195 try pt.zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });189 errdefer pt.destroyNamespace(new_namespace_index);
196 codegen_type: {190 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
197 if (pt.zcu.comp.config.use_llvm) break :codegen_type;191 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
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);
203 },192 },
204 .existing => |ty| ty,
205 };193 };
206 try self.sema.declareDependency(.{ .interned = struct_ty });
207 try self.sema.addTypeReferenceEntry(self.nodeSrc(node), struct_ty);194 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();
210 },199 },
211 }200 }
212}201}
...@@ -299,7 +288,7 @@ fn checkTypeInner(...@@ -299,7 +288,7 @@ fn checkTypeInner(
299 } else {288 } else {
300 const gop = try visited.getOrPut(sema.arena, ty.toIntern());289 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
301 if (gop.found_existing) return;290 if (gop.found_existing) return;
302 try ty.resolveFields(pt);291 try sema.ensureLayoutResolved(ty, self.import_loc, .init);
303 const struct_info = zcu.typeToStruct(ty).?;292 const struct_info = zcu.typeToStruct(ty).?;
304 for (struct_info.field_types.get(ip)) |field_type| {293 for (struct_info.field_types.get(ip)) |field_type| {
305 try self.checkTypeInner(.fromInterned(field_type), null, visited);294 try self.checkTypeInner(.fromInterned(field_type), null, visited);
...@@ -308,7 +297,7 @@ fn checkTypeInner(...@@ -308,7 +297,7 @@ fn checkTypeInner(
308 .@"union" => {297 .@"union" => {
309 const gop = try visited.getOrPut(sema.arena, ty.toIntern());298 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
310 if (gop.found_existing) return;299 if (gop.found_existing) return;
311 try ty.resolveFields(pt);300 try sema.ensureLayoutResolved(ty, self.import_loc, .init);
312 const union_info = zcu.typeToUnion(ty).?;301 const union_info = zcu.typeToUnion(ty).?;
313 for (union_info.field_types.get(ip)) |field_type| {302 for (union_info.field_types.get(ip)) |field_type| {
314 if (field_type != .void_type) {303 if (field_type != .void_type) {
...@@ -645,6 +634,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I...@@ -645,6 +634,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
645 const gpa = comp.gpa;634 const gpa = comp.gpa;
646 const io = comp.io;635 const io = comp.io;
647 const ip = &pt.zcu.intern_pool;636 const ip = &pt.zcu.intern_pool;
637 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
648 switch (node.get(self.file.zoir.?)) {638 switch (node.get(self.file.zoir.?)) {
649 .enum_literal => |field_name| {639 .enum_literal => |field_name| {
650 const field_name_interned = try ip.getOrPutString(640 const field_name_interned = try ip.getOrPutString(
...@@ -767,8 +757,8 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool...@@ -767,8 +757,8 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
767 const io = comp.io;757 const io = comp.io;
768 const ip = &pt.zcu.intern_pool;758 const ip = &pt.zcu.intern_pool;
769759
770 try res_ty.resolveFields(self.sema.pt);760 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
771 try res_ty.resolveStructFieldInits(self.sema.pt);761 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_loc);
772 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;762 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;
773763
774 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {764 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...@@ -779,7 +769,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
779769
780 const field_values = try self.sema.arena.alloc(InternPool.Index, struct_info.field_names.len);770 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);
783 if (field_defaults.len > 0) {773 if (field_defaults.len > 0) {
784 @memcpy(field_values, field_defaults);774 @memcpy(field_values, field_defaults);
785 } else {775 } else {
...@@ -803,7 +793,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool...@@ -803,7 +793,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
803 const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);793 const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);
804 field_values[name_index] = try self.lowerExprKnownResTy(field_node, field_type);794 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)) {
807 const val = ip.indexToKey(field_values[name_index]);797 const val = ip.indexToKey(field_values[name_index]);
808 const default = ip.indexToKey(field_defaults[name_index]);798 const default = ip.indexToKey(field_defaults[name_index]);
809 if (!val.eql(default, ip)) {799 if (!val.eql(default, ip)) {
...@@ -918,9 +908,9 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -918,9 +908,9 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
918 const gpa = comp.gpa;908 const gpa = comp.gpa;
919 const io = comp.io;909 const io = comp.io;
920 const ip = &pt.zcu.intern_pool;910 const ip = &pt.zcu.intern_pool;
921 try res_ty.resolveFields(self.sema.pt);911 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
922 const union_info = self.sema.pt.zcu.typeToUnion(res_ty).?;912 const union_info = pt.zcu.typeToUnion(res_ty).?;
923 const enum_tag_info = union_info.loadTagType(ip);913 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);
924914
925 const field_name, const maybe_field_node = switch (node.get(self.file.zoir.?)) {915 const field_name, const maybe_field_node = switch (node.get(self.file.zoir.?)) {
926 .enum_literal => |name| b: {916 .enum_literal => |name| b: {
...@@ -956,7 +946,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -956,7 +946,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
956 const name_index = enum_tag_info.nameIndex(ip, field_name) orelse {946 const name_index = enum_tag_info.nameIndex(ip, field_name) orelse {
957 return error.WrongType;947 return error.WrongType;
958 };948 };
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);
960 const field_type: Type = .fromInterned(union_info.field_types.get(ip)[name_index]);950 const field_type: Type = .fromInterned(union_info.field_types.get(ip)[name_index]);
961 const val = if (maybe_field_node) |field_node| b: {951 const val = if (maybe_field_node) |field_node| b: {
962 if (field_type.toIntern() == .void_type) {952 if (field_type.toIntern() == .void_type) {
src/Sema/arith.zig+23-19
...@@ -20,6 +20,9 @@ pub fn incrementDefinedInt(...@@ -20,6 +20,9 @@ pub fn incrementDefinedInt(
20 const zcu = pt.zcu;20 const zcu = pt.zcu;
21 assert(prev_val.typeOf(zcu).toIntern() == ty.toIntern());21 assert(prev_val.typeOf(zcu).toIntern() == ty.toIntern());
22 assert(!prev_val.isUndef(zcu));22 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 }
23 const res = try intAdd(sema, prev_val, try pt.intValue(ty, 1), ty);26 const res = try intAdd(sema, prev_val, try pt.intValue(ty, 1), ty);
24 return .{ .overflow = res.overflow, .val = res.val };27 return .{ .overflow = res.overflow, .val = res.val };
25}28}
...@@ -1053,7 +1056,7 @@ fn shlScalar(...@@ -1053,7 +1056,7 @@ fn shlScalar(
1053 if (rhs_val.isUndef(zcu)) return rhs_val;1056 if (rhs_val.isUndef(zcu)) return rhs_val;
1054 },1057 },
1055 }1058 }
1056 switch (try rhs_val.orderAgainstZeroSema(pt)) {1059 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
1057 .gt => {},1060 .gt => {},
1058 .eq => return lhs_val,1061 .eq => return lhs_val,
1059 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),1062 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),
...@@ -1090,7 +1093,7 @@ fn shlWithOverflowScalar(...@@ -1090,7 +1093,7 @@ fn shlWithOverflowScalar(
1090 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);1093 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);
1091 if (rhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, vec_idx);1094 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)) {
1094 .gt => {},1097 .gt => {},
1095 .eq => return .{ .overflow_bit = .zero_u1, .wrapped_result = lhs_val },1098 .eq => return .{ .overflow_bit = .zero_u1, .wrapped_result = lhs_val },
1096 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),1099 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),
...@@ -1169,7 +1172,7 @@ fn shrScalar(...@@ -1169,7 +1172,7 @@ fn shrScalar(
1169 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);1172 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);
1170 if (rhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, vec_idx);1173 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)) {
1173 .gt => {},1176 .gt => {},
1174 .eq => return lhs_val,1177 .eq => return lhs_val,
1175 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),1178 .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...@@ -1430,8 +1433,8 @@ fn intAddWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value
1430 const info = ty.intInfo(zcu);1433 const info = ty.intInfo(zcu);
1431 var lhs_space: Value.BigIntSpace = undefined;1434 var lhs_space: Value.BigIntSpace = undefined;
1432 var rhs_space: Value.BigIntSpace = undefined;1435 var rhs_space: Value.BigIntSpace = undefined;
1433 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);1436 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1434 const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt);1437 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);
1435 const limbs = try sema.arena.alloc(1438 const limbs = try sema.arena.alloc(
1436 std.math.big.Limb,1439 std.math.big.Limb,
1437 std.math.big.int.calcTwosCompLimbCount(info.bits),1440 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -1512,8 +1515,8 @@ fn intSubWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value...@@ -1512,8 +1515,8 @@ fn intSubWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value
1512 const info = ty.intInfo(zcu);1515 const info = ty.intInfo(zcu);
1513 var lhs_space: Value.BigIntSpace = undefined;1516 var lhs_space: Value.BigIntSpace = undefined;
1514 var rhs_space: Value.BigIntSpace = undefined;1517 var rhs_space: Value.BigIntSpace = undefined;
1515 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);1518 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1516 const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt);1519 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);
1517 const limbs = try sema.arena.alloc(1520 const limbs = try sema.arena.alloc(
1518 std.math.big.Limb,1521 std.math.big.Limb,
1519 std.math.big.int.calcTwosCompLimbCount(info.bits),1522 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -1597,8 +1600,8 @@ fn intMulWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value...@@ -1597,8 +1600,8 @@ fn intMulWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value
1597 const info = ty.intInfo(zcu);1600 const info = ty.intInfo(zcu);
1598 var lhs_space: Value.BigIntSpace = undefined;1601 var lhs_space: Value.BigIntSpace = undefined;
1599 var rhs_space: Value.BigIntSpace = undefined;1602 var rhs_space: Value.BigIntSpace = undefined;
1600 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);1603 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1601 const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt);1604 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);
1602 const limbs = try sema.arena.alloc(1605 const limbs = try sema.arena.alloc(
1603 std.math.big.Limb,1606 std.math.big.Limb,
1604 lhs_bigint.limbs.len + rhs_bigint.limbs.len,1607 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -1840,7 +1843,7 @@ fn intShl(...@@ -1840,7 +1843,7 @@ fn intShl(
1840 var lhs_space: Value.BigIntSpace = undefined;1843 var lhs_space: Value.BigIntSpace = undefined;
1841 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);1844 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));
1844 if (shift_amt >= info.bits) {1847 if (shift_amt >= info.bits) {
1845 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);1848 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);
1846 }1849 }
...@@ -1862,7 +1865,7 @@ fn intShlSat(...@@ -1862,7 +1865,7 @@ fn intShlSat(
1862 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);1865 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
18631866
1864 const shift_amt: usize = amt: {1867 const shift_amt: usize = amt: {
1865 if (try rhs.getUnsignedIntSema(pt)) |shift_amt_u64| {1868 if (rhs.getUnsignedInt(zcu)) |shift_amt_u64| {
1866 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| break :amt shift_amt;1869 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| break :amt shift_amt;
1867 }1870 }
1868 // We only support ints with up to 2^16 - 1 bits, so this1871 // We only support ints with up to 2^16 - 1 bits, so this
...@@ -1895,9 +1898,9 @@ fn intShlWithOverflow(...@@ -1895,9 +1898,9 @@ fn intShlWithOverflow(
1895 const info = lhs_ty.intInfo(zcu);1898 const info = lhs_ty.intInfo(zcu);
18961899
1897 var lhs_space: Value.BigIntSpace = undefined;1900 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));
1901 if (shift_amt >= info.bits) {1904 if (shift_amt >= info.bits) {
1902 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);1905 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);
1903 }1906 }
...@@ -1924,9 +1927,10 @@ fn comptimeIntShl(...@@ -1924,9 +1927,10 @@ fn comptimeIntShl(
1924 vec_idx: ?usize,1927 vec_idx: ?usize,
1925) !Value {1928) !Value {
1926 const pt = sema.pt;1929 const pt = sema.pt;
1930 const zcu = pt.zcu;
1927 var lhs_space: Value.BigIntSpace = undefined;1931 var lhs_space: Value.BigIntSpace = undefined;
1928 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);1932 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1929 if (try rhs.getUnsignedIntSema(pt)) |shift_amt_u64| {1933 if (rhs.getUnsignedInt(zcu)) |shift_amt_u64| {
1930 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| {1934 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| {
1931 const result_bigint = try intShlInner(sema, lhs_bigint, shift_amt);1935 const result_bigint = try intShlInner(sema, lhs_bigint, shift_amt);
1932 return pt.intValue_big(.comptime_int, result_bigint.toConst());1936 return pt.intValue_big(.comptime_int, result_bigint.toConst());
...@@ -1963,15 +1967,15 @@ fn intShr(...@@ -1963,15 +1967,15 @@ fn intShr(
1963 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);1967 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
19641968
1965 const shift_amt: usize = if (rhs_ty.toIntern() == .comptime_int_type) amt: {1969 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| {
1967 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| break :amt shift_amt;1971 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| break :amt shift_amt;
1968 }1972 }
1969 if (try rhs.compareAllWithZeroSema(.lt, pt)) {1973 if (rhs.compareAllWithZero(.lt, zcu)) {
1970 return sema.failWithNegativeShiftAmount(block, rhs_src, rhs, vec_idx);1974 return sema.failWithNegativeShiftAmount(block, rhs_src, rhs, vec_idx);
1971 } else {1975 } else {
1972 return sema.failWithUnsupportedComptimeShiftAmount(block, rhs_src, vec_idx);1976 return sema.failWithUnsupportedComptimeShiftAmount(block, rhs_src, vec_idx);
1973 }1977 }
1974 } else @intCast(try rhs.toUnsignedIntSema(pt));1978 } else @intCast(rhs.toUnsignedInt(zcu));
19751979
1976 if (lhs_ty.toIntern() != .comptime_int_type and shift_amt >= lhs_ty.intInfo(zcu).bits) {1980 if (lhs_ty.toIntern() != .comptime_int_type and shift_amt >= lhs_ty.intInfo(zcu).bits) {
1977 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);1981 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);
...@@ -2006,7 +2010,7 @@ fn intBitReverse(sema: *Sema, val: Value, ty: Type) !Value {...@@ -2006,7 +2010,7 @@ fn intBitReverse(sema: *Sema, val: Value, ty: Type) !Value {
2006 const info = ty.intInfo(zcu);2010 const info = ty.intInfo(zcu);
20072011
2008 var val_space: Value.BigIntSpace = undefined;2012 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
2011 const limbs = try sema.arena.alloc(2015 const limbs = try sema.arena.alloc(
2012 std.math.big.Limb,2016 std.math.big.Limb,
src/Sema/bitcast.zig+94-90
...@@ -79,8 +79,8 @@ fn bitCastInner(...@@ -79,8 +79,8 @@ fn bitCastInner(
7979
80 const val_ty = val.typeOf(zcu);80 const val_ty = val.typeOf(zcu);
8181
82 try val_ty.resolveLayout(pt);82 val_ty.assertHasLayout(zcu);
83 try dest_ty.resolveLayout(pt);83 dest_ty.assertHasLayout(zcu);
8484
85 assert(val_ty.hasWellDefinedLayout(zcu));85 assert(val_ty.hasWellDefinedLayout(zcu));
8686
...@@ -138,8 +138,8 @@ fn bitCastSpliceInner(...@@ -138,8 +138,8 @@ fn bitCastSpliceInner(
138 const val_ty = val.typeOf(zcu);138 const val_ty = val.typeOf(zcu);
139 const splice_val_ty = splice_val.typeOf(zcu);139 const splice_val_ty = splice_val.typeOf(zcu);
140140
141 try val_ty.resolveLayout(pt);141 val_ty.assertHasLayout(zcu);
142 try splice_val_ty.resolveLayout(pt);142 splice_val_ty.assertHasLayout(zcu);
143143
144 const splice_bits = splice_val_ty.bitSize(zcu);144 const splice_bits = splice_val_ty.bitSize(zcu);
145145
...@@ -267,12 +267,13 @@ const UnpackValueBits = struct {...@@ -267,12 +267,13 @@ const UnpackValueBits = struct {
267 .int,267 .int,
268 .enum_tag,268 .enum_tag,
269 .simple_value,269 .simple_value,
270 .empty_enum_value,
271 .float,270 .float,
272 .ptr,271 .ptr,
273 .opt,272 .opt,
274 => try unpack.primitive(val),273 => try unpack.primitive(val),
275274
275 .bitpack => |bitpack| try unpack.primitive(.fromInterned(bitpack.backing_int_val)),
276
276 .aggregate => switch (ty.zigTypeTag(zcu)) {277 .aggregate => switch (ty.zigTypeTag(zcu)) {
277 .vector => {278 .vector => {
278 const len: usize = @intCast(ty.arrayLen(zcu));279 const len: usize = @intCast(ty.arrayLen(zcu));
...@@ -443,7 +444,7 @@ const UnpackValueBits = struct {...@@ -443,7 +444,7 @@ const UnpackValueBits = struct {
443 // This @intCast is okay because no primitive can exceed the size of a u16.444 // This @intCast is okay because no primitive can exceed the size of a u16.
444 const int_ty = try unpack.pt.intType(.unsigned, @intCast(bit_count));445 const int_ty = try unpack.pt.intType(.unsigned, @intCast(bit_count));
445 const buf = try unpack.arena.alloc(u8, @intCast((val_bits + 7) / 8));446 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);
447 const sub_val = try Value.readFromPackedMemory(int_ty, unpack.pt, buf, @intCast(bit_offset), unpack.arena);448 const sub_val = try Value.readFromPackedMemory(int_ty, unpack.pt, buf, @intCast(bit_offset), unpack.arena);
448 try unpack.primitive(sub_val);449 try unpack.primitive(sub_val);
449 },450 },
...@@ -451,7 +452,6 @@ const UnpackValueBits = struct {...@@ -451,7 +452,6 @@ const UnpackValueBits = struct {
451 // The only values here with runtime bits are `true` and `false.452 // The only values here with runtime bits are `true` and `false.
452 // These are both 1 bit, so will never need truncating.453 // These are both 1 bit, so will never need truncating.
453 .simple_value => unreachable,454 .simple_value => unreachable,
454 .empty_enum_value => unreachable, // zero-bit
455 else => unreachable, // zero-bit or not primitives455 else => unreachable, // zero-bit or not primitives
456 }456 }
457 }457 }
...@@ -565,102 +565,103 @@ const PackValueBits = struct {...@@ -565,102 +565,103 @@ const PackValueBits = struct {
565 return pt.aggregateValue(ty, elems);565 return pt.aggregateValue(ty, elems);
566 },566 },
567 .@"packed" => {567 .@"packed" => {
568 // All fields are in order with no padding.568 const backing_int_val = try pack.primitive(ty.bitpackBackingInt(zcu));
569 // This is identical between LE and BE targets.569 return pt.bitpackValue(ty, backing_int_val);
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);
576 },570 },
577 },571 },
578 .@"union" => {572 .@"union" => switch (ty.containerLayout(zcu)) {
579 // We will attempt to read as the backing representation. If this emits573 .auto => unreachable, // ill-defined layout
580 // `error.ReinterpretDeclRef`, we will try each union field, preferring larger ones.574 .@"extern" => {
581 // We will also attempt smaller fields when we get `undefined`, as if some bits are575 // We will attempt to read as the backing representation. If this emits
582 // defined we want to include them.576 // `error.ReinterpretDeclRef`, we will try each union field, preferring larger ones.
583 // TODO: this is very very bad. We need a more sophisticated union representation.577 // We will also attempt smaller fields when we get `undefined`, as if some bits are
584578 // defined we want to include them.
585 const prev_unpacked = pack.unpacked;579 // TODO: this is very very bad. We need a more sophisticated union representation.
586 const prev_bit_offset = pack.bit_offset;580
587581 const prev_unpacked = pack.unpacked;
588 const backing_ty = try ty.unionBackingType(pt);582 const prev_bit_offset = pack.bit_offset;
589583
590 backing: {584 const backing_ty = try ty.externUnionBackingType(pt);
591 const backing_val = pack.get(backing_ty) catch |err| switch (err) {585
592 error.ReinterpretDeclRef => {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)) {
593 pack.unpacked = prev_unpacked;596 pack.unpacked = prev_unpacked;
594 pack.bit_offset = prev_bit_offset;597 pack.bit_offset = prev_bit_offset;
595 break :backing;598 break :backing;
596 },599 }
597 else => |e| return e,600 return Value.fromInterned(try pt.internUnion(.{
598 };601 .ty = ty.toIntern(),
599 if (backing_val.isUndef(zcu)) {602 .tag = .none,
600 pack.unpacked = prev_unpacked;603 .val = backing_val.toIntern(),
601 pack.bit_offset = prev_bit_offset;604 }));
602 break :backing;
603 }605 }
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));607 const field_order = try pack.arena.alloc(u32, ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu));
612 for (field_order, 0..) |*f, i| f.* = @intCast(i);608 for (field_order, 0..) |*f, i| f.* = @intCast(i);
613 // Sort `field_order` to put the fields with the largest bit sizes first.609 // Sort `field_order` to put the fields with the largest bit sizes first.
614 const SizeSortCtx = struct {610 const SizeSortCtx = struct {
615 zcu: *Zcu,611 zcu: *Zcu,
616 field_types: []const InternPool.Index,612 field_types: []const InternPool.Index,
617 fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool {613 fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool {
618 const a_ty = Type.fromInterned(ctx.field_types[a_idx]);614 const a_ty = Type.fromInterned(ctx.field_types[a_idx]);
619 const b_ty = Type.fromInterned(ctx.field_types[b_idx]);615 const b_ty = Type.fromInterned(ctx.field_types[b_idx]);
620 return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu);616 return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu);
621 }617 }
622 };618 };
623 std.mem.sortUnstable(u32, field_order, SizeSortCtx{619 std.mem.sortUnstable(u32, field_order, SizeSortCtx{
624 .zcu = zcu,620 .zcu = zcu,
625 .field_types = zcu.typeToUnion(ty).?.field_types.get(ip),621 .field_types = zcu.typeToUnion(ty).?.field_types.get(ip),
626 }, SizeSortCtx.lessThan);622 }, SizeSortCtx.lessThan);
627623
628 const padding_after = endian == .little or ty.containerLayout(zcu) == .@"packed";624 const padding_after = endian == .little or ty.containerLayout(zcu) == .@"packed";
629625
630 for (field_order) |field_idx| {626 for (field_order) |field_idx| {
631 const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]);627 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);628 const pad_bits = ty.bitSize(zcu) - field_ty.bitSize(zcu);
633 if (!padding_after) try pack.padding(pad_bits);629 if (!padding_after) try pack.padding(pad_bits);
634 const field_val = pack.get(field_ty) catch |err| switch (err) {630 const field_val = pack.get(field_ty) catch |err| switch (err) {
635 error.ReinterpretDeclRef => {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)) {
636 pack.unpacked = prev_unpacked;640 pack.unpacked = prev_unpacked;
637 pack.bit_offset = prev_bit_offset;641 pack.bit_offset = prev_bit_offset;
638 continue;642 continue;
639 },643 }
640 else => |e| return e,644 const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);
641 };645 return Value.fromInterned(try pt.internUnion(.{
642 if (padding_after) try pack.padding(pad_bits);646 .ty = ty.toIntern(),
643 if (field_val.isUndef(zcu)) {647 .tag = tag_val.toIntern(),
644 pack.unpacked = prev_unpacked;648 .val = field_val.toIntern(),
645 pack.bit_offset = prev_bit_offset;649 }));
646 continue;
647 }650 }
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);
649 return Value.fromInterned(try pt.internUnion(.{655 return Value.fromInterned(try pt.internUnion(.{
650 .ty = ty.toIntern(),656 .ty = ty.toIntern(),
651 .tag = tag_val.toIntern(),657 .tag = .none,
652 .val = field_val.toIntern(),658 .val = backing_val.toIntern(),
653 }));659 }));
654 }660 },
655661 .@"packed" => {
656 // No field could represent the value. Just do whatever happens when we try to read662 const backing_int_val = try pack.primitive(ty.bitpackBackingInt(zcu));
657 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.663 return pt.bitpackValue(ty, backing_int_val);
658 const backing_val = try pack.get(backing_ty);664 },
659 return Value.fromInterned(try pt.internUnion(.{
660 .ty = ty.toIntern(),
661 .tag = .none,
662 .val = backing_val.toIntern(),
663 }));
664 },665 },
665 else => return pack.primitive(ty),666 else => return pack.primitive(ty),
666 }667 }
...@@ -673,6 +674,9 @@ const PackValueBits = struct {...@@ -673,6 +674,9 @@ const PackValueBits = struct {
673 fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value {674 fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value {
674 const pt = pack.pt;675 const pt = pack.pt;
675 const zcu = pt.zcu;676 const zcu = pt.zcu;
677
678 if (try want_ty.onePossibleValue(pt)) |opv| return opv;
679
676 const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu));680 const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu));
677681
678 for (vals) |val| {682 for (vals) |val| {
...@@ -719,7 +723,7 @@ const PackValueBits = struct {...@@ -719,7 +723,7 @@ const PackValueBits = struct {
719 const val = Value.fromInterned(ip_val);723 const val = Value.fromInterned(ip_val);
720 const ty = val.typeOf(zcu);724 const ty = val.typeOf(zcu);
721 if (!val.isUndef(zcu)) {725 if (!val.isUndef(zcu)) {
722 try val.writeToPackedMemory(ty, pt, buf, cur_bit_off);726 try val.writeToPackedMemory(pt, buf, cur_bit_off);
723 }727 }
724 cur_bit_off += @intCast(ty.bitSize(zcu));728 cur_bit_off += @intCast(ty.bitSize(zcu));
725 }729 }
src/Sema/comptime_ptr_access.zig+19-19
...@@ -67,7 +67,7 @@ pub fn storeComptimePtr(...@@ -67,7 +67,7 @@ pub fn storeComptimePtr(
6767
68 {68 {
69 const store_ty: Type = .fromInterned(ptr_info.child);69 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)) {
71 // zero-bit store; nothing to do71 // zero-bit store; nothing to do
72 return .success;72 return .success;
73 }73 }
...@@ -354,8 +354,8 @@ fn loadComptimePtrInner(...@@ -354,8 +354,8 @@ fn loadComptimePtrInner(
354 const load_one_ty, const load_count = load_ty.arrayBase(zcu);354 const load_one_ty, const load_count = load_ty.arrayBase(zcu);
355355
356 const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: {356 const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: {
357 if (try load_one_ty.comptimeOnlySema(pt)) break :restructure_array;357 if (load_one_ty.comptimeOnly(zcu)) break :restructure_array;
358 const elem_len = try load_one_ty.abiSizeSema(pt);358 const elem_len = load_one_ty.abiSize(zcu);
359 if (ptr.byte_offset % elem_len != 0) break :restructure_array;359 if (ptr.byte_offset % elem_len != 0) break :restructure_array;
360 break :idx @divExact(ptr.byte_offset, elem_len);360 break :idx @divExact(ptr.byte_offset, elem_len);
361 };361 };
...@@ -401,12 +401,12 @@ fn loadComptimePtrInner(...@@ -401,12 +401,12 @@ fn loadComptimePtrInner(
401 var cur_offset = ptr.byte_offset;401 var cur_offset = ptr.byte_offset;
402402
403 if (load_ty.zigTypeTag(zcu) == .array and array_offset > 0) {403 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;
405 }405 }
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)) {
410 return .{ .out_of_bounds = cur_val.typeOf(zcu) };410 return .{ .out_of_bounds = cur_val.typeOf(zcu) };
411 }411 }
412412
...@@ -441,7 +441,7 @@ fn loadComptimePtrInner(...@@ -441,7 +441,7 @@ fn loadComptimePtrInner(
441 .optional => break, // this can only be a pointer-like optional so is terminal441 .optional => break, // this can only be a pointer-like optional so is terminal
442 .array => {442 .array => {
443 const elem_ty = cur_ty.childType(zcu);443 const elem_ty = cur_ty.childType(zcu);
444 const elem_size = try elem_ty.abiSizeSema(pt);444 const elem_size = elem_ty.abiSize(zcu);
445 const elem_idx = cur_offset / elem_size;445 const elem_idx = cur_offset / elem_size;
446 const next_elem_off = elem_size * (elem_idx + 1);446 const next_elem_off = elem_size * (elem_idx + 1);
447 if (cur_offset + need_bytes <= next_elem_off) {447 if (cur_offset + need_bytes <= next_elem_off) {
...@@ -457,7 +457,7 @@ fn loadComptimePtrInner(...@@ -457,7 +457,7 @@ fn loadComptimePtrInner(
457 .@"packed" => break, // let the bitcast logic handle this457 .@"packed" => break, // let the bitcast logic handle this
458 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {458 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
459 const start_off = cur_ty.structFieldOffset(field_idx, zcu);459 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);
461 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {461 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
462 cur_val = try cur_val.getElem(sema.pt, field_idx);462 cur_val = try cur_val.getElem(sema.pt, field_idx);
463 cur_offset -= start_off;463 cur_offset -= start_off;
...@@ -484,7 +484,7 @@ fn loadComptimePtrInner(...@@ -484,7 +484,7 @@ fn loadComptimePtrInner(
484 };484 };
485 // The payload always has offset 0. If it's big enough485 // The payload always has offset 0. If it's big enough
486 // to represent the whole load type, we can use it.486 // 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) {
488 cur_val = payload;488 cur_val = payload;
489 } else {489 } else {
490 break;490 break;
...@@ -753,8 +753,8 @@ fn prepareComptimePtrStore(...@@ -753,8 +753,8 @@ fn prepareComptimePtrStore(
753753
754 const store_one_ty, const store_count = store_ty.arrayBase(zcu);754 const store_one_ty, const store_count = store_ty.arrayBase(zcu);
755 const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: {755 const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: {
756 if (try store_one_ty.comptimeOnlySema(pt)) break :restructure_array;756 if (store_one_ty.comptimeOnly(zcu)) break :restructure_array;
757 const elem_len = try store_one_ty.abiSizeSema(pt);757 const elem_len = store_one_ty.abiSize(zcu);
758 if (ptr.byte_offset % elem_len != 0) break :restructure_array;758 if (ptr.byte_offset % elem_len != 0) break :restructure_array;
759 break :idx @divExact(ptr.byte_offset, elem_len);759 break :idx @divExact(ptr.byte_offset, elem_len);
760 };760 };
...@@ -807,11 +807,11 @@ fn prepareComptimePtrStore(...@@ -807,11 +807,11 @@ fn prepareComptimePtrStore(
807 var cur_val: *MutableValue, var cur_offset: u64 = switch (base_strat) {807 var cur_val: *MutableValue, var cur_offset: u64 = switch (base_strat) {
808 .direct => |direct| .{ direct.val, 0 },808 .direct => |direct| .{ direct.val, 0 },
809 // It's okay to do `abiSize` - the comptime-only case will be caught below.809 // 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) },
811 .flat_index => |flat_index| .{811 .flat_index => |flat_index| .{
812 flat_index.val,812 flat_index.val,
813 // It's okay to do `abiSize` - the comptime-only case will be caught below.813 // 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),
815 },815 },
816 .reinterpret => |r| .{ r.val, r.byte_offset },816 .reinterpret => |r| .{ r.val, r.byte_offset },
817 else => unreachable,817 else => unreachable,
...@@ -823,12 +823,12 @@ fn prepareComptimePtrStore(...@@ -823,12 +823,12 @@ fn prepareComptimePtrStore(
823 }823 }
824824
825 if (store_ty.zigTypeTag(zcu) == .array and array_offset > 0) {825 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;
827 }827 }
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)) {
832 return .{ .out_of_bounds = cur_val.typeOf(zcu) };832 return .{ .out_of_bounds = cur_val.typeOf(zcu) };
833 }833 }
834834
...@@ -863,7 +863,7 @@ fn prepareComptimePtrStore(...@@ -863,7 +863,7 @@ fn prepareComptimePtrStore(
863 .optional => break, // this can only be a pointer-like optional so is terminal863 .optional => break, // this can only be a pointer-like optional so is terminal
864 .array => {864 .array => {
865 const elem_ty = cur_ty.childType(zcu);865 const elem_ty = cur_ty.childType(zcu);
866 const elem_size = try elem_ty.abiSizeSema(pt);866 const elem_size = elem_ty.abiSize(zcu);
867 const elem_idx = cur_offset / elem_size;867 const elem_idx = cur_offset / elem_size;
868 const next_elem_off = elem_size * (elem_idx + 1);868 const next_elem_off = elem_size * (elem_idx + 1);
869 if (cur_offset + need_bytes <= next_elem_off) {869 if (cur_offset + need_bytes <= next_elem_off) {
...@@ -879,7 +879,7 @@ fn prepareComptimePtrStore(...@@ -879,7 +879,7 @@ fn prepareComptimePtrStore(
879 .@"packed" => break, // let the bitcast logic handle this879 .@"packed" => break, // let the bitcast logic handle this
880 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {880 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
881 const start_off = cur_ty.structFieldOffset(field_idx, zcu);881 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);
883 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {883 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
884 cur_val = try cur_val.elem(pt, sema.arena, field_idx);884 cur_val = try cur_val.elem(pt, sema.arena, field_idx);
885 cur_offset -= start_off;885 cur_offset -= start_off;
...@@ -902,7 +902,7 @@ fn prepareComptimePtrStore(...@@ -902,7 +902,7 @@ fn prepareComptimePtrStore(
902 };902 };
903 // The payload always has offset 0. If it's big enough903 // The payload always has offset 0. If it's big enough
904 // to represent the whole load type, we can use it.904 // 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) {
906 cur_val = payload;906 cur_val = payload;
907 } else {907 } else {
908 break;908 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;...@@ -12,12 +12,10 @@ const Target = std.Target;
12const Zcu = @import("Zcu.zig");12const Zcu = @import("Zcu.zig");
13const log = std.log.scoped(.Type);13const log = std.log.scoped(.Type);
14const target_util = @import("target.zig");14const target_util = @import("target.zig");
15const Sema = @import("Sema.zig");
16const InternPool = @import("InternPool.zig");15const InternPool = @import("InternPool.zig");
17const Alignment = InternPool.Alignment;16const Alignment = InternPool.Alignment;
18const Zir = std.zig.Zir;17const Zir = std.zig.Zir;
19const Type = @This();18const Type = @This();
20const SemaError = Zcu.SemaError;
2119
22ip_index: InternPool.Index,20ip_index: InternPool.Index,
2321
...@@ -25,14 +23,288 @@ pub fn zigTypeTag(ty: Type, zcu: *const Zcu) std.builtin.TypeId {...@@ -25,14 +23,288 @@ pub fn zigTypeTag(ty: Type, zcu: *const Zcu) std.builtin.TypeId {
25 return zcu.intern_pool.zigTypeTag(ty.toIntern());23 return zcu.intern_pool.zigTypeTag(ty.toIntern());
26}24}
2725
28pub fn baseZigTypeTag(self: Type, mod: *Zcu) std.builtin.TypeId {26/// Every type is a member of exactly one "class" which determines:
29 return switch (self.zigTypeTag(mod)) {27/// * whether values of the type can exist at all
30 .error_union => self.errorUnionPayload(mod).baseZigTypeTag(mod),28/// * whether values of the type can be runtime-knwon
31 .optional => {29/// * whether the type is considered comptime-only
32 return self.optionalChild(mod).baseZigTypeTag(mod);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;
33 },237 },
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,
35 };260 };
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 }
36}308}
37309
38/// Asserts the type is resolved.310/// Asserts the type is resolved.
...@@ -44,7 +316,7 @@ pub fn isSelfComparable(ty: Type, zcu: *const Zcu, is_equality_cmp: bool) bool {...@@ -44,7 +316,7 @@ pub fn isSelfComparable(ty: Type, zcu: *const Zcu, is_equality_cmp: bool) bool {
44 .comptime_int,316 .comptime_int,
45 => true,317 => true,
46318
47 .vector => ty.elemType2(zcu).isSelfComparable(zcu, is_equality_cmp),319 .vector => ty.childType(zcu).isSelfComparable(zcu, is_equality_cmp),
48320
49 .bool,321 .bool,
50 .type,322 .type,
...@@ -121,11 +393,7 @@ pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool {...@@ -121,11 +393,7 @@ pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool {
121 return a.toIntern() == b.toIntern();393 return a.toIntern() == b.toIntern();
122}394}
123395
124pub fn format(ty: Type, writer: *std.Io.Writer) !void {396pub const format = @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
125 _ = ty;
126 _ = writer;
127 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
128}
129397
130pub const Formatter = std.fmt.Alt(Format, Format.default);398pub 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...@@ -416,13 +684,13 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
416 .error_union,684 .error_union,
417 .enum_literal,685 .enum_literal,
418 .enum_tag,686 .enum_tag,
419 .empty_enum_value,
420 .float,687 .float,
421 .ptr,688 .ptr,
422 .slice,689 .slice,
423 .opt,690 .opt,
424 .aggregate,691 .aggregate,
425 .un,692 .un,
693 .bitpack,
426 // memoization, not types694 // memoization, not types
427 .memoized_call,695 .memoized_call,
428 => unreachable,696 => unreachable,
...@@ -440,247 +708,41 @@ pub fn toIntern(ty: Type) InternPool.Index {...@@ -440,247 +708,41 @@ pub fn toIntern(ty: Type) InternPool.Index {
440}708}
441709
442pub fn toValue(self: Type) Value {710pub fn toValue(self: Type) Value {
443 return Value.fromInterned(self.toIntern());711 return .fromInterned(self.toIntern());
444}712}
445713
446const RuntimeBitsError = SemaError || error{NeedLazy};714/// Returns `true` if and only if the type takes up space in memory at runtime. This is also exactly
447715/// 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.
448pub fn hasRuntimeBits(ty: Type, zcu: *const Zcu) bool {736pub fn hasRuntimeBits(ty: Type, zcu: *const Zcu) bool {
449 return hasRuntimeBitsInner(ty, false, .eager, zcu, {}) catch unreachable;737 return switch (ty.classify(zcu)) {
450}738 .no_possible_value, .one_possible_value, .fully_comptime => false,
451739 .runtime, .partially_comptime => true,
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 },
678 };740 };
679}741}
680742
681/// true if and only if the type has a well-defined memory layout743/// Returns `true` iff the memory layout of `ty` is defined by the Zig language specification.
682/// readFrom/writeToMemory are supported only for types with a well-744///
683/// defined memory layout745/// Does not require `ty` to be resolved.
684pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {746pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
685 const ip = &zcu.intern_pool;747 const ip = &zcu.intern_pool;
686 return switch (ip.indexToKey(ty.toIntern())) {748 return switch (ip.indexToKey(ty.toIntern())) {
...@@ -737,17 +799,17 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {...@@ -737,17 +799,17 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
737 .generic_poison,799 .generic_poison,
738 => false,800 => false,
739 },801 },
740 .struct_type => ip.loadStructType(ty.toIntern()).layout != .auto,802 .struct_type => switch (ip.loadStructType(ty.toIntern()).layout) {
741 .union_type => {803 .auto => false,
742 const union_type = ip.loadUnionType(ty.toIntern());804 .@"extern", .@"packed" => true,
743 return switch (union_type.flagsUnordered(ip).runtime_tag) {805 },
744 .none, .safety => union_type.flagsUnordered(ip).layout != .auto,806 .union_type => switch (ip.loadUnionType(ty.toIntern()).layout) {
745 .tagged => false,807 .auto => false,
746 };808 .@"extern", .@"packed" => true,
747 },809 },
748 .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) {810 .enum_type => switch (ip.loadEnumType(ty.toIntern()).int_tag_mode) {
811 .explicit => true,
749 .auto => false,812 .auto => false,
750 .explicit, .nonexhaustive => true,
751 },813 },
752814
753 // values, not types815 // values, not types
...@@ -761,86 +823,88 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {...@@ -761,86 +823,88 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
761 .error_union,823 .error_union,
762 .enum_literal,824 .enum_literal,
763 .enum_tag,825 .enum_tag,
764 .empty_enum_value,
765 .float,826 .float,
766 .ptr,827 .ptr,
767 .slice,828 .slice,
768 .opt,829 .opt,
769 .aggregate,830 .aggregate,
770 .un,831 .un,
832 .bitpack,
771 // memoization, not types833 // memoization, not types
772 .memoized_call,834 .memoized_call,
773 => unreachable,835 => unreachable,
774 };836 };
775}837}
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
785/// Determines whether a function type has runtime bits, i.e. whether a839/// Determines whether a function type has runtime bits, i.e. whether a
786/// function with this type can exist at runtime.840/// function with this type can exist at runtime.
787/// Asserts that `ty` is a function type.841/// Asserts that `ty` is a function type.
788pub fn fnHasRuntimeBitsInner(842pub fn fnHasRuntimeBits(fn_ty: Type, zcu: *const Zcu) bool {
789 ty: Type,843 assertHasLayout(fn_ty, zcu);
790 comptime strat: ResolveStrat,844 const fn_info = zcu.typeToFunc(fn_ty).?;
791 zcu: strat.ZcuPtr(),845 if (fn_info.comptime_bits != 0) return false;
792 tid: strat.Tid(),846 for (fn_info.param_types.get(&zcu.intern_pool)) |param_ty| {
793) SemaError!bool {847 if (param_ty == .generic_poison_type) return false;
794 const fn_info = zcu.typeToFunc(ty).?;848 switch (Type.fromInterned(param_ty).classify(zcu)) {
795 if (fn_info.is_generic) return false;849 .fully_comptime,
796 if (fn_info.is_var_args) return true;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 }
797 if (fn_info.cc == .@"inline") return false;878 if (fn_info.cc == .@"inline") return false;
798 return !try Type.fromInterned(fn_info.return_type).comptimeOnlyInner(strat, zcu, tid);879 return true;
799}880}
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 {
802 switch (ty.zigTypeTag(zcu)) {884 switch (ty.zigTypeTag(zcu)) {
803 .@"fn" => return ty.fnHasRuntimeBits(zcu),885 .@"fn" => return ty.fnHasRuntimeBits(zcu),
804 else => return ty.hasRuntimeBits(zcu),886 else => return ty.hasRuntimeBits(zcu),
805 }887 }
806}888}
807889
808/// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.890/// Returns whether `ty` is NPV, meaning it is "like `noreturn`" in a sense. See doc comments on
809pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, zcu: *Zcu) bool {891/// `Class` for more details.
810 return switch (ty.zigTypeTag(zcu)) {892///
811 .@"fn" => true,893/// Exactly equivalent to `ty.classify(zcu) == .no_possible_value`.
812 else => return ty.hasRuntimeBitsIgnoreComptime(zcu),
813 };
814}
815
816pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool {894pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool {
817 return zcu.intern_pool.isNoReturn(ty.toIntern());895 return ty.classify(zcu) == .no_possible_value;
818}896}
819897
820/// Never returns `none`. Asserts that all necessary type resolution is already done.898/// Never returns `none`. Asserts that all necessary type resolution is already done.
821pub fn ptrAlignment(ty: Type, zcu: *Zcu) Alignment {899pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment {
822 return ptrAlignmentInner(ty, .normal, zcu, {}) catch unreachable;900 const ip = &zcu.intern_pool;
823}901 const ptr_key: InternPool.Key.PtrType = switch (ip.indexToKey(ptr_ty.toIntern())) {
824902 .ptr_type => |key| key,
825pub fn ptrAlignmentSema(ty: Type, pt: Zcu.PerThread) SemaError!Alignment {903 .opt_type => |child| ip.indexToKey(child).ptr_type,
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),
842 else => unreachable,904 else => unreachable,
843 };905 };
906 if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment;
907 return Type.fromInterned(ptr_key.child).abiAlignment(zcu);
844}908}
845909
846pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace {910pub 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 {...@@ -851,861 +915,364 @@ pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace {
851 };915 };
852}916}
853917
854/// May capture a reference to `ty`.918/// Never returns `.none`. Asserts that the layout of `ty` is resolved.
855/// Returned value has type `comptime_int`.919///
856pub fn lazyAbiAlignment(ty: Type, pt: Zcu.PerThread) !Value {920/// Unlike ABI size, a type's ABI alignment is not affected by its `Class`. In other words, any
857 switch (try ty.abiAlignmentInner(.lazy, pt.zcu, pt.tid)) {921/// alignment is possible regardless of the result of `ty.classify(zcu)`.
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.
951pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {922pub 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();
973 const ip = &zcu.intern_pool;923 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()) {961 .opt_type => |child| Type.fromInterned(child).abiAlignment(zcu),
976 .empty_tuple_type => return .{ .scalar = .@"1" },962 .error_union_type => |eu| Alignment.maxStrict(
977 else => switch (ip.indexToKey(ty.toIntern())) {963 Type.fromInterned(eu.payload_type).abiAlignment(zcu),
978 .int_type => |int_type| {964 errorAbiAlignment(zcu),
979 if (int_type.bits == 0) return .{ .scalar = .@"1" };965 ),
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 },
1021966
1022 .opt_type => return ty.abiAlignmentInnerOptional(strat, zcu, tid),967 .error_set_type, .inferred_error_set_type => errorAbiAlignment(zcu),
1023 .error_union_type => |info| return ty.abiAlignmentInnerErrorUnion(
1024 strat,
1025 zcu,
1026 tid,
1027 Type.fromInterned(info.payload_type),
1028 ),
1029968
1030 .error_set_type, .inferred_error_set_type => {969 .func_type => target_util.minFunctionAlignment(target),
1031 const bits = zcu.errorSetBits();
1032 if (bits == 0) return .{ .scalar = .@"1" };
1033 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
1034 },
1035970
1036 // represents machine code; not a pointer971 .simple_type => |t| switch (t) {
1037 .func_type => return .{ .scalar = target_util.minFunctionAlignment(target) },972 .bool,
1038973 .void,
1039 .simple_type => |t| switch (t) {974 .noreturn,
1040 .bool,975 .anyopaque,
1041 .anyopaque,976 .type,
1042 => return .{ .scalar = .@"1" },977 .comptime_int,
1043978 .comptime_float,
1044 .usize,979 .null,
1045 .isize,980 .undefined,
1046 => return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())) },981 .enum_literal,
1047982 => .@"1",
1048 .c_char => return .{ .scalar = cTypeAlign(target, .char) },983
1049 .c_short => return .{ .scalar = cTypeAlign(target, .short) },984 .anyerror, .adhoc_inferred_error_set => errorAbiAlignment(zcu),
1050 .c_ushort => return .{ .scalar = cTypeAlign(target, .ushort) },985 .usize, .isize => .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1051 .c_int => return .{ .scalar = cTypeAlign(target, .int) },986
1052 .c_uint => return .{ .scalar = cTypeAlign(target, .uint) },987 .c_char => cTypeAlign(target, .char),
1053 .c_long => return .{ .scalar = cTypeAlign(target, .long) },988 .c_short => cTypeAlign(target, .short),
1054 .c_ulong => return .{ .scalar = cTypeAlign(target, .ulong) },989 .c_ushort => cTypeAlign(target, .ushort),
1055 .c_longlong => return .{ .scalar = cTypeAlign(target, .longlong) },990 .c_int => cTypeAlign(target, .int),
1056 .c_ulonglong => return .{ .scalar = cTypeAlign(target, .ulonglong) },991 .c_uint => cTypeAlign(target, .uint),
1057 .c_longdouble => return .{ .scalar = cTypeAlign(target, .longdouble) },992 .c_long => cTypeAlign(target, .long),
1058993 .c_ulong => cTypeAlign(target, .ulong),
1059 .f16 => return .{ .scalar = .@"2" },994 .c_longlong => cTypeAlign(target, .longlong),
1060 .f32 => return .{ .scalar = cTypeAlign(target, .float) },995 .c_ulonglong => cTypeAlign(target, .ulonglong),
1061 .f64 => switch (target.cTypeBitSize(.double)) {996 .c_longdouble => cTypeAlign(target, .longdouble),
1062 64 => return .{ .scalar = cTypeAlign(target, .double) },997
1063 else => return .{ .scalar = .@"8" },998 .f16 => .@"2",
1064 },999 .f32 => cTypeAlign(target, .float),
1065 .f80 => switch (target.cTypeBitSize(.longdouble)) {1000 .f64 => switch (target.cTypeBitSize(.double)) {
1066 80 => return .{ .scalar = cTypeAlign(target, .longdouble) },1001 64 => cTypeAlign(target, .double),
1067 else => return .{ .scalar = Type.u80.abiAlignment(zcu) },1002 else => .@"8",
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 };
1136 },1003 },
1137 .union_type => {1004 .f80 => switch (target.cTypeBitSize(.longdouble)) {
1138 const union_type = ip.loadUnionType(ty.toIntern());1005 80 => cTypeAlign(target, .longdouble),
11391006 else => Type.u80.abiAlignment(zcu),
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 };
1150 },1007 },
1151 .opaque_type => return .{ .scalar = .@"1" },1008 .f128 => switch (target.cTypeBitSize(.longdouble)) {
1152 .enum_type => return .{1009 128 => cTypeAlign(target, .longdouble),
1153 .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(zcu),1010 else => .@"16",
1154 },1011 },
11551012
1156 // values, not types1013 .generic_poison => unreachable,
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,
1177 },1014 },
1178 }1015 .tuple_type => |tuple| {
1179}1016 var big_align: Alignment = .@"1";
11801017 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
1181fn abiAlignmentInnerErrorUnion(1018 if (val != .none) continue; // comptime field
1182 ty: Type,1019 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);
1183 comptime strat: ResolveStratLazy,1020 big_align = big_align.maxStrict(field_align);
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 => {},
1214 }1021 }
1215 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{1022 return big_align;
1216 .ty = .comptime_int_type,
1217 .storage = .{ .lazy_align = ty.toIntern() },
1218 } })) };
1219 },1023 },
1220 }1024 .struct_type => {
1221}1025 const struct_obj = ip.loadStructType(ty.toIntern());
12221026 switch (struct_obj.layout) {
1223fn abiAlignmentInnerOptional(1027 .@"packed" => return Type.fromInterned(struct_obj.packed_backing_int_type).abiAlignment(zcu),
1224 ty: Type,1028 .auto, .@"extern" => {
1225 comptime strat: ResolveStratLazy,1029 assert(struct_obj.alignment != .none);
1226 zcu: strat.ZcuPtr(),1030 return struct_obj.alignment;
1227 tid: strat.Tid(),1031 },
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" };
1252 }1032 }
1253 return child_type.abiAlignmentInner(strat, zcu, tid);
1254 },1033 },
1255 .lazy => switch (try child_type.abiAlignmentInner(strat, zcu, tid)) {1034 .union_type => {
1256 .scalar => |x| return .{ .scalar = x.max(.@"1") },1035 const union_obj = ip.loadUnionType(ty.toIntern());
1257 .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{1036 switch (union_obj.layout) {
1258 .ty = .comptime_int_type,1037 .@"packed" => return Type.fromInterned(union_obj.packed_backing_int_type).abiAlignment(zcu),
1259 .storage = .{ .lazy_align = ty.toIntern() },1038 .auto, .@"extern" => {
1260 } })) },1039 assert(union_obj.alignment != .none);
1040 return union_obj.alignment;
1041 },
1042 }
1261 },1043 },
1262 }1044 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).int_tag_type).abiAlignment(zcu),
1263}1045 .opaque_type => .@"1",
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}
12751046
1276/// May capture a reference to `ty`.1047 // values, not types
1277pub fn abiSizeLazy(ty: Type, pt: Zcu.PerThread) !Value {1048 .undef,
1278 switch (try ty.abiSizeInner(.lazy, pt.zcu, pt.tid)) {1049 .simple_value,
1279 .val => |val| return val,1050 .variable,
1280 .scalar => |x| return pt.intValue(Type.comptime_int, x),1051 .@"extern",
1281 }1052 .func,
1282}1053 .int,
12831054 .err,
1284pub fn abiSizeSema(ty: Type, pt: Zcu.PerThread) SemaError!u64 {1055 .error_union,
1285 return (try abiSizeInner(ty, .sema, pt.zcu, pt.tid)).scalar;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 };
1286}1069}
12871070
1288/// If you pass `eager` you will get back `scalar` and assert the type is resolved.1071/// Asserts that `ty` is not an opaque type, and that the layout of `ty` is resolved.
1289/// In this case there will be no error, guaranteed.1072///
1290/// If you pass `lazy` you may get back `scalar` or `val`.1073/// If the type is NPV, OPV, or fully-comptime (see `Class`), the return value of this function is
1291/// If `val` is returned, a reference to `ty` has been captured.1074/// guaranteed to be zero. Otherwise (if the type is runtime or partially-comptime) the return value
1292/// If you pass `sema` you will get back `scalar` and resolve the type if1075/// is guaranteed to be non-zero.
1293/// necessary, possibly returning a CompileError.1076pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
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();
1301 const ip = &zcu.intern_pool;1077 const ip = &zcu.intern_pool;
13021078 const target = zcu.getTarget();
1303 switch (ty.toIntern()) {1079 assertHasLayout(ty, zcu);
1304 .empty_tuple_type => return .{ .scalar = 0 },1080 return switch (ip.indexToKey(ty.toIntern())) {
13051081 .int_type => |int_type| std.zig.target.intByteSize(target, int_type.bits),
1306 else => switch (ip.indexToKey(ty.toIntern())) {1082 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1307 .int_type => |int_type| {1083 .slice => ptrAbiSize(target) * 2,
1308 if (int_type.bits == 0) return .{ .scalar = 0 };1084 .one, .many, .c => ptrAbiSize(target),
1309 return .{ .scalar = std.zig.target.intByteSize(target, int_type.bits) };1085 },
1310 },1086 .anyframe_type => ptrAbiSize(target),
1311 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1087 .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu),
1312 .slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },1088 .vector_type => |vec| {
1313 else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },1089 const elem_ty: Type = .fromInterned(vec.child);
1314 },1090 const bytes = switch (zcu.comp.getZigBackend()) {
1315 .anyframe_type => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },1091 else => std.math.divCeil(u64, vec.len * elem_ty.bitSize(zcu), 8) catch unreachable,
13161092 .stage2_c => vec.len * elem_ty.abiSize(zcu),
1317 .array_type => |array_type| {1093 .stage2_x86_64 => switch (elem_ty.toIntern()) {
1318 const len = array_type.lenIncludingSentinel();1094 .bool_type => std.math.divCeil(u64, vec.len, 8) catch unreachable,
1319 if (len == 0) return .{ .scalar = 0 };1095 else => vec.len * elem_ty.abiSize(zcu),
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) };
1465 },1096 },
14661097 };
1467 .noreturn => unreachable,1098 return ty.abiAlignment(zcu).forward(bytes);
1468 .generic_poison => unreachable,1099 },
1469 },1100 .opt_type => |child_ty_ip| {
1470 .struct_type => {1101 const child_ty: Type = .fromInterned(child_ty_ip);
1471 const struct_type = ip.loadStructType(ty.toIntern());1102 if (child_ty.classify(zcu) == .no_possible_value) return 0;
1472 switch (strat) {1103 if (ty.optionalReprIsPayload(zcu)) return child_ty.abiSize(zcu);
1473 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),1104 // Optional types are represented as a struct with the child type as the first
1474 .lazy => {1105 // field and a boolean as the second. Since the child type's abi alignment is
1475 const pt = strat.pt(zcu, tid);1106 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
1476 switch (struct_type.layout) {1107 // to the child type's ABI alignment.
1477 .@"packed" => {1108 return child_ty.abiSize(zcu) + child_ty.abiAlignment(zcu).toByteUnits().?;
1478 if (struct_type.backingIntTypeUnordered(ip) == .none) return .{1109 },
1479 .val = Value.fromInterned(try pt.intern(.{ .int = .{1110 .error_set_type, .inferred_error_set_type => errorAbiSize(zcu),
1480 .ty = .comptime_int_type,1111 .error_union_type => |error_union| {
1481 .storage = .{ .lazy_size = ty.toIntern() },1112 const payload_ty: Type = .fromInterned(error_union.payload_type);
1482 } })),1113 switch (payload_ty.classify(zcu)) {
1483 };1114 // Zig has no way to take the address of the error set "in" an error union (giving
1484 },1115 // implementations more freedom in terms of data layout), so if the payload type is
1485 .auto, .@"extern" => {1116 // fully comptime, we don't need to dedicate runtime bits to the error set.
1486 if (!struct_type.haveLayout(ip)) return .{1117 .fully_comptime => return 0,
1487 .val = Value.fromInterned(try pt.intern(.{ .int = .{1118 else => {},
1488 .ty = .comptime_int_type,1119 }
1489 .storage = .{ .lazy_size = ty.toIntern() },1120 // The layout will either be (code, payload, padding) or (payload, code, padding)
1490 } })),1121 // depending on which has larger alignment. So the overall size is just the code
1491 };1122 // and payload sizes added and padded to the larger alignment.
1492 },1123 const big_align: Alignment = .maxStrict(errorAbiAlignment(zcu), payload_ty.abiAlignment(zcu));
1493 }1124 return big_align.forward(errorAbiSize(zcu) + payload_ty.abiSize(zcu));
1494 },1125 },
1495 .eager => {},1126 .func_type => 0,
1496 }1127 .simple_type => |t| switch (t) {
1497 switch (struct_type.layout) {1128 .void,
1498 .@"packed" => return .{1129 .noreturn,
1499 .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiSize(zcu),1130 .type,
1500 },1131 .comptime_int,
1501 .auto, .@"extern" => {1132 .comptime_float,
1502 assert(struct_type.haveLayout(ip));1133 .null,
1503 return .{ .scalar = struct_type.sizeUnordered(ip) };1134 .undefined,
1504 },1135 .enum_literal,
1505 }1136 => 0,
1506 },1137
1507 .tuple_type => |tuple| {1138 .bool => 1,
1508 switch (strat) {1139 .anyerror, .adhoc_inferred_error_set => errorAbiSize(zcu),
1509 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),1140 .usize, .isize => ptrAbiSize(target),
1510 .lazy, .eager => {},1141
1511 }1142 .c_char => target.cTypeByteSize(.char),
1512 const field_count = tuple.types.len;1143 .c_short => target.cTypeByteSize(.short),
1513 if (field_count == 0) {1144 .c_ushort => target.cTypeByteSize(.ushort),
1514 return .{ .scalar = 0 };1145 .c_int => target.cTypeByteSize(.int),
1515 }1146 .c_uint => target.cTypeByteSize(.uint),
1516 return .{ .scalar = ty.structFieldOffset(field_count, zcu) };1147 .c_long => target.cTypeByteSize(.long),
1517 },1148 .c_ulong => target.cTypeByteSize(.ulong),
15181149 .c_longlong => target.cTypeByteSize(.longlong),
1519 .union_type => {1150 .c_ulonglong => target.cTypeByteSize(.ulonglong),
1520 const union_type = ip.loadUnionType(ty.toIntern());1151 .c_longdouble => target.cTypeByteSize(.longdouble),
1521 switch (strat) {1152
1522 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),1153 .f16 => 2,
1523 .lazy => {1154 .f32 => 4,
1524 const pt = strat.pt(zcu, tid);1155 .f64 => 8,
1525 if (!union_type.flagsUnordered(ip).status.haveLayout()) return .{1156 .f80 => switch (target.cTypeBitSize(.longdouble)) {
1526 .val = Value.fromInterned(try pt.intern(.{ .int = .{1157 80 => target.cTypeByteSize(.longdouble),
1527 .ty = .comptime_int_type,1158 else => Type.u80.abiSize(zcu),
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) };
1537 },1159 },
1538 .opaque_type => unreachable, // no size available1160 .f128 => 16,
1539 .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(zcu) },
15401161
1541 // values, not types1162 .anyopaque => unreachable,
1542 .undef,1163 .generic_poison => unreachable,
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,
1562 },1164 },
1563 }1165 .tuple_type => |tuple| switch (ty.classify(zcu)) {
1564}1166 // `structFieldOffset` is bogus on NPV tuples, because there may be some fields with
15651167 // non-zero size.
1566fn abiSizeInnerOptional(1168 .no_possible_value => 0,
1567 ty: Type,1169 else => ty.structFieldOffset(tuple.types.len, zcu),
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 } })) },
1602 },1170 },
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 first1188 // values, not types
1606 // field and a boolean as the second. Since the child type's abi alignment is1189 .undef,
1607 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal1190 .simple_value,
1608 // to the child type's ABI alignment.1191 .variable,
1609 return .{1192 .@"extern",
1610 .scalar = (child_ty.abiAlignment(zcu).toByteUnits() orelse 0) + payload_size,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,
1611 };1209 };
1612}1210}
16131211
1614pub fn ptrAbiAlignment(target: *const Target) Alignment {1212pub fn ptrAbiAlignment(target: *const Target) Alignment {
1615 return Alignment.fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));1213 return .fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
1616}1214}
16171215pub fn ptrAbiSize(target: *const Target) u64 {
1618pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {1216 return @divExact(target.ptrBitWidth(), 8);
1619 return bitSizeInner(ty, .normal, zcu, {}) catch unreachable;
1620}1217}
16211218pub fn errorAbiAlignment(zcu: *const Zcu) Alignment {
1622pub fn bitSizeSema(ty: Type, pt: Zcu.PerThread) SemaError!u64 {1219 return .fromNonzeroByteUnits(std.zig.target.intAlignment(zcu.getTarget(), zcu.errorSetBits()));
1623 return bitSizeInner(ty, .sema, pt.zcu, pt.tid);1220}
1221pub fn errorAbiSize(zcu: *const Zcu) u64 {
1222 return std.zig.target.intByteSize(zcu.getTarget(), zcu.errorSetBits());
1624}1223}
16251224
1626pub fn bitSizeInner(1225/// Asserts that `ty` is not an opaque or comptime-only type.
1627 ty: Type,1226/// Once #19755 is implemented, this query will only work on types with a defined bit-level representation.
1628 comptime strat: ResolveStrat,1227pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
1629 zcu: strat.ZcuPtr(),
1630 tid: strat.Tid(),
1631) SemaError!u64 {
1632 const target = zcu.getTarget();1228 const target = zcu.getTarget();
1633 const ip = &zcu.intern_pool;1229 const ip = &zcu.intern_pool;
16341230 assertHasLayout(ty, zcu);
1635 const strat_lazy: ResolveStratLazy = strat.toLazy();1231 return switch (ip.indexToKey(ty.toIntern())) {
16361232 .int_type => |int_type| int_type.bits,
1637 switch (ip.indexToKey(ty.toIntern())) {
1638 .int_type => |int_type| return int_type.bits,
1639 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1233 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1640 .slice => return target.ptrBitWidth() * 2,1234 .slice => target.ptrBitWidth() * 2,
1641 else => return target.ptrBitWidth(),1235 else => target.ptrBitWidth(),
1642 },1236 },
1643 .anyframe_type => return target.ptrBitWidth(),1237 .anyframe_type => target.ptrBitWidth(),
1644
1645 .array_type => |array_type| {1238 .array_type => |array_type| {
1646 const len = array_type.lenIncludingSentinel();
1647 if (len == 0) return 0;
1648 const elem_ty: Type = .fromInterned(array_type.child);1239 const elem_ty: Type = .fromInterned(array_type.child);
1649 switch (zcu.comp.getZigBackend()) {1240 const len = array_type.lenIncludingSentinel();
1650 else => {1241 return switch (zcu.comp.getZigBackend()) {
1651 const elem_size = (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar;1242 .stage2_x86_64 => len * elem_ty.bitSize(zcu),
1652 if (elem_size == 0) return 0;1243 // this case will be removed under #19755
1653 const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);1244 else => switch (len) {
1654 return (len - 1) * 8 * elem_size + elem_bit_size;1245 0 => 0,
1655 },1246 else => (len - 1) * 8 * elem_ty.abiSize(zcu) + elem_ty.bitSize(zcu),
1656 .stage2_x86_64 => {
1657 const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
1658 return elem_bit_size * len;
1659 },1247 },
1660 }1248 };
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;
1671 },1249 },
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
1681 .simple_type => |t| switch (t) {1254 .simple_type => |t| switch (t) {
1682 .f16 => return 16,1255 .void => 0,
1683 .f32 => return 32,1256 .bool => 1,
1684 .f64 => return 64,1257 .anyerror, .adhoc_inferred_error_set => zcu.errorSetBits(),
1685 .f80 => return 80,1258 .usize, .isize => target.ptrBitWidth(),
1686 .f128 => return 128,1259
16871260 .c_char => target.cTypeBitSize(.char),
1688 .usize,1261 .c_short => target.cTypeBitSize(.short),
1689 .isize,1262 .c_ushort => target.cTypeBitSize(.ushort),
1690 => return target.ptrBitWidth(),1263 .c_int => target.cTypeBitSize(.int),
16911264 .c_uint => target.cTypeBitSize(.uint),
1692 .c_char => return target.cTypeBitSize(.char),1265 .c_long => target.cTypeBitSize(.long),
1693 .c_short => return target.cTypeBitSize(.short),1266 .c_ulong => target.cTypeBitSize(.ulong),
1694 .c_ushort => return target.cTypeBitSize(.ushort),1267 .c_longlong => target.cTypeBitSize(.longlong),
1695 .c_int => return target.cTypeBitSize(.int),1268 .c_ulonglong => target.cTypeBitSize(.ulonglong),
1696 .c_uint => return target.cTypeBitSize(.uint),1269 .c_longdouble => target.cTypeBitSize(.longdouble),
1697 .c_long => return target.cTypeBitSize(.long),1270
1698 .c_ulong => return target.cTypeBitSize(.ulong),1271 .f16 => 16,
1699 .c_longlong => return target.cTypeBitSize(.longlong),1272 .f32 => 32,
1700 .c_ulonglong => return target.cTypeBitSize(.ulonglong),1273 .f64 => 64,
1701 .c_longdouble => return target.cTypeBitSize(.longdouble),1274 .f80 => 80,
17021275 .f128 => 128,
1703 .bool => return 1,
1704 .void => return 0,
1705
1706 .anyerror,
1707 .adhoc_inferred_error_set,
1708 => return zcu.errorSetBits(),
17091276
1710 .anyopaque => unreachable,1277 .anyopaque => unreachable,
1711 .type => unreachable,1278 .type => unreachable,
...@@ -1717,49 +1284,30 @@ pub fn bitSizeInner(...@@ -1717,49 +1284,30 @@ pub fn bitSizeInner(
1717 .enum_literal => unreachable,1284 .enum_literal => unreachable,
1718 .generic_poison => unreachable,1285 .generic_poison => unreachable,
1719 },1286 },
1287
1720 .struct_type => {1288 .struct_type => {
1721 const struct_type = ip.loadStructType(ty.toIntern());1289 const struct_obj = ip.loadStructType(ty.toIntern());
1722 const is_packed = struct_type.layout == .@"packed";1290 switch (struct_obj.layout) {
1723 if (strat == .sema) {1291 .@"packed" => return Type.fromInterned(struct_obj.packed_backing_int_type).bitSize(zcu),
1724 const pt = strat.pt(zcu, tid);1292 .auto, .@"extern" => return struct_obj.size * 8, // will be `unreachable` under #19755
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);
1731 }1293 }
1732 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1733 },1294 },
1734
1735 .tuple_type => {
1736 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1737 },
1738
1739 .union_type => {1295 .union_type => {
1740 const union_type = ip.loadUnionType(ty.toIntern());1296 const union_obj = ip.loadUnionType(ty.toIntern());
1741 const is_packed = ty.containerLayout(zcu) == .@"packed";1297 switch (union_obj.layout) {
1742 if (strat == .sema) {1298 .@"packed" => return Type.fromInterned(union_obj.packed_backing_int_type).bitSize(zcu),
1743 const pt = strat.pt(zcu, tid);1299 .auto, .@"extern" => return union_obj.size * 8, // will be `unreachable` under #19755
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;
1749 }1300 }
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;1304 // will be `unreachable` under #19755
1753 for (0..union_type.field_types.len) |field_index| {1305 .opt_type,
1754 const field_ty = union_type.field_types.get(ip)[field_index];1306 .error_union_type,
1755 size = @max(size, try Type.fromInterned(field_ty).bitSizeInner(strat, zcu, tid));1307 .tuple_type,
1756 }1308 => ty.abiSize(zcu) * 8,
17571309
1758 return size;
1759 },
1760 .opaque_type => unreachable,1310 .opaque_type => unreachable,
1761 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty)
1762 .bitSizeInner(strat, zcu, tid),
17631311
1764 // values, not types1312 // values, not types
1765 .undef,1313 .undef,
...@@ -1772,33 +1320,16 @@ pub fn bitSizeInner(...@@ -1772,33 +1320,16 @@ pub fn bitSizeInner(
1772 .error_union,1320 .error_union,
1773 .enum_literal,1321 .enum_literal,
1774 .enum_tag,1322 .enum_tag,
1775 .empty_enum_value,
1776 .float,1323 .float,
1777 .ptr,1324 .ptr,
1778 .slice,1325 .slice,
1779 .opt,1326 .opt,
1780 .aggregate,1327 .aggregate,
1781 .un,1328 .un,
1782 // memoization, not types1329 .bitpack,
1783 .memoized_call,1330 // memoization, not types
1784 => unreachable,1331 .memoized_call,
1785 }1332 => unreachable,
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,
1802 };1333 };
1803}1334}
18041335
...@@ -1841,7 +1372,7 @@ pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool {...@@ -1841,7 +1372,7 @@ pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool {
1841}1372}
18421373
1843pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type {1374pub 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()));
1845}1376}
18461377
1847pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool {1378pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool {
...@@ -1897,10 +1428,7 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {...@@ -1897,10 +1428,7 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {
1897/// For pointer-like optionals, returns true, otherwise returns the allowzero property1428/// For pointer-like optionals, returns true, otherwise returns the allowzero property
1898/// of pointers.1429/// of pointers.
1899pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool {1430pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool {
1900 if (ty.isPtrLikeOptional(zcu)) {1431 return ty.isPtrLikeOptional(zcu) or ty.ptrInfo(zcu).flags.is_allowzero;
1901 return true;
1902 }
1903 return ty.ptrInfo(zcu).flags.is_allowzero;
1904}1432}
19051433
1906/// See also `isPtrLikeOptional`.1434/// See also `isPtrLikeOptional`.
...@@ -1918,7 +1446,6 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool {...@@ -1918,7 +1446,6 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool {
19181446
1919/// Returns true if the type is optional and would be lowered to a single pointer1447/// Returns true if the type is optional and would be lowered to a single pointer
1920/// address value, using 0 for null. Note that this returns true for C pointers.1448/// 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`.
1922pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {1449pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {
1923 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {1450 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1924 .ptr_type => |ptr_type| ptr_type.flags.size == .c,1451 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
...@@ -1947,52 +1474,54 @@ pub fn childTypeIp(ty: Type, ip: *const InternPool) Type {...@@ -1947,52 +1474,54 @@ pub fn childTypeIp(ty: Type, ip: *const InternPool) Type {
1947 return Type.fromInterned(ip.childType(ty.toIntern()));1474 return Type.fromInterned(ip.childType(ty.toIntern()));
1948}1475}
19491476
1950/// For `*[N]T`, returns `T`.1477/// Similar to `childType`, but for pointer-like (or slice-like) optionals, gets the child type
1951/// For `?*T`, returns `T`.1478/// of the *pointer* type. Asserts that `ty` is either a pointer or a pointer-like optional.
1952/// For `?*[N]T`, returns `T`.1479///
1953/// For `?[*]T`, returns `T`.1480/// Essentially, unwraps any one of the following into `T`:
1954/// For `*T`, returns `T`.1481/// ```
1955/// For `[*]T`, returns `T`.1482/// *T ?*T *allowzero T
1956/// For `[N]T`, returns `T`.1483/// [*]T ?[*]T [*]allowzero T
1957/// For `[]T`, returns `T`.1484/// []T ?[]T []allowzero T
1958/// For `anyframe->T`, returns `T`.1485/// [*c]T
1959pub fn elemType2(ty: Type, zcu: *const Zcu) Type {1486/// ```
1960 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {1487/// This is primarily useful in Sema to implement operations which can act on optional pointers.
1961 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1488pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {
1962 .one => Type.fromInterned(ptr_type.child).shallowElemType(zcu),1489 switch (ty.zigTypeTag(zcu)) {
1963 .many, .c, .slice => Type.fromInterned(ptr_type.child),1490 .pointer => return ty.childType(zcu),
1964 },1491 .optional => {
1965 .anyframe_type => |child| {1492 const ptr_ty = ty.childType(zcu);
1966 assert(child != .none);1493 const ptr_info = zcu.intern_pool.indexToKey(ptr_ty.toIntern()).ptr_type;
1967 return Type.fromInterned(child);1494 assert(ptr_info.flags.size != .c);
1495 assert(!ptr_info.flags.is_allowzero);
1496 return .fromInterned(ptr_info.child);
1968 },1497 },
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)),
1972 else => unreachable,1498 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 => {},
1987 }1499 }
1988 const array_type = ip.indexToKey(ptr_type.child).array_type;
1989 return .fromInterned(array_type.child);
1990}1500}
19911501
1992fn shallowElemType(child_ty: Type, zcu: *const Zcu) Type {1502/// Asserts that `ty` is an indexable type, and returns its element type. Tuples (and pointers to
1993 return switch (child_ty.zigTypeTag(zcu)) {1503/// tuples) are not supported because they do not have a single element type.
1994 .array, .vector => child_ty.childType(zcu),1504///
1995 else => child_ty,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,
1996 };1525 };
1997}1526}
19981527
...@@ -2004,61 +1533,54 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type {...@@ -2004,61 +1533,54 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type {
2004 };1533 };
2005}1534}
20061535
2007/// Asserts that the type is an optional.1536/// Asserts that the type is an optional, or a C pointer.
2008/// Note that for C pointers this returns the type unmodified.1537/// For C pointers this returns the type unmodified.
2009pub fn optionalChild(ty: Type, zcu: *const Zcu) Type {1538pub fn optionalChild(ty: Type, zcu: *const Zcu) Type {
2010 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {1539 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
2011 .opt_type => |child| Type.fromInterned(child),1540 .opt_type => |child| return .fromInterned(child),
2012 .ptr_type => |ptr_type| b: {1541 .ptr_type => |ptr_type| {
2013 assert(ptr_type.flags.size == .c);1542 assert(ptr_type.flags.size == .c);
2014 break :b ty;1543 return ty;
2015 },1544 },
2016 else => unreachable,1545 else => unreachable,
2017 };1546 }
2018}1547}
20191548
2020/// Returns the tag type of a union, if the type is a union and it has a tag type.1549/// If `ty` is a tagged union, returns its tag type. Otherwise, returns `null`.
2021/// Otherwise, returns `null`.
2022pub fn unionTagType(ty: Type, zcu: *const Zcu) ?Type {1550pub fn unionTagType(ty: Type, zcu: *const Zcu) ?Type {
1551 assertHasLayout(ty, zcu);
2023 const ip = &zcu.intern_pool;1552 const ip = &zcu.intern_pool;
2024 switch (ip.indexToKey(ty.toIntern())) {1553 switch (ip.indexToKey(ty.toIntern())) {
2025 .union_type => {},1554 .union_type => {},
2026 else => return null,1555 else => return null,
2027 }1556 }
2028 const union_type = ip.loadUnionType(ty.toIntern());1557 const union_obj = ip.loadUnionType(ty.toIntern());
2029 const union_flags = union_type.flagsUnordered(ip);1558 return switch (union_obj.tag_usage) {
2030 switch (union_flags.runtime_tag) {1559 .tagged => .fromInterned(union_obj.enum_tag_type),
2031 .tagged => {1560 .none, .safety => null,
2032 assert(union_flags.status.haveFieldTypes());1561 };
2033 return Type.fromInterned(union_type.enum_tag_ty);
2034 },
2035 else => return null,
2036 }
2037}1562}
20381563
2039/// Same as `unionTagType` but includes safety tag.1564/// If the given union type contains a tag (including a safety tag) in its runtime layout, returns
2040/// Codegen should use this version.1565/// its enum tag type. Otherwise, returns null. Asserts that `ty` is a union type.
2041pub fn unionTagTypeSafety(ty: Type, zcu: *const Zcu) ?Type {1566///
2042 const ip = &zcu.intern_pool;1567/// In general, codegen logic should call this function instead of `unionTagType`.
2043 return switch (ip.indexToKey(ty.toIntern())) {1568pub fn unionTagTypeRuntime(ty: Type, zcu: *const Zcu) ?Type {
2044 .union_type => {1569 assertHasLayout(ty, zcu);
2045 const union_type = ip.loadUnionType(ty.toIntern());1570 const union_type = zcu.intern_pool.loadUnionType(ty.toIntern());
2046 if (!union_type.hasTag(ip)) return null;1571 if (!union_type.has_runtime_tag) return null;
2047 assert(union_type.haveFieldTypes(ip));1572 return .fromInterned(union_type.enum_tag_type);
2048 return Type.fromInterned(union_type.enum_tag_ty);
2049 },
2050 else => null,
2051 };
2052}1573}
20531574
2054/// Asserts the type is a union; returns the tag type, even if the tag will1575/// Asserts that `ty` is a union type, and returns its tag type, even if the tag will not be stored at runtime.
2055/// not be stored at runtime.
2056pub fn unionTagTypeHypothetical(ty: Type, zcu: *const Zcu) Type {1576pub fn unionTagTypeHypothetical(ty: Type, zcu: *const Zcu) Type {
2057 const union_obj = zcu.typeToUnion(ty).?;1577 assertHasLayout(ty, zcu);
2058 return Type.fromInterned(union_obj.enum_tag_ty);1578 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
1579 return .fromInterned(union_obj.enum_tag_type);
2059}1580}
20601581
2061pub fn unionFieldType(ty: Type, enum_tag: Value, zcu: *const Zcu) ?Type {1582pub fn unionFieldType(ty: Type, enum_tag: Value, zcu: *const Zcu) ?Type {
1583 assertHasLayout(ty, zcu);
2062 const ip = &zcu.intern_pool;1584 const ip = &zcu.intern_pool;
2063 const union_obj = zcu.typeToUnion(ty).?;1585 const union_obj = zcu.typeToUnion(ty).?;
2064 const union_fields = union_obj.field_types.get(ip);1586 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 {...@@ -2067,17 +1589,20 @@ pub fn unionFieldType(ty: Type, enum_tag: Value, zcu: *const Zcu) ?Type {
2067}1589}
20681590
2069pub fn unionFieldTypeByIndex(ty: Type, index: usize, zcu: *const Zcu) Type {1591pub fn unionFieldTypeByIndex(ty: Type, index: usize, zcu: *const Zcu) Type {
1592 assertHasLayout(ty, zcu);
2070 const ip = &zcu.intern_pool;1593 const ip = &zcu.intern_pool;
2071 const union_obj = zcu.typeToUnion(ty).?;1594 const union_obj = zcu.typeToUnion(ty).?;
2072 return Type.fromInterned(union_obj.field_types.get(ip)[index]);1595 return Type.fromInterned(union_obj.field_types.get(ip)[index]);
2073}1596}
20741597
2075pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {1598pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {
1599 assertHasLayout(ty, zcu);
2076 const union_obj = zcu.typeToUnion(ty).?;1600 const union_obj = zcu.typeToUnion(ty).?;
2077 return zcu.unionTagFieldIndex(union_obj, enum_tag);1601 return zcu.unionTagFieldIndex(union_obj, enum_tag);
2078}1602}
20791603
2080pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool {1604pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool {
1605 assertHasLayout(ty, zcu);
2081 const ip = &zcu.intern_pool;1606 const ip = &zcu.intern_pool;
2082 const union_obj = zcu.typeToUnion(ty).?;1607 const union_obj = zcu.typeToUnion(ty).?;
2083 for (union_obj.field_types.get(ip)) |field_ty| {1608 for (union_obj.field_types.get(ip)) |field_ty| {
...@@ -2087,17 +1612,21 @@ pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool {...@@ -2087,17 +1612,21 @@ pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool {
2087}1612}
20881613
2089/// Returns the type used for backing storage of this union during comptime operations.1614/// Returns the type used for backing storage of this union during comptime operations.
2090/// Asserts the type is either an extern or packed union.1615/// Asserts the type is an extern union.
2091pub fn unionBackingType(ty: Type, pt: Zcu.PerThread) !Type {1616pub fn externUnionBackingType(ty: Type, pt: Zcu.PerThread) !Type {
2092 const zcu = pt.zcu;1617 const zcu = pt.zcu;
2093 return switch (ty.containerLayout(zcu)) {1618 assertHasLayout(ty, zcu);
2094 .@"extern" => try pt.arrayType(.{ .len = ty.abiSize(zcu), .child = .u8_type }),1619 const loaded_union = zcu.intern_pool.loadUnionType(ty.toIntern());
2095 .@"packed" => try pt.intType(.unsigned, @intCast(ty.bitSize(zcu))),1620 switch (loaded_union.layout) {
1621 .@"extern" => return pt.arrayType(.{ .len = ty.abiSize(zcu), .child = .u8_type }),
1622 .@"packed" => unreachable,
2096 .auto => unreachable,1623 .auto => unreachable,
2097 };1624 }
2098}1625}
20991626
1627/// Asserts that `ty` is a non-packed union type.
2100pub fn unionGetLayout(ty: Type, zcu: *const Zcu) Zcu.UnionLayout {1628pub fn unionGetLayout(ty: Type, zcu: *const Zcu) Zcu.UnionLayout {
1629 assertHasLayout(ty, zcu);
2101 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());1630 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
2102 return Type.getUnionLayout(union_obj, zcu);1631 return Type.getUnionLayout(union_obj, zcu);
2103}1632}
...@@ -2105,9 +1634,18 @@ pub fn unionGetLayout(ty: Type, zcu: *const Zcu) Zcu.UnionLayout {...@@ -2105,9 +1634,18 @@ pub fn unionGetLayout(ty: Type, zcu: *const Zcu) Zcu.UnionLayout {
2105pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayout {1634pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayout {
2106 const ip = &zcu.intern_pool;1635 const ip = &zcu.intern_pool;
2107 return switch (ip.indexToKey(ty.toIntern())) {1636 return switch (ip.indexToKey(ty.toIntern())) {
2108 .struct_type => ip.loadStructType(ty.toIntern()).layout,
2109 .tuple_type => .auto,1637 .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),
2111 else => unreachable,1649 else => unreachable,
2112 };1650 };
2113}1651}
...@@ -2123,6 +1661,11 @@ pub fn errorUnionSet(ty: Type, zcu: *const Zcu) Type {...@@ -2123,6 +1661,11 @@ pub fn errorUnionSet(ty: Type, zcu: *const Zcu) Type {
2123}1661}
21241662
2125/// Returns false for unresolved inferred error sets.1663/// 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!
2126pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {1669pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {
2127 const ip = &zcu.intern_pool;1670 const ip = &zcu.intern_pool;
2128 return switch (ty.toIntern()) {1671 return switch (ty.toIntern()) {
...@@ -2141,6 +1684,11 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {...@@ -2141,6 +1684,11 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {
2141/// Returns true if it is an error set that includes anyerror, false otherwise.1684/// Returns true if it is an error set that includes anyerror, false otherwise.
2142/// Note that the result may be a false negative if the type did not get error set1685/// Note that the result may be a false negative if the type did not get error set
2143/// resolution prior to this call.1686/// 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!
2144pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {1692pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {
2145 const ip = &zcu.intern_pool;1693 const ip = &zcu.intern_pool;
2146 return switch (ty.toIntern()) {1694 return switch (ty.toIntern()) {
...@@ -2163,46 +1711,25 @@ pub fn isError(ty: Type, zcu: *const Zcu) bool {...@@ -2163,46 +1711,25 @@ pub fn isError(ty: Type, zcu: *const Zcu) bool {
2163/// Returns whether ty, which must be an error set, includes an error `name`.1711/// Returns whether ty, which must be an error set, includes an error `name`.
2164/// Might return a false negative if `ty` is an inferred error set and not fully1712/// Might return a false negative if `ty` is an inferred error set and not fully
2165/// resolved yet.1713/// resolved yet.
2166pub fn errorSetHasFieldIp(1714///
2167 ip: *const InternPool,1715/// TODO: this function will behave incorrectly under incremental compilation, because in that case
2168 ty: InternPool.Index,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,
2169 name: InternPool.NullTerminatedString,1721 name: InternPool.NullTerminatedString,
1722 zcu: *const Zcu,
2170) bool {1723) 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 {
2189 const ip = &zcu.intern_pool;1724 const ip = &zcu.intern_pool;
2190 return switch (ty.toIntern()) {1725 return switch (ty.toIntern()) {
2191 .anyerror_type => true,1726 .anyerror_type => true,
2192 else => switch (ip.indexToKey(ty.toIntern())) {1727 else => switch (ip.indexToKey(ty.toIntern())) {
2193 .error_set_type => |error_set_type| {1728 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,
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 },
2198 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {1729 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
2199 .anyerror_type => true,1730 .anyerror_type => true,
2200 .none => false,1731 .none => false,
2201 else => |t| {1732 else => |t| ip.indexToKey(t).error_set_type.nameIndex(ip, name) != null,
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 },
2206 },1733 },
2207 else => unreachable,1734 else => unreachable,
2208 },1735 },
...@@ -2275,12 +1802,12 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {...@@ -2275,12 +1802,12 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {
2275 };1802 };
2276}1803}
22771804
2278/// Returns true for integers, enums, error sets, and packed structs.1805/// Returns true for integers, enums, error sets, and packed structs/unions.
2279/// If this function returns true, then intInfo() can be called on the type.1806/// If this function returns true, then intInfo() can be called on the type.
2280pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool {1807pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool {
2281 return switch (ty.zigTypeTag(zcu)) {1808 return switch (ty.zigTypeTag(zcu)) {
2282 .int, .@"enum", .error_set => true,1809 .int, .@"enum", .error_set => true,
2283 .@"struct" => ty.containerLayout(zcu) == .@"packed",1810 .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed",
2284 else => false,1811 else => false,
2285 };1812 };
2286}1813}
...@@ -2308,8 +1835,17 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -2308,8 +1835,17 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
2308 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong) },1835 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong) },
2309 else => switch (ip.indexToKey(ty.toIntern())) {1836 else => switch (ip.indexToKey(ty.toIntern())) {
2310 .int_type => |int_type| return int_type,1837 .int_type => |int_type| return int_type,
2311 .struct_type => ty = Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntTypeUnordered(ip)),1838 .struct_type => {
2312 .enum_type => ty = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty),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),
2313 .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child),1849 .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child),
23141850
2315 .error_set_type, .inferred_error_set_type => {1851 .error_set_type, .inferred_error_set_type => {
...@@ -2327,7 +1863,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -2327,7 +1863,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
2327 .func_type => unreachable,1863 .func_type => unreachable,
2328 .simple_type => unreachable, // handled via Index enum tag above1864 .simple_type => unreachable, // handled via Index enum tag above
23291865
2330 .union_type => unreachable,
2331 .opaque_type => unreachable,1866 .opaque_type => unreachable,
23321867
2333 // values, not types1868 // values, not types
...@@ -2341,13 +1876,13 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -2341,13 +1876,13 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
2341 .error_union,1876 .error_union,
2342 .enum_literal,1877 .enum_literal,
2343 .enum_tag,1878 .enum_tag,
2344 .empty_enum_value,
2345 .float,1879 .float,
2346 .ptr,1880 .ptr,
2347 .slice,1881 .slice,
2348 .opt,1882 .opt,
2349 .aggregate,1883 .aggregate,
2350 .un,1884 .un,
1885 .bitpack,
2351 // memoization, not types1886 // memoization, not types
2352 .memoized_call,1887 .memoized_call,
2353 => unreachable,1888 => unreachable,
...@@ -2355,25 +1890,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -2355,25 +1890,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
2355 };1890 };
2356}1891}
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
2377/// Returns `false` for `comptime_float`.1893/// Returns `false` for `comptime_float`.
2378pub fn isRuntimeFloat(ty: Type) bool {1894pub fn isRuntimeFloat(ty: Type) bool {
2379 return switch (ty.toIntern()) {1895 return switch (ty.toIntern()) {
...@@ -2488,429 +2004,181 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool {...@@ -2488,429 +2004,181 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool {
2488 };2004 };
2489}2005}
24902006
2491/// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which2007/// If the type's classification is `Class.one_possible_value` (see `classify`), returns the only
2492/// resolves field types rather than asserting they are already resolved.2008/// possible value for the type. Otherwise, returns `null`.
2493pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {2009pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
2494 const zcu = pt.zcu;2010 const zcu = pt.zcu;
2495 const comp = zcu.comp;2011 const comp = zcu.comp;
2496 const gpa = comp.gpa;2012 const gpa = comp.gpa;
2497 const io = comp.io;
2498 const ip = &zcu.intern_pool;2013 const ip = &zcu.intern_pool;
2499 var ty = starting_type;2014 assertHasLayout(ty, zcu);
2500 while (true) switch (ty.toIntern()) {2015 return switch (ip.indexToKey(ty.toIntern())) {
2501 .empty_tuple_type => return Value.empty_tuple,2016 .ptr_type,
25022017 .error_union_type,
2503 else => switch (ip.indexToKey(ty.toIntern())) {2018 .func_type,
2504 .int_type => |int_type| {2019 .anyframe_type,
2505 if (int_type.bits == 0) {2020 .error_set_type,
2506 return try pt.intValue(ty, 0);2021 .inferred_error_set_type,
2507 } else {2022 .opaque_type,
2508 return null;2023 => 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 },
26832024
2684 // values, not types2025 .simple_type => |t| switch (t) {
2685 .undef,2026 .f16,
2686 .simple_value,2027 .f32,
2687 .variable,2028 .f64,
2688 .@"extern",2029 .f80,
2689 .func,2030 .f128,
2690 .int,2031 .usize,
2691 .err,2032 .isize,
2692 .error_union,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,
2693 .enum_literal,2049 .enum_literal,
2694 .enum_tag,2050 .adhoc_inferred_error_set,
2695 .empty_enum_value,2051 .null,
2696 .float,2052 .undefined,
2697 .ptr,2053 .noreturn,
2698 .slice,2054 => null,
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,
27312055
2732 else => switch (ip.indexToKey(ty.toIntern())) {2056 .void => .void,
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),
27502057
2751 .error_set_type,2058 .generic_poison => unreachable,
2752 .inferred_error_set_type,2059 },
2753 => false,
27542060
2755 // These are function bodies, not function pointers.2061 .int_type => |int_type| switch (int_type.bits) {
2756 .func_type => true,2062 0 => try pt.intValue(ty, 0),
27572063 else => null,
2758 .simple_type => |t| switch (t) {2064 },
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 },
28412065
2842 .tuple_type => |tuple| {2066 inline .array_type, .vector_type => |seq_type, seq_tag| {
2843 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {2067 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
2844 const have_comptime_val = val != .none;2068 if (seq_type.len + @intFromBool(has_sentinel) == 0) {
2845 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) return true;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;
2846 }2113 }
2847 return false;2114 const field_ty: Type = .fromInterned(struct_obj.field_types.get(ip)[i]);
2848 },2115 field_val.* = (try field_ty.onePossibleValue(pt)).?.toIntern();
28492116 }
2850 .union_type => {2117 return try pt.aggregateValue(ty, field_vals);
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,
2913 },2118 },
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,
2914 };2182 };
2915}2183}
29162184
...@@ -3056,20 +2324,18 @@ pub fn maxIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {...@@ -3056,20 +2324,18 @@ pub fn maxIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3056/// Asserts the type is an enum or a union.2324/// Asserts the type is an enum or a union.
3057pub fn intTagType(ty: Type, zcu: *const Zcu) Type {2325pub fn intTagType(ty: Type, zcu: *const Zcu) Type {
3058 const ip = &zcu.intern_pool;2326 const ip = &zcu.intern_pool;
3059 return switch (ip.indexToKey(ty.toIntern())) {2327 const enum_ty: Type = switch (ip.indexToKey(ty.toIntern())) {
3060 .union_type => Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty).intTagType(zcu),2328 .union_type => .fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_type),
3061 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty),2329 .enum_type => ty,
3062 else => unreachable,2330 else => unreachable,
3063 };2331 };
2332 return .fromInterned(ip.loadEnumType(enum_ty.toIntern()).int_tag_type);
3064}2333}
30652334
3066pub fn isNonexhaustiveEnum(ty: Type, zcu: *const Zcu) bool {2335pub fn isNonexhaustiveEnum(ty: Type, zcu: *const Zcu) bool {
3067 const ip = &zcu.intern_pool;2336 const ip = &zcu.intern_pool;
3068 return switch (ip.indexToKey(ty.toIntern())) {2337 return switch (ip.indexToKey(ty.toIntern())) {
3069 .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) {2338 .enum_type => ip.loadEnumType(ty.toIntern()).nonexhaustive,
3070 .nonexhaustive => true,
3071 .auto, .explicit => false,
3072 },
3073 else => false,2339 else => false,
3074 };2340 };
3075}2341}
...@@ -3090,28 +2356,33 @@ pub fn errorSetNames(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString....@@ -3090,28 +2356,33 @@ pub fn errorSetNames(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString.
3090}2356}
30912357
3092pub fn enumFields(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString.Slice {2358pub 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;
3094}2361}
30952362
3096pub fn enumFieldCount(ty: Type, zcu: *const Zcu) usize {2363pub 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;
3098}2366}
30992367
3100pub fn enumFieldName(ty: Type, field_index: usize, zcu: *const Zcu) InternPool.NullTerminatedString {2368pub fn enumFieldName(ty: Type, field_index: usize, zcu: *const Zcu) InternPool.NullTerminatedString {
2369 assertHasLayout(ty, zcu);
3101 const ip = &zcu.intern_pool;2370 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];
3103}2372}
31042373
3105pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, zcu: *const Zcu) ?u32 {2374pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, zcu: *const Zcu) ?u32 {
2375 assertHasLayout(ty, zcu);
3106 const ip = &zcu.intern_pool;2376 const ip = &zcu.intern_pool;
3107 const enum_type = ip.loadEnumType(ty.toIntern());2377 const enum_type = ip.loadEnumType(ty.toIntern());
3108 return enum_type.nameIndex(ip, field_name);2378 return enum_type.nameIndex(ip, field_name);
3109}2379}
31102380
3111/// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or2381/// Asserts `ty` is an enum. `enum_tag` can either be the actual enum tag value
3112/// an integer which represents the enum value. Returns the field index in2382/// or an integer which represents the enum value. Returns the field index in
3113/// declaration order, or `null` if `enum_tag` does not match any field.2383/// declaration order, or `null` if `enum_tag` does not match any field.
3114pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {2384pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {
2385 assertHasLayout(ty, zcu);
3115 const ip = &zcu.intern_pool;2386 const ip = &zcu.intern_pool;
3116 const enum_type = ip.loadEnumType(ty.toIntern());2387 const enum_type = ip.loadEnumType(ty.toIntern());
3117 const int_tag = switch (ip.indexToKey(enum_tag.toIntern())) {2388 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 {...@@ -3119,200 +2390,116 @@ pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {
3119 .enum_tag => |info| info.int,2390 .enum_tag => |info| info.int,
3120 else => unreachable,2391 else => unreachable,
3121 };2392 };
3122 assert(ip.typeOf(int_tag) == enum_type.tag_ty);2393 assert(ip.typeOf(int_tag) == enum_type.int_tag_type);
3123 return enum_type.tagValueIndex(ip, int_tag);2394 return enum_type.tagValueIndex(ip, int_tag);
3124}2395}
31252396
3126/// Returns none in the case of a tuple which uses the integer index as the field name.2397/// Returns none in the case of a tuple which uses the integer index as the field name.
3127pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.OptionalNullTerminatedString {2398pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.OptionalNullTerminatedString {
3128 const ip = &zcu.intern_pool;2399 const ip = &zcu.intern_pool;
3129 return switch (ip.indexToKey(ty.toIntern())) {2400 switch (ip.indexToKey(ty.toIntern())) {
3130 .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, index).toOptional(),2401 .struct_type => {
3131 .tuple_type => .none,2402 assertHasLayout(ty, zcu);
2403 return ip.loadStructType(ty.toIntern()).field_names.get(ip)[index].toOptional();
2404 },
2405 .tuple_type => return .none,
3132 else => unreachable,2406 else => unreachable,
3133 };2407 }
3134}2408}
31352409
3136pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {2410pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {
3137 const ip = &zcu.intern_pool;2411 const ip = &zcu.intern_pool;
3138 return switch (ip.indexToKey(ty.toIntern())) {2412 switch (ip.indexToKey(ty.toIntern())) {
3139 .struct_type => ip.loadStructType(ty.toIntern()).field_types.len,2413 .struct_type => {
3140 .tuple_type => |tuple| tuple.types.len,2414 assertHasLayout(ty, zcu);
2415 return ip.loadStructType(ty.toIntern()).field_types.len;
2416 },
2417 .tuple_type => |tuple| return tuple.types.len,
3141 else => unreachable,2418 else => unreachable,
3142 };2419 }
3143}2420}
31442421
3145/// Returns the field type. Supports structs and unions.2422/// Returns the field type. Supports tuples, structs, and unions.
3146pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {2423pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
3147 const ip = &zcu.intern_pool;2424 const ip = &zcu.intern_pool;
3148 return switch (ip.indexToKey(ty.toIntern())) {2425 const types = switch (ip.indexToKey(ty.toIntern())) {
3149 .struct_type => Type.fromInterned(ip.loadStructType(ty.toIntern()).field_types.get(ip)[index]),2426 .struct_type => types: {
3150 .union_type => {2427 assertHasLayout(ty, zcu);
3151 const union_obj = ip.loadUnionType(ty.toIntern());2428 break :types ip.loadStructType(ty.toIntern()).field_types;
3152 return Type.fromInterned(union_obj.field_types.get(ip)[index]);
3153 },2429 },
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,
3155 else => unreachable,2435 else => unreachable,
3156 };2436 };
2437 return .fromInterned(types.get(ip)[index]);
3157}2438}
31582439
3159pub fn fieldAlignment(ty: Type, index: usize, zcu: *Zcu) Alignment {2440/// If an alignment was explicitly specified for the given field of the struct or union type `ty`,
3160 return ty.fieldAlignmentInner(index, .normal, zcu, {}) catch unreachable;2441/// returns that. Otherwise, returns `.none`. This function also supports tuples, for which it
3161}2442/// always returns `.none`.
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.
3170///2443///
3171/// Provide the struct field as the `ty`.2444/// Asserts that the layout of `ty` is resolved, unless `ty` is a tuple.
3172pub fn fieldAlignmentInner(2445pub fn explicitFieldAlignment(ty: Type, index: usize, zcu: *const Zcu) Alignment {
3173 ty: Type,
3174 index: usize,
3175 comptime strat: ResolveStrat,
3176 zcu: strat.ZcuPtr(),
3177 tid: strat.Tid(),
3178) SemaError!Alignment {
3179 const ip = &zcu.intern_pool;2446 const ip = &zcu.intern_pool;
3180 switch (ip.indexToKey(ty.toIntern())) {2447 return switch (ip.indexToKey(ty.toIntern())) {
2448 .tuple_type => .none,
3181 .struct_type => {2449 .struct_type => {
3182 const struct_type = ip.loadStructType(ty.toIntern());2450 assertHasLayout(ty, zcu);
3183 assert(struct_type.layout != .@"packed");2451 const struct_obj = ip.loadStructType(ty.toIntern());
3184 const explicit_align = struct_type.fieldAlign(ip, index);2452 assert(struct_obj.layout != .@"packed");
3185 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);2453 if (struct_obj.field_aligns.len == 0) return .none;
3186 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);2454 return struct_obj.field_aligns.get(ip)[index];
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;
3194 },2455 },
3195 .union_type => {2456 .union_type => {
2457 assertHasLayout(ty, zcu);
3196 const union_obj = ip.loadUnionType(ty.toIntern());2458 const union_obj = ip.loadUnionType(ty.toIntern());
3197 const layout = union_obj.flagsUnordered(ip).layout;2459 assert(union_obj.layout != .@"packed");
3198 assert(layout != .@"packed");2460 if (union_obj.field_aligns.len == 0) return .none;
3199 const explicit_align = union_obj.fieldAlign(ip, index);2461 return union_obj.field_aligns.get(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);
3202 },2462 },
3203 else => unreachable,2463 else => unreachable,
3204 }2464 };
3205}2465}
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).
3208///2470///
3209/// Asserts that all resolution needed was done.2471/// Asserts that the layout of `field_ty` is resolved. Asserts that `layout` is not `.@"packed"`.
3210pub fn structFieldAlignment(2472pub fn defaultStructFieldAlignment(
3211 field_ty: Type,2473 field_ty: Type,
3212 explicit_alignment: InternPool.Alignment,
3213 layout: std.builtin.Type.ContainerLayout,2474 layout: std.builtin.Type.ContainerLayout,
3214 zcu: *Zcu,2475 zcu: *const Zcu,
3215) Alignment {2476) Alignment {
3216 return field_ty.structFieldAlignmentInner(2477 const overalign_big_int = switch (layout) {
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) {
3261 .@"packed" => unreachable,2478 .@"packed" => unreachable,
3262 .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align,2479 .auto => zcu.getTarget().ofmt == .c,
3263 .@"extern" => {},2480 .@"extern" => true,
3264 }2481 };
3265 // extern2482 const abi_align = field_ty.abiAlignment(zcu);
3266 if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {2483 assert(abi_align != .none);
3267 return ty_abi_align.maxStrict(.@"16");2484 if (overalign_big_int and field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {
2485 return abi_align.maxStrict(.@"16");
3268 }2486 }
3269 return ty_abi_align;2487 return 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;
3299}2488}
33002489
3301pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) Value {2490pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value {
3302 const ip = &zcu.intern_pool;2491 const ip = &zcu.intern_pool;
3303 switch (ip.indexToKey(ty.toIntern())) {2492 switch (ip.indexToKey(ty.toIntern())) {
3304 .struct_type => {2493 .struct_type => {
3305 const struct_type = ip.loadStructType(ty.toIntern());2494 const field_defaults = ip.loadStructType(ty.toIntern()).field_defaults.get(ip);
3306 const val = struct_type.fieldInit(ip, index);2495 if (field_defaults.len == 0) return null;
3307 // TODO: avoid using `unreachable` to indicate this.2496 if (field_defaults[index] == .none) return null;
3308 if (val == .none) return Value.@"unreachable";2497 return .fromInterned(field_defaults[index]);
3309 return Value.fromInterned(val);
3310 },2498 },
3311 .tuple_type => |tuple| {2499 .tuple_type => |tuple| {
3312 const val = tuple.values.get(ip)[index];2500 const val = tuple.values.get(ip)[index];
3313 // TODO: avoid using `unreachable` to indicate this.2501 if (val == .none) return null;
3314 if (val == .none) return Value.@"unreachable";2502 return .fromInterned(val);
3315 return Value.fromInterned(val);
3316 },2503 },
3317 else => unreachable,2504 else => unreachable,
3318 }2505 }
...@@ -3324,9 +2511,8 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val...@@ -3324,9 +2511,8 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
3324 switch (ip.indexToKey(ty.toIntern())) {2511 switch (ip.indexToKey(ty.toIntern())) {
3325 .struct_type => {2512 .struct_type => {
3326 const struct_type = ip.loadStructType(ty.toIntern());2513 const struct_type = ip.loadStructType(ty.toIntern());
3327 if (struct_type.fieldIsComptime(ip, index)) {2514 if (struct_type.field_is_comptime_bits.get(ip, index)) {
3328 assert(struct_type.haveFieldInits(ip));2515 return .fromInterned(struct_type.field_defaults.get(ip)[index]);
3329 return Value.fromInterned(struct_type.field_inits.get(ip)[index]);
3330 } else {2516 } else {
3331 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);2517 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);
3332 }2518 }
...@@ -3336,7 +2522,7 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val...@@ -3336,7 +2522,7 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
3336 if (val == .none) {2522 if (val == .none) {
3337 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt);2523 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt);
3338 } else {2524 } else {
3339 return Value.fromInterned(val);2525 return .fromInterned(val);
3340 }2526 }
3341 },2527 },
3342 else => unreachable,2528 else => unreachable,
...@@ -3345,11 +2531,14 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val...@@ -3345,11 +2531,14 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
33452531
3346pub fn structFieldIsComptime(ty: Type, index: usize, zcu: *const Zcu) bool {2532pub fn structFieldIsComptime(ty: Type, index: usize, zcu: *const Zcu) bool {
3347 const ip = &zcu.intern_pool;2533 const ip = &zcu.intern_pool;
3348 return switch (ip.indexToKey(ty.toIntern())) {2534 switch (ip.indexToKey(ty.toIntern())) {
3349 .struct_type => ip.loadStructType(ty.toIntern()).fieldIsComptime(ip, index),2535 .struct_type => {
3350 .tuple_type => |tuple| tuple.values.get(ip)[index] != .none,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,
3351 else => unreachable,2540 else => unreachable,
3352 };2541 }
3353}2542}
33542543
3355pub const FieldOffset = struct {2544pub const FieldOffset = struct {
...@@ -3357,15 +2546,15 @@ pub const FieldOffset = struct {...@@ -3357,15 +2546,15 @@ pub const FieldOffset = struct {
3357 offset: u64,2546 offset: u64,
3358};2547};
33592548
3360/// Supports structs and unions.2549/// Supports structs, tuples, and unions.
3361pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {2550pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
2551 assertHasLayout(ty, zcu);
3362 const ip = &zcu.intern_pool;2552 const ip = &zcu.intern_pool;
3363 switch (ip.indexToKey(ty.toIntern())) {2553 switch (ip.indexToKey(ty.toIntern())) {
3364 .struct_type => {2554 .struct_type => {
3365 const struct_type = ip.loadStructType(ty.toIntern());2555 const struct_type = ip.loadStructType(ty.toIntern());
3366 assert(struct_type.haveLayout(ip));
3367 assert(struct_type.layout != .@"packed");2556 assert(struct_type.layout != .@"packed");
3368 return struct_type.offsets.get(ip)[index];2557 return struct_type.field_offsets.get(ip)[index];
3369 },2558 },
33702559
3371 .tuple_type => |tuple| {2560 .tuple_type => |tuple| {
...@@ -3375,7 +2564,7 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {...@@ -3375,7 +2564,7 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
3375 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {2564 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
3376 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {2565 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {
3377 // comptime field2566 // comptime field
3378 if (i == index) return offset;2567 if (i == index) return 0;
3379 continue;2568 continue;
3380 }2569 }
33812570
...@@ -3391,8 +2580,7 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {...@@ -3391,8 +2580,7 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
33912580
3392 .union_type => {2581 .union_type => {
3393 const union_type = ip.loadUnionType(ty.toIntern());2582 const union_type = ip.loadUnionType(ty.toIntern());
3394 if (!union_type.hasTag(ip))2583 if (!union_type.has_runtime_tag) return 0;
3395 return 0;
3396 const layout = Type.getUnionLayout(union_type, zcu);2584 const layout = Type.getUnionLayout(union_type, zcu);
3397 if (layout.tag_align.compare(.gte, layout.payload_align)) {2585 if (layout.tag_align.compare(.gte, layout.payload_align)) {
3398 // {Tag, Payload}2586 // {Tag, Payload}
...@@ -3414,7 +2602,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {...@@ -3414,7 +2602,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
3414 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {2602 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
3415 .declared => |d| d.zir_index,2603 .declared => |d| d.zir_index,
3416 .reified => |r| r.zir_index,2604 .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,
3418 },2606 },
3419 else => return null,2607 else => return null,
3420 },2608 },
...@@ -3438,8 +2626,8 @@ pub fn isTuple(ty: Type, zcu: *const Zcu) bool {...@@ -3438,8 +2626,8 @@ pub fn isTuple(ty: Type, zcu: *const Zcu) bool {
3438 };2626 };
3439}2627}
34402628
3441/// Traverses optional child types and error union payloads until the type2629/// Traverses optional child types and error union payloads until the type is neither of those.
3442/// is not a pointer. For `E!?u32`, returns `u32`; for `*u8`, returns `*u8`.2630/// For `E!?u32`, returns `u32`; for `*u8`, returns `*u8`.
3443pub fn optEuBaseType(ty: Type, zcu: *const Zcu) Type {2631pub fn optEuBaseType(ty: Type, zcu: *const Zcu) Type {
3444 var cur = ty;2632 var cur = ty;
3445 while (true) switch (cur.zigTypeTag(zcu)) {2633 while (true) switch (cur.zigTypeTag(zcu)) {
...@@ -3485,439 +2673,81 @@ pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.Trac...@@ -3485,439 +2673,81 @@ pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.Trac
3485 const ip = &zcu.intern_pool;2673 const ip = &zcu.intern_pool;
3486 return switch (ip.indexToKey(ty.toIntern())) {2674 return switch (ip.indexToKey(ty.toIntern())) {
3487 .struct_type => ip.loadStructType(ty.toIntern()).zir_index,2675 .struct_type => ip.loadStructType(ty.toIntern()).zir_index,
3488 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,2676 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3489 .enum_type => |e| switch (e) {2677 .enum_type => |e| switch (e) {
3490 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,2678 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3491 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,2679 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
3492 },2680 },
3493 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,2681 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
3494 else => null,2682 else => null,
3495 };2683 };
3496}2684}
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();
38232685
3824 var comptime_err_ret_trace = std.array_list.Managed(Zcu.LazySrcLoc).init(gpa);2686pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3825 defer comptime_err_ret_trace.deinit();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.?;2691 const ip = &zcu.intern_pool;
3828 var sema: Sema = .{2692 const tracked = switch (ip.indexToKey(ty.toIntern())) {
3829 .pt = pt,2693 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
3830 .gpa = gpa,2694 .declared => |d| d.zir_index,
3831 .arena = analysis_arena.allocator(),2695 .reified => |r| r.zir_index,
3832 .code = zir,2696 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
3833 .owner = owner,2697 },
3834 .func_index = .none,2698 else => return null,
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,
3839 };2699 };
3840 defer sema.deinit();2700 const info = tracked.resolveFull(&zcu.intern_pool) orelse return null;
38412701 const file = zcu.fileByIndex(info.file);
3842 (switch (resolution) {2702 const zir = switch (file.getMode()) {
3843 .fields => sema.resolveStructFieldTypes(ty.toIntern(), struct_obj),2703 .zig => file.zir.?,
3844 .inits => sema.resolveStructFieldInits(ty),2704 .zon => return 0,
3845 .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj),2705 };
3846 .layout => sema.resolveStructLayout(ty),2706 const inst = zir.instructions.get(@intFromEnum(info.inst));
3847 .full => sema.resolveStructFully(ty),2707 return switch (inst.tag) {
3848 }) catch |err| switch (err) {2708 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
3849 error.AnalysisFail => {2709 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_line,
3850 if (!zcu.failed_analysis.contains(owner)) {2710 .extended => switch (inst.data.extended.opcode) {
3851 try zcu.transitive_failed_analysis.put(gpa, owner, {});2711 .struct_decl => zir.getStructDecl(info.inst).src_line,
3852 }2712 .union_decl => zir.getUnionDecl(info.inst).src_line,
3853 return error.AnalysisFail;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,
3854 },2719 },
3855 error.OutOfMemory, error.Canceled => |e| return e,2720 else => unreachable,
3856 };2721 };
3857}2722}
38582723
3859/// `ty` must be a union.2724/// Given a namespace type, returns its list of captured values.
3860fn resolveUnionInner(2725pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
3861 ty: Type,2726 const ip = &zcu.intern_pool;
3862 pt: Zcu.PerThread,2727 return switch (ip.indexToKey(ty.toIntern())) {
3863 resolution: enum { fields, alignment, layout, full },2728 .struct_type => ip.loadStructType(ty.toIntern()).captures,
3864) SemaError!void {2729 .union_type => ip.loadUnionType(ty.toIntern()).captures,
3865 const zcu = pt.zcu;2730 .enum_type => ip.loadEnumType(ty.toIntern()).captures,
3866 const gpa = zcu.gpa;2731 .opaque_type => ip.loadOpaqueType(ty.toIntern()).captures,
38672732 else => unreachable,
3868 const union_obj = zcu.typeToUnion(ty).?;2733 };
3869 const owner: InternPool.AnalUnit = .wrap(.{ .type = ty.toIntern() });2734}
3870
3871 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3872 return error.AnalysisFail;
3873 }
38742735
3875 if (zcu.comp.debugIncremental()) {2736pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } {
3876 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, owner);2737 var cur_ty: Type = ty;
3877 info.last_update_gen = zcu.generation;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);
3878 }2742 }
38792743 return .{ cur_ty, cur_len };
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 };
3916}2744}
39172745
2746/// Asserts that `loaded_union.layout` is not `.@"packed"`.
3918pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) Zcu.UnionLayout {2747pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) Zcu.UnionLayout {
2748 assert(loaded_union.layout != .@"packed");
2749
3919 const ip = &zcu.intern_pool;2750 const ip = &zcu.intern_pool;
3920 assert(loaded_union.haveLayout(ip));
3921 var most_aligned_field: u32 = 0;2751 var most_aligned_field: u32 = 0;
3922 var most_aligned_field_align: InternPool.Alignment = .@"1";2752 var most_aligned_field_align: InternPool.Alignment = .@"1";
3923 var most_aligned_field_size: u64 = 0;2753 var most_aligned_field_size: u64 = 0;
...@@ -3928,11 +2758,14 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -3928,11 +2758,14 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
3928 const field_ty: Type = .fromInterned(field_ty_ip_index);2758 const field_ty: Type = .fromInterned(field_ty_ip_index);
3929 if (field_ty.isNoReturn(zcu)) continue;2759 if (field_ty.isNoReturn(zcu)) continue;
39302760
3931 const explicit_align = loaded_union.fieldAlign(ip, field_index);2761 const field_align: InternPool.Alignment = a: {
3932 const field_align = if (explicit_align != .none)2762 const explicit_aligns = loaded_union.field_aligns.get(ip);
3933 explicit_align2763 if (explicit_aligns.len > 0) {
3934 else2764 const a = explicit_aligns[field_index];
3935 field_ty.abiAlignment(zcu);2765 if (a != .none) break :a a;
2766 }
2767 break :a field_ty.abiAlignment(zcu);
2768 };
3936 if (field_ty.hasRuntimeBits(zcu)) {2769 if (field_ty.hasRuntimeBits(zcu)) {
3937 const field_size = field_ty.abiSize(zcu);2770 const field_size = field_ty.abiSize(zcu);
3938 if (field_size > payload_size) {2771 if (field_size > payload_size) {
...@@ -3947,8 +2780,9 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -3947,8 +2780,9 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
3947 }2780 }
3948 payload_align = payload_align.max(field_align);2781 payload_align = payload_align.max(field_align);
3949 }2782 }
3950 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();2783 if (!loaded_union.has_runtime_tag or
3951 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {2784 !Type.fromInterned(loaded_union.enum_tag_type).hasRuntimeBits(zcu))
2785 {
3952 return .{2786 return .{
3953 .abi_size = payload_align.forward(payload_size),2787 .abi_size = payload_align.forward(payload_size),
3954 .abi_align = payload_align,2788 .abi_align = payload_align,
...@@ -3963,10 +2797,10 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -3963,10 +2797,10 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
3963 };2797 };
3964 }2798 }
39652799
3966 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(zcu);2800 const tag_size = Type.fromInterned(loaded_union.enum_tag_type).abiSize(zcu);
3967 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(zcu).max(.@"1");2801 const tag_align = Type.fromInterned(loaded_union.enum_tag_type).abiAlignment(zcu).max(.@"1");
3968 return .{2802 return .{
3969 .abi_size = loaded_union.sizeUnordered(ip),2803 .abi_size = loaded_union.size,
3970 .abi_align = tag_align.max(payload_align),2804 .abi_align = tag_align.max(payload_align),
3971 .most_aligned_field = most_aligned_field,2805 .most_aligned_field = most_aligned_field,
3972 .most_aligned_field_size = most_aligned_field_size,2806 .most_aligned_field_size = most_aligned_field_size,
...@@ -3975,85 +2809,229 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -3975,85 +2809,229 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
3975 .payload_align = payload_align,2809 .payload_align = payload_align,
3976 .tag_align = tag_align,2810 .tag_align = tag_align,
3977 .tag_size = tag_size,2811 .tag_size = tag_size,
3978 .padding = loaded_union.paddingUnordered(ip),2812 .padding = loaded_union.padding,
3979 };2813 };
3980}2814}
39812815
3982/// Returns the type of a pointer to an element.2816/// Asserts that `ptr_ty` is either a many-item pointer, a slice, a C pointer, or a single pointer
3983/// Asserts that the type is a pointer, and that the element type is indexable.2817/// to array (in other words, a pointer which is indexed by pointer arithmetic), and returns the
3984/// If the element index is comptime-known, it must be passed in `offset`.2818/// type of the element pointer at the given index.
3985/// For *@Vector(n, T), return *align(a:b:h:v) T2819///
3986/// For *[N]T, return *T2820/// Asserts that the layout of the pointer element type is resolved.
3987/// For [*]T, returns *T2821///
3988/// For []T, returns *T2822/// If `index` is `null`, the index is an arbitrary runtime-known value.
3989/// Handles const-ness and address spaces in particular.2823pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type {
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 {
3993 const zcu = pt.zcu;2824 const zcu = pt.zcu;
3994 const ptr_info = ptr_ty.ptrInfo(zcu);2825 const ip = &zcu.intern_pool;
3995 const elem_ty = ptr_ty.elemType2(zcu);2826 const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type;
3996 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;2827 const elem_ty: Type = switch (ptr_info.flags.size) {
3997 const parent_ty = ptr_ty.childType(zcu);2828 .slice, .many, .c => .fromInterned(ptr_info.child),
39982829 .one => switch (ip.indexToKey(ptr_info.child)) {
3999 const VI = InternPool.Key.PtrType.VectorIndex;2830 .array_type => |array_type| .fromInterned(array_type.child),
40002831 else => unreachable,
4001 const vector_info: struct {2832 },
4002 host_size: u16 = 0,2833 };
4003 alignment: Alignment = .none,2834 elem_ty.assertHasLayout(zcu);
4004 vector_index: VI = .none,2835 const elem_align: Alignment = switch (elem_ty.classify(zcu)) {
4005 } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .one) blk: {2836 .no_possible_value,
4006 const elem_bits = elem_ty.bitSize(zcu);2837 .one_possible_value,
4007 if (elem_bits == 0) break :blk .{};2838 => ptr_info.flags.alignment,
4008 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);2839
4009 if (!is_packed) break :blk .{};2840 .partially_comptime,
40102841 .fully_comptime,
4011 break :blk .{2842 => switch (ptr_info.flags.alignment) {
4012 .host_size = @intCast(parent_ty.arrayLen(zcu)),2843 .none => .none,
4013 .alignment = parent_ty.abiAlignment(zcu),2844 else => |array_align| .minStrict(array_align, elem_ty.abiAlignment(zcu)),
4014 .vector_index = @enumFromInt(offset.?),2845 },
4015 };2846
4016 } else .{};2847 .runtime => switch (ptr_info.flags.alignment) {
40172848 .none => .none,
4018 const alignment: Alignment = a: {2849 else => |array_align| elem_align: {
4019 // Calculate the new pointer alignment.2850 // If the index is runtime-known, use 1 as it gives the minimum possible alignment.
4020 if (ptr_info.flags.alignment == .none) {2851 const effective_index = index orelse 1;
4021 // In case of an ABI-aligned pointer, any pointer arithmetic2852 if (effective_index == 0) break :elem_align array_align;
4022 // maintains the same ABI-alignedness.2853 const byte_offset = effective_index * elem_ty.abiSize(zcu);
4023 break :a vector_info.alignment;2854 break :elem_align .minStrict(array_align, .fromLog2Units(@ctz(byte_offset)));
4024 }2855 },
4025 // If the addend is not a comptime-known value we can still count on2856 },
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;
4039 };2857 };
4040 return pt.ptrTypeSema(.{2858 return pt.ptrType(.{
4041 .child = elem_ty.toIntern(),2859 .child = elem_ty.toIntern(),
4042 .flags = .{2860 .flags = .{
4043 .alignment = alignment,2861 .size = .one,
4044 .is_const = ptr_info.flags.is_const,2862 .is_const = ptr_info.flags.is_const,
4045 .is_volatile = ptr_info.flags.is_volatile,2863 .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),
4047 .address_space = ptr_info.flags.address_space,2865 .address_space = ptr_info.flags.address_space,
4048 .vector_index = vector_info.vector_index,2866 .alignment = elem_align,
4049 },
4050 .packed_offset = .{
4051 .host_size = vector_info.host_size,
4052 .bit_offset = 0,
4053 },2867 },
4054 });2868 });
4055}2869}
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
4057pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {3035pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
4058 return switch (ip.indexToKey(ty.toIntern())) {3036 return switch (ip.indexToKey(ty.toIntern())) {
4059 .struct_type => ip.loadStructType(ty.toIntern()).name,3037 .struct_type => ip.loadStructType(ty.toIntern()).name,
...@@ -4064,14 +3042,257 @@ pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTermina...@@ -4064,14 +3042,257 @@ pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTermina
4064 };3042 };
4065}3043}
40663044
4067/// Returns `true` if a value of this type is always `null`.3045pub fn destructurable(ty: Type, zcu: *const Zcu) bool {
4068/// Returns `false` if a value of this type is neve `null`.3046 return switch (ty.zigTypeTag(zcu)) {
4069/// Returns `null` otherwise.3047 .array, .vector => true,
4070pub fn isNullFromType(ty: Type, zcu: *const Zcu) ?bool {3048 .@"struct" => ty.isTuple(zcu),
4071 if (ty.zigTypeTag(zcu) != .optional and !ty.isCPtr(zcu)) return false;3049 else => false,
4072 const child = ty.optionalChild(zcu);3050 };
4073 if (child.zigTypeTag(zcu) == .noreturn) return true; // `?noreturn` is always null3051}
4074 return null;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 }
4075}3296}
40763297
4077/// Recursively walks the type and marks for each subtype how many times it has been seen3298/// 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...@@ -4138,13 +3359,13 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn
4138 .error_union,3359 .error_union,
4139 .enum_literal,3360 .enum_literal,
4140 .enum_tag,3361 .enum_tag,
4141 .empty_enum_value,
4142 .float,3362 .float,
4143 .ptr,3363 .ptr,
4144 .slice,3364 .slice,
4145 .opt,3365 .opt,
4146 .aggregate,3366 .aggregate,
4147 .un,3367 .un,
3368 .bitpack,
4148 // memoization, not types3369 // memoization, not types
4149 .memoized_call,3370 .memoized_call,
4150 => unreachable,3371 => unreachable,
...@@ -4243,6 +3464,7 @@ pub const Comparison = struct {...@@ -4243,6 +3464,7 @@ pub const Comparison = struct {
4243 };3464 };
4244};3465};
42453466
3467pub const @"u0": Type = .{ .ip_index = .u0_type };
4246pub const @"u1": Type = .{ .ip_index = .u1_type };3468pub const @"u1": Type = .{ .ip_index = .u1_type };
4247pub const @"u8": Type = .{ .ip_index = .u8_type };3469pub const @"u8": Type = .{ .ip_index = .u8_type };
4248pub const @"u16": Type = .{ .ip_index = .u16_type };3470pub const @"u16": Type = .{ .ip_index = .u16_type };
src/Value.zig+295-897
...@@ -146,80 +146,23 @@ pub fn toType(self: Value) Type {...@@ -146,80 +146,23 @@ pub fn toType(self: Value) Type {
146 return Type.fromInterned(self.toIntern());146 return Type.fromInterned(self.toIntern());
147}147}
148148
149pub fn intFromEnum(val: Value, ty: Type, pt: Zcu.PerThread) Allocator.Error!Value {149pub fn intFromEnum(val: Value, zcu: *const Zcu) Value {
150 const ip = &pt.zcu.intern_pool;150 return .fromInterned(zcu.intern_pool.indexToKey(val.toIntern()).enum_tag.int);
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 };
175}151}
176152
177pub const ResolveStrat = Type.ResolveStrat;153/// Asserts that `val` is an integer.
178154pub fn toBigInt(val: Value, space: *BigIntSpace, zcu: *const Zcu) BigIntConst {
179/// Asserts the value is an integer.155 if (val.getUnsignedInt(zcu)) |x| {
180pub fn toBigInt(val: Value, space: *BigIntSpace, zcu: *Zcu) BigIntConst {156 return BigIntMutable.init(&space.limbs, x).toConst();
181 return val.toBigIntAdvanced(space, .normal, zcu, {}) catch unreachable;157 }
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 {
196 const ip = &zcu.intern_pool;158 const ip = &zcu.intern_pool;
197 return switch (val.toIntern()) {159 const int_key = switch (ip.indexToKey(val.toIntern())) {
198 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),160 .enum_tag => |enum_tag| ip.indexToKey(enum_tag.int).int,
199 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),161 .bitpack => |bitpack| ip.indexToKey(bitpack.backing_int_val).int,
200 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),162 .int => |int| int,
201 else => switch (ip.indexToKey(val.toIntern())) {163 else => unreachable,
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 },
222 };164 };
165 return int_key.storage.toBigInt(space);
223}166}
224167
225pub fn isFuncBody(val: Value, zcu: *Zcu) bool {168pub fn isFuncBody(val: Value, zcu: *Zcu) bool {
...@@ -240,31 +183,17 @@ pub fn getVariable(val: Value, mod: *Zcu) ?InternPool.Key.Variable {...@@ -240,31 +183,17 @@ pub fn getVariable(val: Value, mod: *Zcu) ?InternPool.Key.Variable {
240 };183 };
241}184}
242185
243/// If the value fits in a u64, return it, otherwise null.186/// Asserts the value is a (defined) integer and it fits in a u64.
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
250pub fn toUnsignedInt(val: Value, zcu: *const Zcu) u64 {187pub fn toUnsignedInt(val: Value, zcu: *const Zcu) u64 {
251 return getUnsignedInt(val, zcu).?;188 return getUnsignedInt(val, zcu).?;
252}189}
253190
254pub fn getUnsignedIntSema(val: Value, pt: Zcu.PerThread) !?u64 {
255 return try val.getUnsignedIntInner(.sema, pt.zcu, pt.tid);
256}
257
258/// If the value fits in a u64, return it, otherwise null.191/// If the value fits in a u64, return it, otherwise null.
259/// Asserts not undefined.192/// Asserts not undefined.
260pub fn getUnsignedIntInner(193pub fn getUnsignedInt(val: Value, zcu: *const Zcu) ?u64 {
261 val: Value,
262 comptime strat: ResolveStrat,
263 zcu: strat.ZcuPtr(),
264 tid: strat.Tid(),
265) !?u64 {
266 return switch (val.toIntern()) {194 return switch (val.toIntern()) {
267 .undef => unreachable,195 .undef => unreachable,
196 .null_value => 0,
268 .bool_false => 0,197 .bool_false => 0,
269 .bool_true => 1,198 .bool_true => 1,
270 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {199 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {
...@@ -273,37 +202,28 @@ pub fn getUnsignedIntInner(...@@ -273,37 +202,28 @@ pub fn getUnsignedIntInner(
273 .big_int => |big_int| big_int.toInt(u64) catch null,202 .big_int => |big_int| big_int.toInt(u64) catch null,
274 .u64 => |x| x,203 .u64 => |x| x,
275 .i64 => |x| std.math.cast(u64, x),204 .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,
278 },205 },
279 .ptr => |ptr| switch (ptr.base_addr) {206 .ptr => |ptr| switch (ptr.base_addr) {
280 .int => ptr.byte_offset,207 .int => ptr.byte_offset,
281 .field => |field| {208 .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;
283 const struct_ty = Value.fromInterned(field.base).typeOf(zcu).childType(zcu);210 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 }
288 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), zcu) + ptr.byte_offset;211 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), zcu) + ptr.byte_offset;
289 },212 },
290 else => null,213 else => null,
291 },214 },
292 .opt => |opt| switch (opt.val) {215 .opt => |opt| switch (opt.val) {
293 .none => 0,216 .none => 0,
294 else => |payload| Value.fromInterned(payload).getUnsignedIntInner(strat, zcu, tid),217 else => |payload| Value.fromInterned(payload).getUnsignedInt(zcu),
295 },218 },
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).?,
297 else => null,222 else => null,
298 },223 },
299 };224 };
300}225}
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
307/// Asserts the value is an integer and it fits in a i64227/// Asserts the value is an integer and it fits in a i64
308pub fn toSignedInt(val: Value, zcu: *const Zcu) i64 {228pub fn toSignedInt(val: Value, zcu: *const Zcu) i64 {
309 return switch (val.toIntern()) {229 return switch (val.toIntern()) {
...@@ -314,8 +234,6 @@ pub fn toSignedInt(val: Value, zcu: *const Zcu) i64 {...@@ -314,8 +234,6 @@ pub fn toSignedInt(val: Value, zcu: *const Zcu) i64 {
314 .big_int => |big_int| big_int.toInt(i64) catch unreachable,234 .big_int => |big_int| big_int.toInt(i64) catch unreachable,
315 .i64 => |x| x,235 .i64 => |x| x,
316 .u64 => |x| @intCast(x),236 .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)),
319 },237 },
320 else => unreachable,238 else => unreachable,
321 },239 },
...@@ -393,7 +311,7 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{...@@ -393,7 +311,7 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
393 // We use byte_count instead of abi_size here, so that any padding bytes311 // We use byte_count instead of abi_size here, so that any padding bytes
394 // follow the data bytes, on both big- and little-endian systems.312 // follow the data bytes, on both big- and little-endian systems.
395 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;313 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);
397 },315 },
398 .@"struct" => {316 .@"struct" => {
399 const struct_type = zcu.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout;317 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{...@@ -412,8 +330,8 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
412 try writeToMemory(field_val, pt, buffer[off..]);330 try writeToMemory(field_val, pt, buffer[off..]);
413 },331 },
414 .@"packed" => {332 .@"packed" => {
415 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;333 const int_index = ip.indexToKey(val.toIntern()).bitpack.backing_int_val;
416 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);334 return Value.fromInterned(int_index).writeToMemory(pt, buffer);
417 },335 },
418 }336 }
419 },337 },
...@@ -428,15 +346,14 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{...@@ -428,15 +346,14 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
428 const byte_count: usize = @intCast(field_type.abiSize(zcu));346 const byte_count: usize = @intCast(field_type.abiSize(zcu));
429 return writeToMemory(field_val, pt, buffer[0..byte_count]);347 return writeToMemory(field_val, pt, buffer[0..byte_count]);
430 } else {348 } else {
431 const backing_ty = try ty.unionBackingType(pt);349 const backing_ty = try ty.externUnionBackingType(pt);
432 const byte_count: usize = @intCast(backing_ty.abiSize(zcu));350 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]);
434 }352 }
435 },353 },
436 .@"packed" => {354 .@"packed" => {
437 const backing_ty = try ty.unionBackingType(pt);355 const int_val: Value = .fromInterned(ip.indexToKey(val.toIntern()).bitpack.backing_int_val);
438 const byte_count: usize = @intCast(backing_ty.abiSize(zcu));356 return writeToMemory(int_val, pt, buffer);
439 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
440 },357 },
441 },358 },
442 .optional => {359 .optional => {
...@@ -458,7 +375,6 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{...@@ -458,7 +375,6 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
458/// big-endian packed memory layouts start at the end of the buffer.375/// big-endian packed memory layouts start at the end of the buffer.
459pub fn writeToPackedMemory(376pub fn writeToPackedMemory(
460 val: Value,377 val: Value,
461 ty: Type,
462 pt: Zcu.PerThread,378 pt: Zcu.PerThread,
463 buffer: []u8,379 buffer: []u8,
464 bit_offset: usize,380 bit_offset: usize,
...@@ -467,6 +383,7 @@ pub fn writeToPackedMemory(...@@ -467,6 +383,7 @@ pub fn writeToPackedMemory(
467 const ip = &zcu.intern_pool;383 const ip = &zcu.intern_pool;
468 const target = zcu.getTarget();384 const target = zcu.getTarget();
469 const endian = target.cpu.arch.endian();385 const endian = target.cpu.arch.endian();
386 const ty = val.typeOf(zcu);
470 if (val.isUndef(zcu)) {387 if (val.isUndef(zcu)) {
471 const bit_size: usize = @intCast(ty.bitSize(zcu));388 const bit_size: usize = @intCast(ty.bitSize(zcu));
472 if (bit_size != 0) {389 if (bit_size != 0) {
...@@ -487,22 +404,22 @@ pub fn writeToPackedMemory(...@@ -487,22 +404,22 @@ pub fn writeToPackedMemory(
487 buffer[byte_index] &= ~(@as(u8, 1) << @as(u3, @intCast(bit_offset % 8)));404 buffer[byte_index] &= ~(@as(u8, 1) << @as(u3, @intCast(bit_offset % 8)));
488 }405 }
489 },406 },
490 .int, .@"enum" => {407 .@"enum" => {
491 if (buffer.len == 0) return;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 => {
492 const bits = ty.intInfo(zcu).bits;418 const bits = ty.intInfo(zcu).bits;
493 if (bits == 0) return;419 if (bits == 0 or buffer.len == 0) return;
494420 switch (ip.indexToKey(val.toIntern()).int.storage) {
495 switch (ip.indexToKey((try val.intFromEnum(ty, pt)).toIntern()).int.storage) {
496 inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),421 inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),
497 .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),422 .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 },
506 }423 }
507 },424 },
508 .float => switch (ty.floatBits(target)) {425 .float => switch (ty.floatBits(target)) {
...@@ -524,58 +441,21 @@ pub fn writeToPackedMemory(...@@ -524,58 +441,21 @@ pub fn writeToPackedMemory(
524 // On big-endian systems, LLVM reverses the element order of vectors by default441 // On big-endian systems, LLVM reverses the element order of vectors by default
525 const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i;442 const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i;
526 const elem_val = try val.elemValue(pt, tgt_elem_i);443 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);
528 bits += elem_bit_size;445 bits += elem_bit_size;
529 }446 }
530 },447 },
531 .@"struct" => {448 .@"struct", .@"union" => {
532 const struct_type = ip.loadStructType(ty.toIntern());449 assert(ty.containerLayout(zcu) == .@"packed");
533 // Sema is supposed to have emitted a compile error already in the case of Auto,450 const int_val: Value = .fromInterned(ip.indexToKey(val.toIntern()).bitpack.backing_int_val);
534 // and Extern is handled in non-packed writeToMemory.451 return int_val.writeToPackedMemory(pt, buffer, bit_offset);
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);
570 },452 },
571 .optional => {453 .optional => {
572 assert(ty.isPtrLikeOptional(zcu));454 assert(ty.isPtrLikeOptional(zcu));
573 const child = ty.optionalChild(zcu);455 if (val.optionalValue(zcu)) |ptr_val| {
574 const opt_val = val.optionalValue(zcu);456 return ptr_val.writeToPackedMemory(pt, buffer, bit_offset);
575 if (opt_val) |some| {
576 return some.writeToPackedMemory(child, pt, buffer, bit_offset);
577 } else {457 } 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);
579 }459 }
580 },460 },
581 else => @panic("TODO implement writeToPackedMemory for more types"),461 else => @panic("TODO implement writeToPackedMemory for more types"),
...@@ -625,13 +505,12 @@ pub fn readFromPackedMemory(...@@ -625,13 +505,12 @@ pub fn readFromPackedMemory(
625 pt: Zcu.PerThread,505 pt: Zcu.PerThread,
626 buffer: []const u8,506 buffer: []const u8,
627 bit_offset: usize,507 bit_offset: usize,
628 arena: Allocator,508 gpa: Allocator,
629) error{509) error{
630 IllDefinedMemoryLayout,510 IllDefinedMemoryLayout,
631 OutOfMemory,511 OutOfMemory,
632}!Value {512}!Value {
633 const zcu = pt.zcu;513 const zcu = pt.zcu;
634 const ip = &zcu.intern_pool;
635 const target = zcu.getTarget();514 const target = zcu.getTarget();
636 const endian = target.cpu.arch.endian();515 const endian = target.cpu.arch.endian();
637 switch (ty.zigTypeTag(zcu)) {516 switch (ty.zigTypeTag(zcu)) {
...@@ -665,7 +544,8 @@ pub fn readFromPackedMemory(...@@ -665,7 +544,8 @@ pub fn readFromPackedMemory(
665 const abi_size: usize = @intCast(ty.abiSize(zcu));544 const abi_size: usize = @intCast(ty.abiSize(zcu));
666 const Limb = std.math.big.Limb;545 const Limb = std.math.big.Limb;
667 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);546 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
670 var bigint = BigIntMutable.init(limbs_buffer, 0);550 var bigint = BigIntMutable.init(limbs_buffer, 0);
671 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);551 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);
...@@ -673,7 +553,7 @@ pub fn readFromPackedMemory(...@@ -673,7 +553,7 @@ pub fn readFromPackedMemory(
673 },553 },
674 .@"enum" => {554 .@"enum" => {
675 const int_ty = ty.intTagType(zcu);555 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);
677 return pt.getCoerced(int_val, ty);557 return pt.getCoerced(int_val, ty);
678 },558 },
679 .float => return Value.fromInterned(try pt.intern(.{ .float = .{559 .float => return Value.fromInterned(try pt.intern(.{ .float = .{
...@@ -689,64 +569,35 @@ pub fn readFromPackedMemory(...@@ -689,64 +569,35 @@ pub fn readFromPackedMemory(
689 } })),569 } })),
690 .vector => {570 .vector => {
691 const elem_ty = ty.childType(zcu);571 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
694 var bits: u16 = 0;575 var bits: u16 = 0;
695 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(zcu));576 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(zcu));
696 for (elems, 0..) |_, i| {577 for (elems, 0..) |_, i| {
697 // On big-endian systems, LLVM reverses the element order of vectors by default578 // On big-endian systems, LLVM reverses the element order of vectors by default
698 const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i;579 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();
700 bits += elem_bit_size;581 bits += elem_bit_size;
701 }582 }
702 return pt.aggregateValue(ty, elems);583 return pt.aggregateValue(ty, elems);
703 },584 },
704 .@"struct" => {585 .@"struct", .@"union" => {
705 // Sema is supposed to have emitted a compile error already for Auto layout structs,586 assert(ty.containerLayout(zcu) == .@"packed");
706 // and Extern is handled by non-packed readFromMemory.587 const int_val: Value = try .readFromPackedMemory(ty.bitpackBackingInt(zcu), pt, buffer, bit_offset, gpa);
707 const struct_type = zcu.typeToPackedStruct(ty).?;588 return pt.bitpackValue(ty, int_val);
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 },
729 },589 },
730 .pointer => {590 .pointer => {
731 assert(!ty.isSlice(zcu)); // No well defined layout.591 assert(!ty.isSlice(zcu)); // No well defined layout.
732 const int_val = try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, arena);592 const addr = (try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, gpa)).toUnsignedInt(zcu);
733 return Value.fromInterned(try pt.intern(.{ .ptr = .{593 return pt.ptrIntValue(ty, addr);
734 .ty = ty.toIntern(),
735 .base_addr = .int,
736 .byte_offset = int_val.toUnsignedInt(zcu),
737 } }));
738 },594 },
739 .optional => {595 .optional => {
740 assert(ty.isPtrLikeOptional(zcu));596 assert(ty.isPtrLikeOptional(zcu));
741 const child_ty = ty.optionalChild(zcu);597 const addr = (try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, gpa)).toUnsignedInt(zcu);
742 const child_val = try readFromPackedMemory(child_ty, pt, buffer, bit_offset, arena);598 return .fromInterned(try pt.intern(.{ .opt = .{
743 return Value.fromInterned(try pt.intern(.{ .opt = .{
744 .ty = ty.toIntern(),599 .ty = ty.toIntern(),
745 .val = switch (child_val.orderAgainstZero(zcu)) {600 .val = if (addr == 0) .none else (try pt.ptrIntValue(ty.childType(zcu), addr)).toIntern(),
746 .lt => unreachable,
747 .eq => .none,
748 .gt => child_val.toIntern(),
749 },
750 } }));601 } }));
751 },602 },
752 else => @panic("TODO implement readFromPackedMemory for more types"),603 else => @panic("TODO implement readFromPackedMemory for more types"),
...@@ -764,8 +615,6 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T {...@@ -764,8 +615,6 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T {
764 }615 }
765 return @floatFromInt(x);616 return @floatFromInt(x);
766 },617 },
767 .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0),
768 .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(zcu)),
769 },618 },
770 .float => |float| switch (float.storage) {619 .float => |float| switch (float.storage) {
771 inline else => |x| @floatCast(x),620 inline else => |x| @floatCast(x),
...@@ -819,110 +668,8 @@ pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value {...@@ -819,110 +668,8 @@ pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value {
819 } }));668 } }));
820}669}
821670
822pub fn orderAgainstZero(lhs: Value, zcu: *Zcu) std.math.Order {671/// Asserts the value is comparable. Supports comparisons between heterogeneous types.
823 return orderAgainstZeroInner(lhs, .normal, zcu, {}) catch unreachable;672pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, zcu: *const Zcu) bool {
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 {
926 if (lhs.pointerNav(zcu)) |lhs_nav| {673 if (lhs.pointerNav(zcu)) |lhs_nav| {
927 if (rhs.pointerNav(zcu)) |rhs_nav| {674 if (rhs.pointerNav(zcu)) |rhs_nav| {
928 switch (op) {675 switch (op) {
...@@ -944,9 +691,21 @@ pub fn compareHeteroAdvanced(...@@ -944,9 +691,21 @@ pub fn compareHeteroAdvanced(
944 else => {},691 else => {},
945 }692 }
946 }693 }
947
948 if (lhs.isNan(zcu) or rhs.isNan(zcu)) return op == .neq;694 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);
950}709}
951710
952/// Asserts the values are comparable. Both operands have type `ty`.711/// Asserts the values are comparable. Both operands have type `ty`.
...@@ -988,55 +747,30 @@ pub fn compareScalar(...@@ -988,55 +747,30 @@ pub fn compareScalar(
988///747///
989/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`748/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
990pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, zcu: *Zcu) bool {749pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, zcu: *Zcu) bool {
991 return compareAllWithZeroAdvancedExtra(lhs, op, .normal, zcu, {}) catch unreachable;750 return switch (zcu.intern_pool.indexToKey(lhs.toIntern())) {
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())) {
1019 .float => |float| switch (float.storage) {751 .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),
1021 },753 },
1022 .aggregate => |aggregate| return switch (aggregate.storage) {754 .aggregate => |aggregate| switch (aggregate.storage) {
1023 .bytes => |bytes| for (bytes.toSlice(lhs.typeOf(zcu).arrayLenIncludingSentinel(zcu), &zcu.intern_pool)) |byte| {755 .bytes => |bytes| for (bytes.toSlice(
1024 if (!std.math.order(byte, 0).compare(op)) break false;756 lhs.typeOf(zcu).arrayLenIncludingSentinel(zcu),
757 &zcu.intern_pool,
758 )) |byte| {
759 if (!std.math.compare(byte, op, 0)) break false;
1025 } else true,760 } else true,
1026 .elems => |elems| for (elems) |elem| {761 .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;
1028 } else true,763 } else true,
1029 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, strat, zcu, tid),764 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZero(op, zcu),
1030 },765 },
1031 .undef => return false,766 .undef => false,
1032 else => {},767 else => order(lhs, .zero_comptime_int, zcu).compare(op),
1033 }768 };
1034 return (try orderAgainstZeroInner(lhs, strat, zcu, tid)).compare(op);
1035}769}
1036770
1037pub fn eql(a: Value, b: Value, ty: Type, zcu: *Zcu) bool {771pub fn eql(a: Value, b: Value, ty: Type, zcu: *Zcu) bool {
1038 assert(zcu.intern_pool.typeOf(a.toIntern()) == ty.toIntern());772 assert(a.typeOf(zcu).toIntern() == ty.toIntern());
1039 assert(zcu.intern_pool.typeOf(b.toIntern()) == ty.toIntern());773 assert(b.typeOf(zcu).toIntern() == ty.toIntern());
1040 return a.toIntern() == b.toIntern();774 return a.toIntern() == b.toIntern();
1041}775}
1042776
...@@ -1071,7 +805,7 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {...@@ -1071,7 +805,7 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {
1071/// Gets the `Nav` referenced by this pointer. If the pointer does not point805/// Gets the `Nav` referenced by this pointer. If the pointer does not point
1072/// to a `Nav`, or if it points to some part of one (like a field or element),806/// to a `Nav`, or if it points to some part of one (like a field or element),
1073/// returns null.807/// returns null.
1074pub fn pointerNav(val: Value, zcu: *Zcu) ?InternPool.Nav.Index {808pub fn pointerNav(val: Value, zcu: *const Zcu) ?InternPool.Nav.Index {
1075 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {809 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1076 // TODO: these 3 cases are weird; these aren't pointer values!810 // TODO: these 3 cases are weird; these aren't pointer values!
1077 .variable => |v| v.owner_nav,811 .variable => |v| v.owner_nav,
...@@ -1088,16 +822,13 @@ pub fn pointerNav(val: Value, zcu: *Zcu) ?InternPool.Nav.Index {...@@ -1088,16 +822,13 @@ pub fn pointerNav(val: Value, zcu: *Zcu) ?InternPool.Nav.Index {
1088pub const slice_ptr_index = 0;822pub const slice_ptr_index = 0;
1089pub const slice_len_index = 1;823pub 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}
1091pub fn slicePtr(val: Value, zcu: *Zcu) Value {828pub fn slicePtr(val: Value, zcu: *Zcu) Value {
1092 return Value.fromInterned(zcu.intern_pool.slicePtr(val.toIntern()));829 return Value.fromInterned(zcu.intern_pool.slicePtr(val.toIntern()));
1093}830}
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
1101/// Asserts the value is an aggregate, and returns the element value at the given index.832/// Asserts the value is an aggregate, and returns the element value at the given index.
1102pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Value {833pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Value {
1103 const zcu = pt.zcu;834 const zcu = pt.zcu;
...@@ -1123,62 +854,6 @@ pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Va...@@ -1123,62 +854,6 @@ pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Va
1123 }854 }
1124}855}
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
1182pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {857pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1183 const zcu = pt.zcu;858 const zcu = pt.zcu;
1184 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {859 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
...@@ -1193,8 +868,44 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {...@@ -1193,8 +868,44 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1193 .elems => |elems| elems[index],868 .elems => |elems| elems[index],
1194 .repeated_elem => |elem| elem,869 .repeated_elem => |elem| elem,
1195 }),870 }),
1196 // TODO assert the tag is correct871 .un => |un| {
1197 .un => |un| Value.fromInterned(un.val),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 },
1198 else => unreachable,909 else => unreachable,
1199 };910 };
1200}911}
...@@ -1207,7 +918,7 @@ pub fn unionTag(val: Value, zcu: *Zcu) ?Value {...@@ -1207,7 +918,7 @@ pub fn unionTag(val: Value, zcu: *Zcu) ?Value {
1207 };918 };
1208}919}
1209920
1210pub fn unionValue(val: Value, zcu: *Zcu) Value {921pub fn unionPayload(val: Value, zcu: *Zcu) Value {
1211 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {922 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1212 .un => |un| Value.fromInterned(un.val),923 .un => |un| Value.fromInterned(un.val),
1213 else => unreachable,924 else => unreachable,
...@@ -1334,63 +1045,6 @@ pub fn isFloat(self: Value, zcu: *const Zcu) bool {...@@ -1334,63 +1045,6 @@ pub fn isFloat(self: Value, zcu: *const Zcu) bool {
1334 };1045 };
1335}1046}
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
1394fn calcLimbLenFloat(scalar: anytype) usize {1048fn calcLimbLenFloat(scalar: anytype) usize {
1395 if (scalar == 0) {1049 if (scalar == 0) {
1396 return 1;1050 return 1;
...@@ -1410,11 +1064,11 @@ pub fn numberMax(lhs: Value, rhs: Value, zcu: *Zcu) Value {...@@ -1410,11 +1064,11 @@ pub fn numberMax(lhs: Value, rhs: Value, zcu: *Zcu) Value {
1410 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef;1064 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef;
1411 if (lhs.isNan(zcu)) return rhs;1065 if (lhs.isNan(zcu)) return rhs;
1412 if (rhs.isNan(zcu)) return lhs;1066 if (rhs.isNan(zcu)) return lhs;
14131067 if (compareHetero(lhs, .gt, rhs, zcu)) {
1414 return switch (order(lhs, rhs, zcu)) {1068 return lhs;
1415 .lt => rhs,1069 } else {
1416 .gt, .eq => lhs,1070 return rhs;
1417 };1071 }
1418}1072}
14191073
1420/// Supports both floats and ints; handles undefined.1074/// Supports both floats and ints; handles undefined.
...@@ -1422,11 +1076,11 @@ pub fn numberMin(lhs: Value, rhs: Value, zcu: *Zcu) Value {...@@ -1422,11 +1076,11 @@ pub fn numberMin(lhs: Value, rhs: Value, zcu: *Zcu) Value {
1422 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef;1076 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef;
1423 if (lhs.isNan(zcu)) return rhs;1077 if (lhs.isNan(zcu)) return rhs;
1424 if (rhs.isNan(zcu)) return lhs;1078 if (rhs.isNan(zcu)) return lhs;
14251079 if (compareHetero(lhs, .lt, rhs, zcu)) {
1426 return switch (order(lhs, rhs, zcu)) {1080 return lhs;
1427 .lt => lhs,1081 } else {
1428 .gt, .eq => rhs,1082 return rhs;
1429 };1083 }
1430}1084}
14311085
1432/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.1086/// 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 {...@@ -2033,8 +1687,6 @@ pub fn makeBool(x: bool) Value {
2033/// `parent_ptr` must be a single-pointer or C pointer to some optional.1687/// `parent_ptr` must be a single-pointer or C pointer to some optional.
2034///1688///
2035/// Returns a pointer to the payload of the optional.1689/// Returns a pointer to the payload of the optional.
2036///
2037/// May perform type resolution.
2038pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {1690pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
2039 const zcu = pt.zcu;1691 const zcu = pt.zcu;
2040 const parent_ptr_ty = parent_ptr.typeOf(zcu);1692 const parent_ptr_ty = parent_ptr.typeOf(zcu);
...@@ -2044,7 +1696,7 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {...@@ -2044,7 +1696,7 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
2044 assert(ptr_size == .one or ptr_size == .c);1696 assert(ptr_size == .one or ptr_size == .c);
2045 assert(opt_ty.zigTypeTag(zcu) == .optional);1697 assert(opt_ty.zigTypeTag(zcu) == .optional);
20461698
2047 const result_ty = try pt.ptrTypeSema(info: {1699 const result_ty = try pt.ptrType(info: {
2048 var new = parent_ptr_ty.ptrInfo(zcu);1700 var new = parent_ptr_ty.ptrInfo(zcu);
2049 // We can correctly preserve alignment `.none`, since an optional has the same1701 // We can correctly preserve alignment `.none`, since an optional has the same
2050 // natural alignment as its child type.1702 // natural alignment as its child type.
...@@ -2060,7 +1712,7 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {...@@ -2060,7 +1712,7 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
2060 }1712 }
20611713
2062 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, opt_ty, pt);1714 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 = .{
2064 .ty = result_ty.toIntern(),1716 .ty = result_ty.toIntern(),
2065 .base_addr = .{ .opt_payload = base_ptr.toIntern() },1717 .base_addr = .{ .opt_payload = base_ptr.toIntern() },
2066 .byte_offset = 0,1718 .byte_offset = 0,
...@@ -2069,7 +1721,6 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {...@@ -2069,7 +1721,6 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20691721
2070/// `parent_ptr` must be a single-pointer to some error union.1722/// `parent_ptr` must be a single-pointer to some error union.
2071/// Returns a pointer to the payload of the error union.1723/// Returns a pointer to the payload of the error union.
2072/// May perform type resolution.
2073pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {1724pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
2074 const zcu = pt.zcu;1725 const zcu = pt.zcu;
2075 const parent_ptr_ty = parent_ptr.typeOf(zcu);1726 const parent_ptr_ty = parent_ptr.typeOf(zcu);
...@@ -2078,7 +1729,7 @@ pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {...@@ -2078,7 +1729,7 @@ pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
2078 assert(parent_ptr_ty.ptrSize(zcu) == .one);1729 assert(parent_ptr_ty.ptrSize(zcu) == .one);
2079 assert(eu_ty.zigTypeTag(zcu) == .error_union);1730 assert(eu_ty.zigTypeTag(zcu) == .error_union);
20801731
2081 const result_ty = try pt.ptrTypeSema(info: {1732 const result_ty = try pt.ptrType(info: {
2082 var new = parent_ptr_ty.ptrInfo(zcu);1733 var new = parent_ptr_ty.ptrInfo(zcu);
2083 // We can correctly preserve alignment `.none`, since an error union has a1734 // We can correctly preserve alignment `.none`, since an error union has a
2084 // natural alignment greater than or equal to that of its payload type.1735 // 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 {...@@ -2089,147 +1740,57 @@ pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
2089 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);1740 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
20901741
2091 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, eu_ty, pt);1742 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 = .{
2093 .ty = result_ty.toIntern(),1744 .ty = result_ty.toIntern(),
2094 .base_addr = .{ .eu_payload = base_ptr.toIntern() },1745 .base_addr = .{ .eu_payload = base_ptr.toIntern() },
2095 .byte_offset = 0,1746 .byte_offset = 0,
2096 } }));1747 } }));
2097}1748}
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.
2100///1751///
2101/// Returns a pointer to the aggregate field at the specified index.1752/// Returns a pointer to the aggregate field at the specified index.
2102///1753///
2103/// For slices, uses `slice_ptr_index` and `slice_len_index`.1754/// For slices, uses `slice_ptr_index` and `slice_len_index`.
2104///1755///
2105/// May perform type resolution.1756/// Asserts that the layout of the aggregate type is resolved.
2106pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {1757pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
2107 const zcu = pt.zcu;1758 const zcu = pt.zcu;
2108 const parent_ptr_ty = parent_ptr.typeOf(zcu);1759 const parent_ptr_ty = parent_ptr.typeOf(zcu);
2109 const aggregate_ty = parent_ptr_ty.childType(zcu);1760 const aggregate_ty = parent_ptr_ty.childType(zcu);
1761 aggregate_ty.assertHasLayout(zcu);
21101762
2111 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);1763 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
2112 assert(parent_ptr_info.flags.size == .one or parent_ptr_info.flags.size == .c);1764 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.1766 const field_ptr_ty = try parent_ptr_ty.fieldPtrType(field_idx, pt);
2115 // `field_align` may be `.none` to represent the natural alignment of `field_ty`, but is not necessarily.1767
2116 const field_ty: Type, const field_align: InternPool.Alignment = switch (aggregate_ty.zigTypeTag(zcu)) {1768 switch (aggregate_ty.zigTypeTag(zcu)) {
2117 .@"struct" => field: {1769 .pointer => assert(aggregate_ty.isSlice(zcu)),
2118 const field_ty = aggregate_ty.fieldType(field_idx, zcu);1770 .@"struct" => switch (aggregate_ty.containerLayout(zcu)) {
2119 switch (aggregate_ty.containerLayout(zcu)) {1771 .auto => {},
2120 .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },1772 .@"extern" => return parent_ptr.getOffsetPtr(
2121 .@"extern" => {1773 aggregate_ty.structFieldOffset(field_idx, zcu),
2122 // Well-defined layout, so just offset the pointer appropriately.1774 field_ptr_ty,
2123 try aggregate_ty.resolveLayout(pt);1775 pt,
2124 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);1776 ),
2125 const field_align = a: {1777 .@"packed" => return pt.getCoerced(parent_ptr, field_ptr_ty),
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 }
2201 },1778 },
2202 .pointer => field_ty: {1779 .@"union" => switch (aggregate_ty.containerLayout(zcu)) {
2203 assert(aggregate_ty.isSlice(zcu));1780 .auto => {},
2204 break :field_ty switch (field_idx) {1781 .@"packed", .@"extern" => return pt.getCoerced(parent_ptr, field_ptr_ty),
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 };
2209 },1782 },
2210 else => unreachable,1783 else => unreachable,
2211 };1784 }
22121785
2213 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {1786 // If we get here, we need to use the `.field` comptime pointer representation, because the
2214 const ty_align = (try field_ty.abiAlignmentInner(.sema, zcu, pt.tid)).scalar;1787 // aggregate does not have a well-defined layout.
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 });
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
2230 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, aggregate_ty, pt);1791 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, aggregate_ty, pt);
2231 return Value.fromInterned(try pt.intern(.{ .ptr = .{1792 return .fromInterned(try pt.intern(.{ .ptr = .{
2232 .ty = result_ty.toIntern(),1793 .ty = field_ptr_ty.toIntern(),
2233 .base_addr = .{ .field = .{1794 .base_addr = .{ .field = .{
2234 .base = base_ptr.toIntern(),1795 .base = base_ptr.toIntern(),
2235 .index = field_idx,1796 .index = field_idx,
...@@ -2238,9 +1799,9 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {...@@ -2238,9 +1799,9 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
2238 } }));1799 } }));
2239}1800}
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.
2242/// Returns a pointer to the element at the specified index.1803/// 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.
2244pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value {1805pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value {
2245 const zcu = pt.zcu;1806 const zcu = pt.zcu;
2246 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {1807 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...@@ -2249,79 +1810,50 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value
2249 };1810 };
22501811
2251 const parent_ptr_ty = parent_ptr.typeOf(zcu);1812 const parent_ptr_ty = parent_ptr.typeOf(zcu);
2252 const elem_ty = parent_ptr_ty.childType(zcu);1813 const result_ty = try parent_ptr_ty.elemPtrType(field_idx, pt);
2253 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), pt);1814 const elem_ty = result_ty.childType(zcu);
1815 elem_ty.assertHasLayout(zcu);
22541816
2255 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);1817 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
22561818
2257 if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) {1819 if (!elem_ty.comptimeOnly(zcu)) {
2258 // Since we have a bit-pointer, the pointer address should be unchanged.1820 const byte_offset = field_idx * elem_ty.abiSize(zcu);
2259 assert(elem_ty.zigTypeTag(zcu) == .vector);1821 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
2260 return pt.getCoerced(parent_ptr, result_ty);
2261 }1822 }
22621823
2263 const PtrStrat = union(enum) {1824 // Comptime-only element type.
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 },
22801825
2281 .many, .c => if (try elem_ty.comptimeOnlySema(pt))1826 if (field_idx == 0) {
2282 .{ .elem_ptr = elem_ty }1827 return pt.getCoerced(parent_ptr, result_ty);
2283 else1828 }
2284 .{ .offset = field_idx * (try elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar },
2285
2286 .slice => unreachable,
2287 };
22881829
2289 switch (strat) {1830 const arr_base_ty, const arr_base_len = elem_ty.arrayBase(zcu);
2290 .offset => |byte_offset| {1831 const base_idx = arr_base_len * field_idx;
2291 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);1832 const parent_info = zcu.intern_pool.indexToKey(parent_ptr.toIntern()).ptr;
2292 },1833 switch (parent_info.base_addr) {
2293 .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) {1834 .arr_elem => |arr_elem| {
2294 return pt.getCoerced(parent_ptr, result_ty);1835 if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) {
2295 } else {1836 // We already have a pointer to an element of an array of this type.
2296 const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu);1837 // Just modify the index.
2297 const base_idx = arr_base_len * field_idx;1838 return .fromInterned(try pt.intern(.{ .ptr = ptr: {
2298 const parent_info = zcu.intern_pool.indexToKey(parent_ptr.toIntern()).ptr;1839 var new = parent_info;
2299 switch (parent_info.base_addr) {1840 new.base_addr.arr_elem.index += base_idx;
2300 .arr_elem => |arr_elem| {1841 new.ty = result_ty.toIntern();
2301 if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) {1842 break :ptr new;
2302 // We already have a pointer to an element of an array of this type.1843 } }));
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 => {},
2313 }1844 }
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 } }));
2323 },1845 },
1846 else => {},
2324 }1847 }
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 } }));
2325}1857}
23261858
2327fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, pt: Zcu.PerThread) !Value {1859fn 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) {...@@ -2417,19 +1949,11 @@ pub const PointerDeriveStep = union(enum) {
2417 }1949 }
2418};1950};
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
2428/// Given a pointer value, get the sequence of steps to derive it, ideally by taking1952/// Given a pointer value, get the sequence of steps to derive it, ideally by taking
2429/// only field and element pointers with no casts. This can be used by codegen backends1953/// only field and element pointers with no casts. This can be used by codegen backends
2430/// which prefer field/elem accesses when lowering constant pointer values.1954/// which prefer field/elem accesses when lowering constant pointer values.
2431/// It is also used by the Value printing logic for pointers.1955/// 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 {
2433 const zcu = pt.zcu;1957 const zcu = pt.zcu;
2434 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;1958 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
2435 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {1959 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {
...@@ -2454,7 +1978,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -2454,7 +1978,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2454 .comptime_alloc => |idx| base: {1978 .comptime_alloc => |idx| base: {
2455 const sema = opt_sema.?;1979 const sema = opt_sema.?;
2456 const alloc = sema.getComptimeAlloc(idx);1980 const alloc = sema.getComptimeAlloc(idx);
2457 const val = try alloc.val.intern(pt, sema.arena);1981 const val = try alloc.val.intern(pt, arena);
2458 const ty = val.typeOf(zcu);1982 const ty = val.typeOf(zcu);
2459 break :base .{ .comptime_alloc_ptr = .{1983 break :base .{ .comptime_alloc_ptr = .{
2460 .idx = idx,1984 .idx = idx,
...@@ -2472,7 +1996,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -2472,7 +1996,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2472 const base_ptr = Value.fromInterned(eu_ptr);1996 const base_ptr = Value.fromInterned(eu_ptr);
2473 const base_ptr_ty = base_ptr.typeOf(zcu);1997 const base_ptr_ty = base_ptr.typeOf(zcu);
2474 const parent_step = try arena.create(PointerDeriveStep);1998 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);
2476 break :base .{ .eu_payload_ptr = .{2000 break :base .{ .eu_payload_ptr = .{
2477 .parent = parent_step,2001 .parent = parent_step,
2478 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)),2002 .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...@@ -2482,7 +2006,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2482 const base_ptr = Value.fromInterned(opt_ptr);2006 const base_ptr = Value.fromInterned(opt_ptr);
2483 const base_ptr_ty = base_ptr.typeOf(zcu);2007 const base_ptr_ty = base_ptr.typeOf(zcu);
2484 const parent_step = try arena.create(PointerDeriveStep);2008 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);
2486 break :base .{ .opt_payload_ptr = .{2010 break :base .{ .opt_payload_ptr = .{
2487 .parent = parent_step,2011 .parent = parent_step,
2488 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)),2012 .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...@@ -2490,59 +2014,32 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2490 },2014 },
2491 .field => |field| base: {2015 .field => |field| base: {
2492 const base_ptr = Value.fromInterned(field.base);2016 const base_ptr = Value.fromInterned(field.base);
2493 const base_ptr_ty = base_ptr.typeOf(zcu);2017 const base_ptr_ty = try pt.ptrType(info: {
2494 const agg_ty = base_ptr_ty.childType(zcu);2018 var info = base_ptr.typeOf(zcu).ptrInfo(zcu);
2495 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {2019 info.flags.size = .one;
2496 .@"struct" => .{ agg_ty.fieldType(@intCast(field.index), zcu), try agg_ty.fieldAlignmentInner(2020 break :info info;
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 },
2528 });2021 });
2529 const parent_step = try arena.create(PointerDeriveStep);2022 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);
2531 break :base .{ .field_ptr = .{2024 break :base .{ .field_ptr = .{
2532 .parent = parent_step,2025 .parent = parent_step,
2533 .field_idx = @intCast(field.index),2026 .field_idx = @intCast(field.index),
2534 .result_ptr_ty = result_ty,2027 .result_ptr_ty = try base_ptr_ty.fieldPtrType(@intCast(field.index), pt),
2535 } };2028 } };
2536 },2029 },
2537 .arr_elem => |arr_elem| base: {2030 .arr_elem => |arr_elem| base: {
2538 const parent_step = try arena.create(PointerDeriveStep);2031 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);
2540 const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu);2033 const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu);
2541 const result_ptr_ty = try pt.ptrType(.{2034 const result_ptr_ty = try pt.ptrType(.{
2542 .child = parent_ptr_info.child,2035 .child = parent_ptr_info.child,
2543 .flags = flags: {2036 .flags = flags: {
2544 var flags = parent_ptr_info.flags;2037 var flags = parent_ptr_info.flags;
2545 flags.size = .one;2038 flags.size = .one;
2039 if (flags.alignment != .none) flags.alignment = .minStrict(
2040 flags.alignment,
2041 Type.fromInterned(parent_ptr_info.child).abiAlignment(zcu),
2042 );
2546 break :flags flags;2043 break :flags flags;
2547 },2044 },
2548 });2045 });
...@@ -2560,7 +2057,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -2560,7 +2057,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
25602057
2561 const ptr_ty_info = Type.fromInterned(ptr.ty).ptrInfo(zcu);2058 const ptr_ty_info = Type.fromInterned(ptr.ty).ptrInfo(zcu);
2562 const need_child: Type = .fromInterned(ptr_ty_info.child);2059 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") {
2564 // No refinement can happen - this pointer is presumably invalid.2061 // No refinement can happen - this pointer is presumably invalid.
2565 // Just offset it.2062 // Just offset it.
2566 const parent = try arena.create(PointerDeriveStep);2063 const parent = try arena.create(PointerDeriveStep);
...@@ -2662,27 +2159,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -2662,27 +2159,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2662 const start_off = cur_ty.structFieldOffset(field_idx, zcu);2159 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
2663 const end_off = start_off + field_ty.abiSize(zcu);2160 const end_off = start_off + field_ty.abiSize(zcu);
2664 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {2161 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
2665 const old_ptr_ty = try cur_derive.ptrType(pt);2162 const base_ptr_ty = try pt.ptrType(info: {
2666 const parent_align = old_ptr_ty.ptrAlignment(zcu);2163 var info = (try cur_derive.ptrType(pt)).ptrInfo(zcu);
2667 const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off)));2164 info.flags.size = .one;
2165 break :info info;
2166 });
2668 const parent = try arena.create(PointerDeriveStep);2167 const parent = try arena.create(PointerDeriveStep);
2669 parent.* = cur_derive;2168 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 });
2682 cur_derive = .{ .field_ptr = .{2169 cur_derive = .{ .field_ptr = .{
2683 .parent = parent,2170 .parent = parent,
2684 .field_idx = @intCast(field_idx),2171 .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),
2686 } };2173 } };
2687 cur_offset -= start_off;2174 cur_offset -= start_off;
2688 break;2175 break;
...@@ -2720,148 +2207,6 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -2720,148 +2207,6 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2720 } };2207 } };
2721}2208}
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
2865const InterpretMode = enum {2210const InterpretMode = enum {
2866 /// In this mode, types are assumed to match what the compiler was built with in terms of field2211 /// In this mode, types are assumed to match what the compiler was built with in terms of field
2867 /// order, field types, etc. This improves compiler performance. However, it means that certain2212 /// 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...@@ -2878,7 +2223,6 @@ const interpret_mode: InterpretMode = @field(InterpretMode, @tagName(build_optio
28782223
2879/// Given a `Value` representing a comptime-known value of type `T`, unwrap it into an actual `T` known to the compiler.2224/// Given a `Value` representing a comptime-known value of type `T`, unwrap it into an actual `T` known to the compiler.
2880/// This is useful for accessing `std.builtin` structures received from comptime logic.2225/// This is useful for accessing `std.builtin` structures received from comptime logic.
2881/// `val` must be fully resolved.
2882pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMemory, UndefinedValue, TypeMismatch }!T {2226pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMemory, UndefinedValue, TypeMismatch }!T {
2883 const zcu = pt.zcu;2227 const zcu = pt.zcu;
2884 const io = zcu.comp.io;2228 const io = zcu.comp.io;
...@@ -2917,7 +2261,6 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe...@@ -2917,7 +2261,6 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe
2917 },2261 },
29182262
2919 .int => switch (ip.indexToKey(val.toIntern()).int.storage) {2263 .int => switch (ip.indexToKey(val.toIntern()).int.storage) {
2920 .lazy_align, .lazy_size => unreachable, // `val` is fully resolved
2921 inline .u64, .i64 => |x| std.math.cast(T, x) orelse return error.TypeMismatch,2264 inline .u64, .i64 => |x| std.math.cast(T, x) orelse return error.TypeMismatch,
2922 .big_int => |big| big.toInt(T) catch return error.TypeMismatch,2265 .big_int => |big| big.toInt(T) catch return error.TypeMismatch,
2923 },2266 },
...@@ -2949,7 +2292,7 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe...@@ -2949,7 +2292,7 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe
2949 inline else => |tag_comptime| @unionInit(2292 inline else => |tag_comptime| @unionInit(
2950 T,2293 T,
2951 @tagName(tag_comptime),2294 @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),
2953 ),2296 ),
2954 };2297 };
2955 },2298 },
...@@ -3076,7 +2419,7 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory...@@ -3076,7 +2419,7 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory
3076 }2419 }
3077 for (field_vals, 0..) |*field_val, field_idx| {2420 for (field_vals, 0..) |*field_val, field_idx| {
3078 if (field_val.* == .none) {2421 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];
3080 if (default_init == .none) return error.TypeMismatch;2423 if (default_init == .none) return error.TypeMismatch;
3081 field_val.* = default_init;2424 field_val.* = default_init;
3082 }2425 }
...@@ -3092,8 +2435,8 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory...@@ -3092,8 +2435,8 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory
3092pub fn doPointersOverlap(ptr_val_a: Value, ptr_val_b: Value, elem_count: u64, zcu: *const Zcu) bool {2435pub fn doPointersOverlap(ptr_val_a: Value, ptr_val_b: Value, elem_count: u64, zcu: *const Zcu) bool {
3093 const ip = &zcu.intern_pool;2436 const ip = &zcu.intern_pool;
30942437
3095 const a_elem_ty = ptr_val_a.typeOf(zcu).indexablePtrElem(zcu);2438 const a_elem_ty = ptr_val_a.typeOf(zcu).indexableElem(zcu);
3096 const b_elem_ty = ptr_val_b.typeOf(zcu).indexablePtrElem(zcu);2439 const b_elem_ty = ptr_val_b.typeOf(zcu).indexableElem(zcu);
30972440
3098 const a_ptr = ip.indexToKey(ptr_val_a.toIntern()).ptr;2441 const a_ptr = ip.indexToKey(ptr_val_a.toIntern()).ptr;
3099 const b_ptr = ip.indexToKey(ptr_val_b.toIntern()).ptr;2442 const b_ptr = ip.indexToKey(ptr_val_b.toIntern()).ptr;
...@@ -3179,3 +2522,58 @@ pub fn eqlScalarNum(lhs: Value, rhs: Value, zcu: *Zcu) bool {...@@ -3179,3 +2522,58 @@ pub fn eqlScalarNum(lhs: Value, rhs: Value, zcu: *Zcu) bool {
3179 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, zcu);2522 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, zcu);
3180 return lhs_bigint.eql(rhs_bigint);2523 return lhs_bigint.eql(rhs_bigint);
3181}2524}
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;...@@ -14,6 +14,8 @@ const mem = std.mem;
14const Allocator = std.mem.Allocator;14const Allocator = std.mem.Allocator;
15const assert = std.debug.assert;15const assert = std.debug.assert;
16const log = std.log.scoped(.zcu);16const log = std.log.scoped(.zcu);
17const deps_log = std.log.scoped(.zcu_deps);
18const refs_log = std.log.scoped(.zcu_refs);
17const BigIntConst = std.math.big.int.Const;19const BigIntConst = std.math.big.int.Const;
18const BigIntMutable = std.math.big.int.Mutable;20const BigIntMutable = std.math.big.int.Mutable;
19const Target = std.Target;21const Target = std.Target;
...@@ -117,7 +119,7 @@ module_roots: std.AutoArrayHashMapUnmanaged(*Package.Module, File.Index.Optional...@@ -117,7 +119,7 @@ module_roots: std.AutoArrayHashMapUnmanaged(*Package.Module, File.Index.Optional
117///119///
118/// Always accessed through `ImportTableAdapter`, where keys are fully resolved120/// Always accessed through `ImportTableAdapter`, where keys are fully resolved
119/// file paths in order to ensure files are properly deduplicated. This table owns121/// file paths in order to ensure files are properly deduplicated. This table owns
120/// the keys and values.122/// the keysand values.
121///123///
122/// Protected by Compilation's mutex.124/// Protected by Compilation's mutex.
123///125///
...@@ -175,7 +177,9 @@ embed_table: std.ArrayHashMapUnmanaged(...@@ -175,7 +177,9 @@ embed_table: std.ArrayHashMapUnmanaged(
175/// is not yet implemented.177/// is not yet implemented.
176intern_pool: InternPool = .empty,178intern_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,
179/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.183/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.
180failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .empty,184failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .empty,
181/// This `AnalUnit` failed semantic analysis because it required analysis of another `AnalUnit` which itself failed.185/// 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...@@ -187,6 +191,19 @@ transitive_failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .emp
187/// codegen and linking run on a separate thread.191/// codegen and linking run on a separate thread.
188failed_codegen: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, *ErrorMsg) = .empty,192failed_codegen: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, *ErrorMsg) = .empty,
189failed_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, *ErrorMsg) = .empty,193failed_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
190/// Keep track of `@compileLog`s per `AnalUnit`.207/// Keep track of `@compileLog`s per `AnalUnit`.
191/// We track the source location of the first `@compileLog` call, and all logged lines as a linked list.208/// We track the source location of the first `@compileLog` call, and all logged lines as a linked list.
192/// The list is singly linked, but we do track its tail for fast appends (optimizing many logs in one unit).209/// 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) = ....@@ -247,6 +264,10 @@ cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .
247/// Maximum amount of distinct error values, set by --error-limit264/// Maximum amount of distinct error values, set by --error-limit
248error_limit: ErrorInt,265error_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,
250/// Value is the number of PO dependencies of this AnalUnit.271/// Value is the number of PO dependencies of this AnalUnit.
251/// This value will decrease as we perform semantic analysis to learn what is outdated.272/// This value will decrease as we perform semantic analysis to learn what is outdated.
252/// If any of these PO deps is outdated, this value will be moved to `outdated`.273/// 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,...@@ -254,19 +275,22 @@ potentially_outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .empty,
254/// Value is the number of PO dependencies of this AnalUnit.275/// Value is the number of PO dependencies of this AnalUnit.
255/// Once this value drops to 0, the AnalUnit is a candidate for re-analysis.276/// Once this value drops to 0, the AnalUnit is a candidate for re-analysis.
256outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .empty,277outdated: 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.
258/// Such `AnalUnit`s are ready for immediate re-analysis.279/// Such `AnalUnit`s are ready for immediate re-analysis.
259/// See `findOutdatedToAnalyze` for details.280/// 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 },
261/// This contains a list of AnalUnit whose analysis or codegen failed, but the288/// This contains a list of AnalUnit whose analysis or codegen failed, but the
262/// failure was something like running out of disk space, and trying again may289/// failure was something like running out of disk space, and trying again may
263/// succeed. On the next update, we will flush this list, marking all members of290/// succeed. On the next update, we will flush this list, marking all members of
264/// it as outdated.291/// it as outdated.
265retryable_failures: std.ArrayList(AnalUnit) = .empty,292retryable_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
270/// These are the modules which we initially queue for analysis in `Compilation.update`.294/// These are the modules which we initially queue for analysis in `Compilation.update`.
271/// `resolveReferences` will use these as the root of its reachability traversal.295/// `resolveReferences` will use these as the root of its reachability traversal.
272analysis_roots_buffer: [5]*Package.Module,296analysis_roots_buffer: [5]*Package.Module,
...@@ -322,6 +346,12 @@ codegen_task_pool: CodegenTaskPool,...@@ -322,6 +346,12 @@ codegen_task_pool: CodegenTaskPool,
322346
323generation: u32 = 0,347generation: 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
325pub const IncrementalDebugState = struct {355pub const IncrementalDebugState = struct {
326 /// All container types in the ZCU, even dead ones.356 /// All container types in the ZCU, even dead ones.
327 /// Value is the generation the type was created on.357 /// Value is the generation the type was created on.
...@@ -1220,6 +1250,15 @@ pub const ErrorMsg = struct {...@@ -1220,6 +1250,15 @@ pub const ErrorMsg = struct {
1220 notes: []ErrorMsg = &.{},1250 notes: []ErrorMsg = &.{},
1221 reference_trace_root: AnalUnit.Optional = .none,1251 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
1223 pub fn create(1262 pub fn create(
1224 gpa: Allocator,1263 gpa: Allocator,
1225 src_loc: LazySrcLoc,1264 src_loc: LazySrcLoc,
...@@ -1910,40 +1949,6 @@ pub const SrcLoc = struct {...@@ -1910,40 +1949,6 @@ pub const SrcLoc = struct {
1910 const full = tree.fullPtrType(parent_node).?;1949 const full = tree.fullPtrType(parent_node).?;
1911 return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?);1950 return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?);
1912 },1951 },
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 },
1947 .node_offset_init_ty => |node_off| {1952 .node_offset_init_ty => |node_off| {
1948 const tree = try src_loc.file_scope.getTree(zcu);1953 const tree = try src_loc.file_scope.getTree(zcu);
1949 const parent_node = node_off.toAbsolute(src_loc.base_node);1954 const parent_node = node_off.toAbsolute(src_loc.base_node);
...@@ -2019,6 +2024,20 @@ pub const SrcLoc = struct {...@@ -2019,6 +2024,20 @@ pub const SrcLoc = struct {
2019 }2024 }
2020 return tree.nodeToSpan(node);2025 return tree.nodeToSpan(node);
2021 },2026 },
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 },
2022 .container_field_name,2041 .container_field_name,
2023 .container_field_value,2042 .container_field_value,
2024 .container_field_type,2043 .container_field_type,
...@@ -2027,8 +2046,38 @@ pub const SrcLoc = struct {...@@ -2027,8 +2046,38 @@ pub const SrcLoc = struct {
2027 const tree = try src_loc.file_scope.getTree(zcu);2046 const tree = try src_loc.file_scope.getTree(zcu);
2028 const node = src_loc.base_node;2047 const node = src_loc.base_node;
2029 var buf: [2]Ast.Node.Index = undefined;2048 var buf: [2]Ast.Node.Index = undefined;
2030 const container_decl = tree.fullContainerDecl(&buf, node) orelse2049 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 }
2031 return tree.nodeToSpan(node);2079 return tree.nodeToSpan(node);
2080 };
20322081
2033 var cur_field_idx: usize = 0;2082 var cur_field_idx: usize = 0;
2034 for (container_decl.ast.members) |member_node| {2083 for (container_decl.ast.members) |member_node| {
...@@ -2260,7 +2309,11 @@ pub const SrcLoc = struct {...@@ -2260,7 +2309,11 @@ pub const SrcLoc = struct {
2260 var param_it = full.iterate(tree);2309 var param_it = full.iterate(tree);
2261 for (0..param_idx) |_| assert(param_it.next() != null);2310 for (0..param_idx) |_| assert(param_it.next() != null);
2262 const param = param_it.next().?;2311 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 }
2264 },2317 },
2265 }2318 }
2266 }2319 }
...@@ -2482,10 +2535,6 @@ pub const LazySrcLoc = struct {...@@ -2482,10 +2535,6 @@ pub const LazySrcLoc = struct {
2482 node_offset_ptr_bitoffset: Ast.Node.Offset,2535 node_offset_ptr_bitoffset: Ast.Node.Offset,
2483 /// The source location points to the host size of a pointer.2536 /// The source location points to the host size of a pointer.
2484 node_offset_ptr_hostsize: Ast.Node.Offset,2537 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,
2489 /// The source location points to the type of an array or struct initializer.2538 /// The source location points to the type of an array or struct initializer.
2490 node_offset_init_ty: Ast.Node.Offset,2539 node_offset_init_ty: Ast.Node.Offset,
2491 /// The source location points to the LHS of an assignment (or assign-op, e.g. `+=`).2540 /// The source location points to the LHS of an assignment (or assign-op, e.g. `+=`).
...@@ -2530,6 +2579,11 @@ pub const LazySrcLoc = struct {...@@ -2530,6 +2579,11 @@ pub const LazySrcLoc = struct {
2530 fn_proto_param_type: FnProtoParam,2579 fn_proto_param_type: FnProtoParam,
2531 array_cat_lhs: ArrayCat,2580 array_cat_lhs: ArrayCat,
2532 array_cat_rhs: ArrayCat,2581 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,
2533 /// The source location points to the name of the field at the given index2587 /// The source location points to the name of the field at the given index
2534 /// of the container type declaration at the base node.2588 /// of the container type declaration at the base node.
2535 container_field_name: u32,2589 container_field_name: u32,
...@@ -2685,10 +2739,10 @@ pub const LazySrcLoc = struct {...@@ -2685,10 +2739,10 @@ pub const LazySrcLoc = struct {
2685 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_node,2739 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_node,
2686 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,2740 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,
2687 .extended => switch (inst.data.extended.opcode) {2741 .extended => switch (inst.data.extended.opcode) {
2688 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_node,2742 .struct_decl => zir.getStructDecl(zir_inst).src_node,
2689 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,2743 .union_decl => zir.getUnionDecl(zir_inst).src_node,
2690 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,2744 .enum_decl => zir.getEnumDecl(zir_inst).src_node,
2691 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,2745 .opaque_decl => zir.getOpaqueDecl(zir_inst).src_node,
2692 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node,2746 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node,
2693 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,2747 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
2694 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,2748 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,
...@@ -2715,36 +2769,34 @@ pub const LazySrcLoc = struct {...@@ -2715,36 +2769,34 @@ pub const LazySrcLoc = struct {
2715 };2769 };
2716 }2770 }
27172771
2718 /// Used to sort error messages, so that they're printed in a consistent order.2772 pub fn order(lhs: LazySrcLoc, rhs: LazySrcLoc, zcu: *Zcu) std.math.Order {
2719 /// If an error is returned, a file could not be read in order to resolve a source location.2773 const lhs_resolved = lhs.upgradeOrLost(zcu) orelse {
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 {
2723 // LHS source location lost, so should never be referenced. Just sort it to the end.2774 // LHS source location lost, so should never be referenced. Just sort it to the end.
2724 return false;2775 return .gt;
2725 };2776 };
2726 const rhs_src = rhs_lazy.upgradeOrLost(zcu) orelse {2777 const rhs_resolved = rhs.upgradeOrLost(zcu) orelse {
2727 // RHS source location lost, so should never be referenced. Just sort it to the end.2778 // RHS source location lost, so should never be referenced. Just sort it to the end.
2728 return true;2779 return .lt;
2729 };2780 };
2730 if (lhs_src.file_scope != rhs_src.file_scope) {2781 if (lhs_resolved.file_scope != rhs_resolved.file_scope) {
2731 const lhs_path = lhs_src.file_scope.path;2782 const lhs_path = lhs_resolved.file_scope.path;
2732 const rhs_path = rhs_src.file_scope.path;2783 const rhs_path = rhs_resolved.file_scope.path;
2733 if (lhs_path.root != rhs_path.root) {2784 return std.math.order(@intFromEnum(lhs_path.root), @intFromEnum(rhs_path.root)).differ() orelse
2734 return @intFromEnum(lhs_path.root) < @intFromEnum(rhs_path.root);2785 std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).differ().?;
2735 }
2736 return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt);
2737 }2786 }
27382787 const prev_prot = zcu.comp.io.swapCancelProtection(.blocked);
2739 const lhs_span = lhs_src.span(zcu) catch |err| {2788 defer _ = zcu.comp.io.swapCancelProtection(prev_prot);
2740 bad_file_out.* = lhs_src.file_scope;2789 const lhs_span = lhs_resolved.span(zcu) catch |err| {
2741 return 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;
2742 };2793 };
2743 const rhs_span = rhs_src.span(zcu) catch |err| {2794 const rhs_span = rhs_resolved.span(zcu) catch |err| {
2744 bad_file_out.* = rhs_src.file_scope;2795 assert(err != error.Canceled); // we're protected
2745 return err;2796 // Failed to read RHS, so we'll get a transient error. Just sort it to the end.
2797 return .lt;
2746 };2798 };
2747 return lhs_span.main < rhs_span.main;2799 return std.math.order(lhs_span.main, rhs_span.main);
2748 }2800 }
2749};2801};
27502802
...@@ -2800,6 +2852,8 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2800,6 +2852,8 @@ pub fn deinit(zcu: *Zcu) void {
2800 zcu.analysis_in_progress.deinit(gpa);2852 zcu.analysis_in_progress.deinit(gpa);
2801 zcu.failed_analysis.deinit(gpa);2853 zcu.failed_analysis.deinit(gpa);
2802 zcu.transitive_failed_analysis.deinit(gpa);2854 zcu.transitive_failed_analysis.deinit(gpa);
2855 zcu.dependency_loops.deinit(gpa);
2856 zcu.dependency_loop_nodes.deinit(gpa);
2803 zcu.failed_codegen.deinit(gpa);2857 zcu.failed_codegen.deinit(gpa);
2804 zcu.failed_types.deinit(gpa);2858 zcu.failed_types.deinit(gpa);
28052859
...@@ -2830,12 +2884,10 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2830,12 +2884,10 @@ pub fn deinit(zcu: *Zcu) void {
28302884
2831 zcu.potentially_outdated.deinit(gpa);2885 zcu.potentially_outdated.deinit(gpa);
2832 zcu.outdated.deinit(gpa);2886 zcu.outdated.deinit(gpa);
2833 zcu.outdated_ready.deinit(gpa);2887 zcu.outdated_ready.funcs.deinit(gpa);
2888 zcu.outdated_ready.other.deinit(gpa);
2834 zcu.retryable_failures.deinit(gpa);2889 zcu.retryable_failures.deinit(gpa);
28352890
2836 zcu.func_body_analysis_queued.deinit(gpa);
2837 zcu.nav_val_analysis_queued.deinit(gpa);
2838
2839 zcu.test_functions.deinit(gpa);2891 zcu.test_functions.deinit(gpa);
28402892
2841 for (zcu.global_assembly.values()) |s| {2893 for (zcu.global_assembly.values()) |s| {
...@@ -3063,18 +3115,24 @@ pub fn markDependeeOutdated(...@@ -3063,18 +3115,24 @@ pub fn markDependeeOutdated(
3063 marked_po: enum { not_marked_po, marked_po },3115 marked_po: enum { not_marked_po, marked_po },
3064 dependee: InternPool.Dependee,3116 dependee: InternPool.Dependee,
3065) !void {3117) !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)});
3067 var it = zcu.intern_pool.dependencyIterator(dependee);3120 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);
3068 while (it.next()) |depender| {3123 while (it.next()) |depender| {
3069 if (zcu.outdated.getPtr(depender)) |po_dep_count| {3124 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
3070 switch (marked_po) {3125 switch (marked_po) {
3071 .not_marked_po => {},3126 .not_marked_po => {},
3072 .marked_po => {3127 .marked_po => {
3073 po_dep_count.* -= 1;3128 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.* });
3075 if (po_dep_count.* == 0) {3130 if (po_dep_count.* == 0) {
3076 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});3131 deps_log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3077 try zcu.outdated_ready.put(zcu.gpa, 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 }
3078 }3136 }
3079 },3137 },
3080 }3138 }
...@@ -3090,14 +3148,17 @@ pub fn markDependeeOutdated(...@@ -3090,14 +3148,17 @@ pub fn markDependeeOutdated(
3090 },3148 },
3091 };3149 };
3092 try zcu.outdated.putNoClobber(3150 try zcu.outdated.putNoClobber(
3093 zcu.gpa,3151 gpa,
3094 depender,3152 depender,
3095 new_po_dep_count,3153 new_po_dep_count,
3096 );3154 );
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 });
3098 if (new_po_dep_count == 0) {3156 if (new_po_dep_count == 0) {
3099 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});3157 deps_log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3100 try zcu.outdated_ready.put(zcu.gpa, 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 }
3101 }3162 }
3102 // If this is a Decl and was not previously PO, we must recursively3163 // If this is a Decl and was not previously PO, we must recursively
3103 // mark dependencies on its tyval as PO.3164 // mark dependencies on its tyval as PO.
...@@ -3109,17 +3170,27 @@ pub fn markDependeeOutdated(...@@ -3109,17 +3170,27 @@ pub fn markDependeeOutdated(
3109}3170}
31103171
3111pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {3172pub 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)});
3113 var it = zcu.intern_pool.dependencyIterator(dependee);3181 var it = zcu.intern_pool.dependencyIterator(dependee);
3114 while (it.next()) |depender| {3182 while (it.next()) |depender| {
3115 if (zcu.outdated.getPtr(depender)) |po_dep_count| {3183 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
3116 // This depender is already outdated, but it now has one3184 // This depender is already outdated, but it now has one
3117 // less PO dependency!3185 // less PO dependency!
3118 po_dep_count.* -= 1;3186 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.* });
3120 if (po_dep_count.* == 0) {3188 if (po_dep_count.* == 0) {
3121 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});3189 deps_log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3122 try zcu.outdated_ready.put(zcu.gpa, 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 }
3123 }3194 }
3124 continue;3195 continue;
3125 }3196 }
...@@ -3132,11 +3203,11 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -3132,11 +3203,11 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3132 };3203 };
3133 if (ptr.* > 1) {3204 if (ptr.* > 1) {
3134 ptr.* -= 1;3205 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.* });
3136 continue;3207 continue;
3137 }3208 }
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
3141 // This dependency is no longer PO, i.e. is known to be up-to-date.3212 // This dependency is no longer PO, i.e. is known to be up-to-date.
3142 assert(zcu.potentially_outdated.swapRemove(depender));3213 assert(zcu.potentially_outdated.swapRemove(depender));
...@@ -3144,139 +3215,120 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -3144,139 +3215,120 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3144 // as no longer PO.3215 // as no longer PO.
3145 switch (depender.unwrap()) {3216 switch (depender.unwrap()) {
3146 .@"comptime" => {},3217 .@"comptime" => {},
3147 .nav_val => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_val = nav }),3218 .nav_val => |nav| try zcu.markPoDependeeUpToDateInner(.{ .nav_val = nav }),
3148 .nav_ty => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav }),3219 .nav_ty => |nav| try zcu.markPoDependeeUpToDateInner(.{ .nav_ty = nav }),
3149 .type => |ty| try zcu.markPoDependeeUpToDate(.{ .interned = ty }),3220 .type_layout => |ty| try zcu.markPoDependeeUpToDateInner(.{ .type_layout = ty }),
3150 .func => |func| try zcu.markPoDependeeUpToDate(.{ .interned = func }),3221 .struct_defaults => |ty| try zcu.markPoDependeeUpToDateInner(.{ .struct_defaults = ty }),
3151 .memoized_state => |stage| try zcu.markPoDependeeUpToDate(.{ .memoized_state = stage }),3222 .func => |func| try zcu.markPoDependeeUpToDateInner(.{ .func_ies = func }),
3223 .memoized_state => |stage| try zcu.markPoDependeeUpToDateInner(.{ .memoized_state = stage }),
3152 }3224 }
3153 }3225 }
3154}3226}
31553227
3156/// Given a AnalUnit which is newly outdated or PO, mark all AnalUnits which may3228/// Given a AnalUnit which is newly outdated or PO, mark all AnalUnits which may
3157/// in turn be PO, due to a dependency on the original AnalUnit's tyval or IES.3229/// 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;
3159 const ip = &zcu.intern_pool;3234 const ip = &zcu.intern_pool;
3160 const dependee: InternPool.Dependee = switch (maybe_outdated.unwrap()) {3235 const dependee: InternPool.Dependee = switch (maybe_outdated.unwrap()) {
3161 .@"comptime" => return, // analysis of a comptime decl can't outdate any dependencies3236 .@"comptime" => return, // analysis of a comptime decl can't outdate any dependencies
3162 .nav_val => |nav| .{ .nav_val = nav },3237 .nav_val => |nav| .{ .nav_val = nav },
3163 .nav_ty => |nav| .{ .nav_ty = nav },3238 .nav_ty => |nav| .{ .nav_ty = nav },
3164 .type => |ty| .{ .interned = ty },3239 .type_layout => |ty| .{ .type_layout = ty },
3165 .func => |func_index| .{ .interned = func_index }, // IES3240 .struct_defaults => |ty| .{ .struct_defaults = ty },
3241 .func => |func_index| .{ .func_ies = func_index },
3166 .memoized_state => |stage| .{ .memoized_state = stage },3242 .memoized_state => |stage| .{ .memoized_state = stage },
3167 };3243 };
3168 log.debug("potentially outdated dependee: {f}", .{zcu.fmtDependee(dependee)});3244 deps_log.debug("potentially outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
3169 var it = ip.dependencyIterator(dependee);3245 var it = ip.dependencyIterator(dependee);
3170 while (it.next()) |po| {3246 while (it.next()) |po| {
3171 if (zcu.outdated.getPtr(po)) |po_dep_count| {3247 if (zcu.outdated.getPtr(po)) |po_dep_count| {
3172 // This dependency is already outdated, but it now has one more PO3248 // This dependency is already outdated, but it now has one more PO dependency.
3173 // dependency.
3174 if (po_dep_count.* == 0) {3249 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 }
3176 }3254 }
3177 po_dep_count.* += 1;3255 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.* });
3179 continue;3257 continue;
3180 }3258 }
3181 if (zcu.potentially_outdated.getPtr(po)) |n| {3259 if (zcu.potentially_outdated.getPtr(po)) |n| {
3182 // There is now one more PO dependency.3260 // There is now one more PO dependency.
3183 n.* += 1;3261 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.* });
3185 continue;3263 continue;
3186 }3264 }
3187 try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1);3265 try zcu.potentially_outdated.putNoClobber(gpa, po, 1);
3188 log.debug("po {f} => {f} po_deps=1", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po) });3266 deps_log.debug("po {f} => {f} po_deps=1", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po) });
3189 // This AnalUnit was not already PO, so we must recursively mark its dependers as also PO.3267 // This AnalUnit was not already PO, so we must recursively mark its dependers as also PO.
3190 try zcu.markTransitiveDependersPotentiallyOutdated(po);3268 try zcu.markTransitiveDependersPotentiallyOutdated(po);
3191 }3269 }
3192}3270}
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.
3194pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {3276pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
3195 if (!zcu.comp.config.incremental) return null;3277 // We prioritize functions, because the sooner they get analyzed, the sooner they can be send to
31963278 // the codegen backend and linker, which are usually running in parallel (so this can increase
3197 if (zcu.outdated.count() == 0) {3279 // parallelism).
3198 // Any units in `potentially_outdated` must just be stuck in loops with one another: none of those3280 // TODO: perhaps we should also experiment with *avoiding* functions if the codegen/link queue
3199 // units have had any outdated dependencies so far, and all of their remaining PO deps are triggered3281 // is backed up (for instance due to a very large function). That could help minimize blocking
3200 // by other units in `potentially_outdated`. So, we can safety assume those units up-to-date.3282 // on the main thread in `CodegenTaskPool.start` waiting for the linker to catch up.
3201 zcu.potentially_outdated.clearRetainingCapacity();3283 if (zcu.outdated_ready.funcs.count() > 0) {
3202 log.debug("findOutdatedToAnalyze: no outdated depender", .{});3284 const unit: AnalUnit = .wrap(.{ .func = zcu.outdated_ready.funcs.keys()[0] });
3203 return null;3285 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});
3286 return unit;
3204 }3287 }
32053288
3206 // Our goal is to find an outdated AnalUnit which itself has no outdated or3289 if (zcu.outdated_ready.other.count() > 0) {
3207 // PO dependencies. Most of the time, such an AnalUnit will exist - we track3290 const unit = zcu.outdated_ready.other.keys()[0];
3208 // them in the `outdated_ready` set for efficiency. However, this is not3291 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});
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)});
3218 return unit;3292 return unit;
3219 }3293 }
32203294
3221 // There is no single AnalUnit which is ready for re-analysis. Instead, we must assume that some3295 // Usually, getting here means that everything is up-to-date, so there is no more work to do. We
3222 // AnalUnit with PO dependencies is outdated -- e.g. in the above example we arbitrarily pick one of3296 // will see that `zcu.outdated` and `zcu.potentially_outdated` are both empty.
3223 // A or B. We should definitely not select a function, since a function can't be responsible for the3297 //
3224 // loop (IES dependencies can't have loops). We should also, of course, not select a `comptime`3298 // However, if a previous update had a dependency loop compile error, there is a cycle in the
3225 // declaration, since you can't depend on those!3299 // dependency graph (which is usually acyclic), which can cause a scenario where no unit appears
32263300 // to be ready, because they're all waiting for the next in the loop to be up-to-date. In that
3227 // The choice of this unit could have a big impact on how much total analysis we perform, since3301 // case, we usually have to just bite the bullet and analyze one of them. An exception is if
3228 // if analysis concludes any dependencies on its result are up-to-date, then other PO AnalUnit3302 // `zcu.outdated` is empty but `zcu.potentially_outdated` is non-empty: in that case, the only
3229 // may be resolved as up-to-date. To hopefully avoid doing too much work, let's find a unit3303 // possible situation is a cycle where everything is actually up-to-date, so we can clear out
3230 // which the most things depend on - the idea is that this will resolve a lot of loops (but this3304 // `zcu.potentially_outdated` and we are done.
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;
32393305
3240 var chosen_unit: ?AnalUnit = null;3306 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
3241 var chosen_unit_dependers: u32 = undefined;3307 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
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;
32603308
3261 if (chosen_unit == null or n > chosen_unit_dependers) {3309 if (zcu.outdated.count() == 0) {
3262 chosen_unit = unit;3310 // Everything is up-to-date. There could be lingering entries in `zcu.potentially_outdated`
3263 chosen_unit_dependers = n;3311 // from a dependency loop on a previous update.
3264 }3312 zcu.potentially_outdated.clearRetainingCapacity();
3265 }3313 log.debug("findOutdatedToAnalyze: all up-to-date", .{});
3314 return null;
3266 }3315 }
32673316
3268 log.debug("findOutdatedToAnalyze: heuristic returned '{f}' ({d} dependers)", .{3317 const unit = zcu.outdated.keys()[0];
3269 zcu.fmtAnalUnit(chosen_unit.?),3318 log.debug("findOutdatedToAnalyze: dependency loop affecting {d} units, selected {f}", .{
3270 chosen_unit_dependers,3319 zcu.outdated.count(),
3320 zcu.fmtAnalUnit(unit),
3271 });3321 });
32723322 return unit;
3273 return chosen_unit.?;
3274}3323}
32753324
3276/// During an incremental update, before semantic analysis, call this to flush all values from3325/// During an incremental update, before semantic analysis, call this to flush all values from
3277/// `retryable_failures` and mark them as outdated so they get re-analyzed.3326/// `retryable_failures` and mark them as outdated so they get re-analyzed.
3278pub fn flushRetryableFailures(zcu: *Zcu) !void {3327pub 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);
3280 for (zcu.retryable_failures.items) |depender| {3332 for (zcu.retryable_failures.items) |depender| {
3281 if (zcu.outdated.contains(depender)) continue;3333 if (zcu.outdated.contains(depender)) continue;
3282 if (zcu.potentially_outdated.fetchSwapRemove(depender)) |kv| {3334 if (zcu.potentially_outdated.fetchSwapRemove(depender)) |kv| {
...@@ -3350,12 +3402,59 @@ pub fn mapOldZirToNew(...@@ -3350,12 +3402,59 @@ pub fn mapOldZirToNew(
3350 }3402 }
33513403
3352 while (match_stack.pop()) |match_item| {3404 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, because3405 // There are some properties of type declarations which cannot change across incremental
3354 // we wouldn't know how to correlate type information with the last update.3406 // updates. If they have, we need to ignore this mapping. These properties are essentially
3355 // Synchronizes with logic in `Zcu.PerThread.recreateStructType` etc.3407 // everything passed into `InternPool.getDeclaredStructType` (likewise for unions, enums,
3356 if (old_zir.typeCapturesLen(match_item.old_inst) != new_zir.typeCapturesLen(match_item.new_inst)) {3408 // and opaques).
3357 // Don't map this type or anything within it.3409 const old_tag = old_zir.instructions.items(.data)[@intFromEnum(match_item.old_inst)].extended.opcode;
3358 continue;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,
3359 }3458 }
33603459
3361 // Match the namespace declaration itself3460 // Match the namespace declaration itself
...@@ -3377,25 +3476,21 @@ pub fn mapOldZirToNew(...@@ -3377,25 +3476,21 @@ pub fn mapOldZirToNew(
3377 var comptime_decls: std.ArrayList(Zir.Inst.Index) = .empty;3476 var comptime_decls: std.ArrayList(Zir.Inst.Index) = .empty;
3378 defer comptime_decls.deinit(gpa);3477 defer comptime_decls.deinit(gpa);
33793478
3380 {3479 for (old_zir.typeDecls(match_item.old_inst)) |old_decl_inst| {
3381 var old_decl_it = old_zir.declIterator(match_item.old_inst);3480 const old_decl = old_zir.getDeclaration(old_decl_inst);
3382 while (old_decl_it.next()) |old_decl_inst| {3481 switch (old_decl.kind) {
3383 const old_decl = old_zir.getDeclaration(old_decl_inst);3482 .@"comptime" => try comptime_decls.append(gpa, old_decl_inst),
3384 switch (old_decl.kind) {3483 .unnamed_test => try unnamed_tests.append(gpa, old_decl_inst),
3385 .@"comptime" => try comptime_decls.append(gpa, old_decl_inst),3484 .@"test" => try named_tests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3386 .unnamed_test => try unnamed_tests.append(gpa, old_decl_inst),3485 .decltest => try named_decltests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3387 .@"test" => try named_tests.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),
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 }
3391 }3487 }
3392 }3488 }
33933489
3394 var unnamed_test_idx: u32 = 0;3490 var unnamed_test_idx: u32 = 0;
3395 var comptime_decl_idx: u32 = 0;3491 var comptime_decl_idx: u32 = 0;
33963492
3397 var new_decl_it = new_zir.declIterator(match_item.new_inst);3493 for (new_zir.typeDecls(match_item.new_inst)) |new_decl_inst| {
3398 while (new_decl_it.next()) |new_decl_inst| {
3399 const new_decl = new_zir.getDeclaration(new_decl_inst);3494 const new_decl = new_zir.getDeclaration(new_decl_inst);
3400 // Attempt to match this to a declaration in the old ZIR:3495 // Attempt to match this to a declaration in the old ZIR:
3401 // * For named declarations (`const`/`var`/`fn`), we match based on name.3496 // * For named declarations (`const`/`var`/`fn`), we match based on name.
...@@ -3474,47 +3569,93 @@ pub fn mapOldZirToNew(...@@ -3474,47 +3569,93 @@ pub fn mapOldZirToNew(
3474/// The caller is responsible for ensuring the function decl itself is already3569/// The caller is responsible for ensuring the function decl itself is already
3475/// analyzed, and for ensuring it can exist at runtime (see3570/// analyzed, and for ensuring it can exist at runtime (see
3476/// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body3571/// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body
3477/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.3572/// will be analyzed when it returns: for that, see `PerThread.ensureFuncBodyUpToDate`.
3478pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void {3573pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func: InternPool.Index) !void {
3574 const comp = zcu.comp;
3575 const gpa = comp.gpa;
3576 const io = comp.io;
3479 const ip = &zcu.intern_pool;3577 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);3590pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav: InternPool.Nav.Index) !void {
34823591 const comp = zcu.comp;
3483 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one3592 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) {3623/// If `unit` was marked as outdated or porentially outdated, clears that status and returns `true`.
3488 if (!zcu.outdated.contains(.wrap(.{ .func = func_index })) and3624/// Otherwise, returns `false`.
3489 !zcu.potentially_outdated.contains(.wrap(.{ .func = func_index })))3625pub fn clearOutdatedState(zcu: *Zcu, unit: AnalUnit) bool {
3490 {3626 const io = zcu.comp.io;
3491 // This function has been analyzed before and is definitely up-to-date.3627 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(io);
3492 return;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);
3493 }3638 }
3639 return true;
3640 } else if (zcu.potentially_outdated.swapRemove(unit)) {
3641 return true;
3642 } else {
3643 return false;
3494 }3644 }
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, {});
3499}3645}
35003646
3501pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void {3647/// This function takes a `*const Zcu` and `@constCast`s it so that it can be called from functions
3502 const ip = &zcu.intern_pool;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) {3654 @constCast(zcu).outdated_lock.lockSharedUncancelable(io);
3507 if (!zcu.outdated.contains(.wrap(.{ .nav_val = nav_id })) and3655 defer @constCast(zcu).outdated_lock.unlockShared(io);
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 }
35143656
3515 try zcu.nav_val_analysis_queued.ensureUnusedCapacity(zcu.gpa, 1);3657 assert(!zcu.outdated.contains(unit));
3516 try zcu.comp.queueJob(.{ .analyze_comptime_unit = .wrap(.{ .nav_val = nav_id }) });3658 assert(!zcu.potentially_outdated.contains(unit));
3517 zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {});
3518}3659}
35193660
3520pub const ImportResult = struct {3661pub const ImportResult = struct {
...@@ -3533,56 +3674,83 @@ pub const ImportResult = struct {...@@ -3533,56 +3674,83 @@ pub const ImportResult = struct {
3533 module: ?*Package.Module,3674 module: ?*Package.Module,
3534};3675};
35353676
3536/// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of3677/// Prepares `unit` for re-analysis by clearing all of the following state:
3537/// this `AnalUnit` will cause them to be re-created (or not).3678/// * Compile errors associated with `unit`
3538pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {3679/// * Compile logs associated with `unit`
3539 const gpa = zcu.gpa;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|3689 if (!dev.env.supports(.incremental)) {
3542 .{ @intFromEnum(kv.value), 1 }3690 // This is the first time `unit` is being analyzed, so there is no stale data to clear.
3543 else if (zcu.multi_exports.fetchSwapRemove(anal_unit)) |info|
3544 .{ info.value.index, info.value.len }
3545 else
3546 return;3691 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 are3704 // Compile logs
3551 // guaranteed not to be any exports in the output file that need deleting (since we only call3705 if (zcu.compile_logs.fetchSwapRemove(unit)) |kv| {
3552 // `updateExports` on flush).3706 var opt_line_idx = kv.value.first_line.toOptional();
3553 // This case is needed because in some rare edge cases, `Sema` wants to add and delete exports3707 while (opt_line_idx.unwrap()) |line_idx| {
3554 // within a single update.3708 zcu.free_compile_log_lines.append(gpa, line_idx) catch {
3555 if (dev.env.supports(.incremental)) {3709 // This space will be reused eventually, so we need not propagate this error.
3556 for (exports, exports_base..) |exp, export_index_usize| {3710 // Just leak it for now, and let GC reclaim it later on.
3557 const export_idx: Export.Index = @enumFromInt(export_index_usize);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);
3558 if (zcu.comp.bin_file) |lf| {3730 if (zcu.comp.bin_file) |lf| {
3559 lf.deleteExport(exp.exported, exp.opts.name);3731 lf.deleteExport(exp.exported, exp.opts.name);
3560 }3732 }
3561 if (zcu.failed_exports.fetchSwapRemove(export_idx)) |failed_kv| {3733 if (zcu.failed_exports.fetchSwapRemove(exp_index)) |failed_kv| {
3562 failed_kv.value.destroy(gpa);3734 failed_kv.value.destroy(gpa);
3563 }3735 }
3564 }3736 }
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 }
3565 }3745 }
35663746
3567 zcu.free_exports.ensureUnusedCapacity(gpa, exports_len) catch {3747 // Dependencies
3568 // This space will be reused eventually, so we need not propagate this error.3748 zcu.intern_pool.removeDependenciesForDepender(gpa, unit);
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;
35813749
3750 // References
3582 zcu.clearCachedResolvedReferences();3751 zcu.clearCachedResolvedReferences();
3583
3584 unit_refs: {3752 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;
3586 var idx = kv.value;3754 var idx = kv.value;
35873755
3588 while (idx != std.math.maxInt(u32)) {3756 while (idx != std.math.maxInt(u32)) {
...@@ -3610,9 +3778,8 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {...@@ -3610,9 +3778,8 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
3610 }3778 }
3611 }3779 }
3612 }3780 }
3613
3614 type_refs: {3781 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;
3616 var idx = kv.value;3783 var idx = kv.value;
36173784
3618 while (idx != std.math.maxInt(u32)) {3785 while (idx != std.math.maxInt(u32)) {
...@@ -3626,22 +3793,6 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {...@@ -3626,22 +3793,6 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
3626 }3793 }
3627}3794}
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
3645pub fn addInlineReferenceFrame(zcu: *Zcu, frame: InlineReferenceFrame) Allocator.Error!Zcu.InlineReferenceFrame.Index {3796pub fn addInlineReferenceFrame(zcu: *Zcu, frame: InlineReferenceFrame) Allocator.Error!Zcu.InlineReferenceFrame.Index {
3646 const frame_idx: InlineReferenceFrame.Index = zcu.free_inline_reference_frames.pop() orelse idx: {3797 const frame_idx: InlineReferenceFrame.Index = zcu.free_inline_reference_frames.pop() orelse idx: {
3647 _ = try zcu.inline_reference_frames.addOne(zcu.gpa);3798 _ = try zcu.inline_reference_frames.addOne(zcu.gpa);
...@@ -3851,9 +4002,9 @@ pub const AtomicPtrAlignmentDiagnostics = struct {...@@ -3851,9 +4002,9 @@ pub const AtomicPtrAlignmentDiagnostics = struct {
3851 max_bits: u16 = undefined,4002 max_bits: u16 = undefined,
3852};4003};
38534004
3854/// If ABI alignment of `ty` is OK for atomic operations, returns 0.4005/// Returns the alignment required for the target to perform atomic operations on type `ty` (that
3855/// Otherwise returns the alignment required on a pointer for the target4006/// is, the required align attribute on the pointer). If the ABI alignment of `ty` is sufficient,
3856/// to perform atomic operations.4007/// returns `.none`.
3857// TODO this function does not take into account CPU features, which can affect4008// TODO this function does not take into account CPU features, which can affect
3858// this value. Audit this!4009// this value. Audit this!
3859pub fn atomicPtrAlignment(4010pub fn atomicPtrAlignment(
...@@ -3908,8 +4059,7 @@ pub fn atomicPtrAlignment(...@@ -3908,8 +4059,7 @@ pub fn atomicPtrAlignment(
3908 return error.BadType;4059 return error.BadType;
3909}4060}
39104061
3911/// Returns null in the following cases:4062/// Returns null if `ty` is not a struct.
3912/// * Not a struct.
3913pub fn typeToStruct(zcu: *const Zcu, ty: Type) ?InternPool.LoadedStructType {4063pub fn typeToStruct(zcu: *const Zcu, ty: Type) ?InternPool.LoadedStructType {
3914 if (ty.ip_index == .none) return null;4064 if (ty.ip_index == .none) return null;
3915 const ip = &zcu.intern_pool;4065 const ip = &zcu.intern_pool;
...@@ -3936,7 +4086,6 @@ pub fn structPackedFieldBitOffset(...@@ -3936,7 +4086,6 @@ pub fn structPackedFieldBitOffset(
3936) u16 {4086) u16 {
3937 const ip = &zcu.intern_pool;4087 const ip = &zcu.intern_pool;
3938 assert(struct_type.layout == .@"packed");4088 assert(struct_type.layout == .@"packed");
3939 assert(struct_type.haveLayout(ip));
3940 var bit_sum: u64 = 0;4089 var bit_sum: u64 = 0;
3941 for (0..struct_type.field_types.len) |i| {4090 for (0..struct_type.field_types.len) |i| {
3942 if (i == field_index) {4091 if (i == field_index) {
...@@ -3995,8 +4144,10 @@ pub const UnionLayout = struct {...@@ -3995,8 +4144,10 @@ pub const UnionLayout = struct {
3995pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 {4144pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 {
3996 const ip = &zcu.intern_pool;4145 const ip = &zcu.intern_pool;
3997 if (enum_tag.toIntern() == .none) return null;4146 if (enum_tag.toIntern() == .none) return null;
3998 assert(ip.typeOf(enum_tag.toIntern()) == loaded_union.enum_tag_ty);4147 const enum_tag_key = ip.indexToKey(enum_tag.toIntern()).enum_tag;
3999 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());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);
4000}4151}
40014152
4002pub const ResolvedReference = struct {4153pub const ResolvedReference = struct {
...@@ -4012,13 +4163,13 @@ pub const ResolvedReference = struct {...@@ -4012,13 +4163,13 @@ pub const ResolvedReference = struct {
4012/// If an `AnalUnit` is not in the returned map, it is unreferenced.4163/// If an `AnalUnit` is not in the returned map, it is unreferenced.
4013/// The returned hashmap is owned by the `Zcu`, so should not be freed by the caller.4164/// The returned hashmap is owned by the `Zcu`, so should not be freed by the caller.
4014/// This hashmap is cached, so repeated calls to this function are cheap.4165/// 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) {
4016 if (zcu.resolved_references == null) {4167 if (zcu.resolved_references == null) {
4017 zcu.resolved_references = try zcu.resolveReferencesInner();4168 zcu.resolved_references = try zcu.resolveReferencesInner();
4018 }4169 }
4019 return &zcu.resolved_references.?;4170 return &zcu.resolved_references.?;
4020}4171}
4021fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {4172fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
4022 const gpa = zcu.gpa;4173 const gpa = zcu.gpa;
4023 const comp = zcu.comp;4174 const comp = zcu.comp;
4024 const ip = &zcu.intern_pool;4175 const ip = &zcu.intern_pool;
...@@ -4049,32 +4200,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4049,32 +4200,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4049 const referencer = types.values()[type_idx];4200 const referencer = types.values()[type_idx];
4050 type_idx += 1;4201 type_idx += 1;
40514202
4052 log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});4203 refs_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 }
40784204
4079 // Queue any decls within this type which would be automatically analyzed.4205 // Queue any decls within this type which would be automatically analyzed.
4080 // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`.4206 // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`.
...@@ -4084,7 +4210,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4084,7 +4210,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4084 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });4210 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });
4085 const gop = try units.getOrPut(gpa, unit);4211 const gop = try units.getOrPut(gpa, unit);
4086 if (!gop.found_existing) {4212 if (!gop.found_existing) {
4087 log.debug("type '{f}': ref comptime %{}", .{4213 refs_log.debug("type '{f}': ref comptime %{}", .{
4088 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),4214 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
4089 @intFromEnum(ip.getComptimeUnit(cu).zir_index.resolve(ip) orelse continue),4215 @intFromEnum(ip.getComptimeUnit(cu).zir_index.resolve(ip) orelse continue),
4090 });4216 });
...@@ -4118,7 +4244,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4118,7 +4244,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4118 {4244 {
4119 const gop = try units.getOrPut(gpa, .wrap(.{ .nav_val = nav_id }));4245 const gop = try units.getOrPut(gpa, .wrap(.{ .nav_val = nav_id }));
4120 if (!gop.found_existing) {4246 if (!gop.found_existing) {
4121 log.debug("type '{f}': ref test %{}", .{4247 refs_log.debug("type '{f}': ref test %{}", .{
4122 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),4248 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
4123 @intFromEnum(inst_info.inst),4249 @intFromEnum(inst_info.inst),
4124 });4250 });
...@@ -4141,7 +4267,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4141,7 +4267,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4141 const unit: AnalUnit = .wrap(.{ .nav_val = nav });4267 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
4142 const gop = try units.getOrPut(gpa, unit);4268 const gop = try units.getOrPut(gpa, unit);
4143 if (!gop.found_existing) {4269 if (!gop.found_existing) {
4144 log.debug("type '{f}': ref named %{}", .{4270 refs_log.debug("type '{f}': ref named %{}", .{
4145 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),4271 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
4146 @intFromEnum(inst_info.inst),4272 @intFromEnum(inst_info.inst),
4147 });4273 });
...@@ -4158,7 +4284,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4158,7 +4284,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4158 const unit: AnalUnit = .wrap(.{ .nav_val = nav });4284 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
4159 const gop = try units.getOrPut(gpa, unit);4285 const gop = try units.getOrPut(gpa, unit);
4160 if (!gop.found_existing) {4286 if (!gop.found_existing) {
4161 log.debug("type '{f}': ref named %{}", .{4287 refs_log.debug("type '{f}': ref named %{}", .{
4162 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),4288 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
4163 @intFromEnum(inst_info.inst),4289 @intFromEnum(inst_info.inst),
4164 });4290 });
...@@ -4173,18 +4299,25 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4173,18 +4299,25 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4173 unit_idx += 1;4299 unit_idx += 1;
41744300
4175 // `nav_val` and `nav_ty` reference each other *implicitly* to save memory.4301 // `nav_val` and `nav_ty` reference each other *implicitly* to save memory.
4302 // Likewise for `type_layout` and `struct_defaults` of a struct type.
4176 queue_paired: {4303 queue_paired: {
4177 const other: AnalUnit = .wrap(switch (unit.unwrap()) {4304 const other: AnalUnit = .wrap(switch (unit.unwrap()) {
4178 .nav_val => |n| .{ .nav_ty = n },4305 .nav_val => |n| .{ .nav_ty = n },
4179 .nav_ty => |n| .{ .nav_val = n },4306 .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,
4181 });4314 });
4182 const gop = try units.getOrPut(gpa, other);4315 const gop = try units.getOrPut(gpa, other);
4183 if (gop.found_existing) break :queue_paired;4316 if (gop.found_existing) break :queue_paired;
4184 gop.value_ptr.* = units.values()[unit_idx]; // same reference location4317 gop.value_ptr.* = units.values()[unit_idx - 1]; // same reference location
4185 }4318 }
41864319
4187 log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});4320 refs_log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});
41884321
4189 if (zcu.reference_table.get(unit)) |first_ref_idx| {4322 if (zcu.reference_table.get(unit)) |first_ref_idx| {
4190 assert(first_ref_idx != std.math.maxInt(u32));4323 assert(first_ref_idx != std.math.maxInt(u32));
...@@ -4193,7 +4326,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4193,7 +4326,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4193 const ref = zcu.all_references.items[ref_idx];4326 const ref = zcu.all_references.items[ref_idx];
4194 const gop = try units.getOrPut(gpa, ref.referenced);4327 const gop = try units.getOrPut(gpa, ref.referenced);
4195 if (!gop.found_existing) {4328 if (!gop.found_existing) {
4196 log.debug("unit '{f}': ref unit '{f}'", .{4329 refs_log.debug("unit '{f}': ref unit '{f}'", .{
4197 zcu.fmtAnalUnit(unit),4330 zcu.fmtAnalUnit(unit),
4198 zcu.fmtAnalUnit(ref.referenced),4331 zcu.fmtAnalUnit(ref.referenced),
4199 });4332 });
...@@ -4213,7 +4346,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4213,7 +4346,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
4213 const ref = zcu.all_type_references.items[ref_idx];4346 const ref = zcu.all_type_references.items[ref_idx];
4214 const gop = try types.getOrPut(gpa, ref.referenced);4347 const gop = try types.getOrPut(gpa, ref.referenced);
4215 if (!gop.found_existing) {4348 if (!gop.found_existing) {
4216 log.debug("unit '{f}': ref type '{f}'", .{4349 refs_log.debug("unit '{f}': ref type '{f}'", .{
4217 zcu.fmtAnalUnit(unit),4350 zcu.fmtAnalUnit(unit),
4218 Type.fromInterned(ref.referenced).containerTypeName(ip).fmt(ip),4351 Type.fromInterned(ref.referenced).containerTypeName(ip).fmt(ip),
4219 });4352 });
...@@ -4298,6 +4431,16 @@ pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File {...@@ -4298,6 +4431,16 @@ pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File {
4298 return zcu.fileByIndex(zcu.navFileScopeIndex(nav));4431 return zcu.fileByIndex(zcu.navFileScopeIndex(nav));
4299}4432}
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
4301pub fn fmtAnalUnit(zcu: *Zcu, unit: AnalUnit) std.fmt.Alt(FormatAnalUnit, formatAnalUnit) {4444pub fn fmtAnalUnit(zcu: *Zcu, unit: AnalUnit) std.fmt.Alt(FormatAnalUnit, formatAnalUnit) {
4302 return .{ .data = .{ .unit = unit, .zcu = zcu } };4445 return .{ .data = .{ .unit = unit, .zcu = zcu } };
4303}4446}
...@@ -4305,11 +4448,7 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Alt(FormatDependee...@@ -4305,11 +4448,7 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Alt(FormatDependee
4305 return .{ .data = .{ .dependee = d, .zcu = zcu } };4448 return .{ .data = .{ .dependee = d, .zcu = zcu } };
4306}4449}
43074450
4308const FormatAnalUnit = struct {4451const FormatAnalUnit = struct { unit: AnalUnit, zcu: *const Zcu };
4309 unit: AnalUnit,
4310 zcu: *Zcu,
4311};
4312
4313fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void {4452fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void {
4314 const zcu = data.zcu;4453 const zcu = data.zcu;
4315 const ip = &zcu.intern_pool;4454 const ip = &zcu.intern_pool;
...@@ -4323,9 +4462,8 @@ fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void...@@ -4323,9 +4462,8 @@ fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void
4323 return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)});4462 return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)});
4324 }4463 }
4325 },4464 },
4326 .nav_val => |nav| return writer.print("nav_val('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),4465 .nav_val, .nav_ty => |nav, tag| return writer.print("{t}('{f}' [{}])", .{ tag, 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) }),4466 .type_layout, .struct_defaults => |ty, tag| return writer.print("{t}('{f}' [{}])", .{ tag, Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
4328 .type => |ty| return writer.print("ty('{f}' [{}])", .{ Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
4329 .func => |func| {4467 .func => |func| {
4330 const nav = zcu.funcInfo(func).owner_nav;4468 const nav = zcu.funcInfo(func).owner_nav;
4331 return writer.print("func('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });4469 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...@@ -4334,8 +4472,7 @@ fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void
4334 }4472 }
4335}4473}
43364474
4337const FormatDependee = struct { dependee: InternPool.Dependee, zcu: *Zcu };4475const FormatDependee = struct { dependee: InternPool.Dependee, zcu: *const Zcu };
4338
4339fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void {4476fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void {
4340 const zcu = data.zcu;4477 const zcu = data.zcu;
4341 const ip = &zcu.intern_pool;4478 const ip = &zcu.intern_pool;
...@@ -4347,18 +4484,17 @@ fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void...@@ -4347,18 +4484,17 @@ fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void
4347 const file_path = zcu.fileByIndex(info.file).path;4484 const file_path = zcu.fileByIndex(info.file).path;
4348 return writer.print("inst('{f}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });4485 return writer.print("inst('{f}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });
4349 },4486 },
4350 .nav_val => |nav| {4487 .nav_val, .nav_ty => |nav, tag| {
4351 const fqn = ip.getNav(nav).fqn;4488 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) });
4353 },4490 },
4354 .nav_ty => |nav| {4491 .type_layout, .struct_defaults => |ip_index, tag| {
4355 const fqn = ip.getNav(nav).fqn;4492 const name = Type.fromInterned(ip_index).containerTypeName(ip);
4356 return writer.print("nav_ty('{f}')", .{fqn.fmt(ip)});4493 return writer.print("{t}('{f}')", .{ tag, name.fmt(ip) });
4357 },4494 },
4358 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {4495 .func_ies => |ip_index| {
4359 .struct_type, .union_type, .enum_type => return writer.print("type('{f}')", .{Type.fromInterned(ip_index).containerTypeName(ip).fmt(ip)}),4496 const fqn = ip.getNav(ip.indexToKey(ip_index).func.owner_nav).fqn;
4360 .func => |f| return writer.print("ies('{f}')", .{ip.getNav(f.owner_nav).fqn.fmt(ip)}),4497 return writer.print("func_ies('{f}')", .{fqn.fmt(ip)});
4361 else => unreachable,
4362 },4498 },
4363 .zon_file => |file| {4499 .zon_file => |file| {
4364 const file_path = zcu.fileByIndex(file).path;4500 const file_path = zcu.fileByIndex(file).path;
...@@ -4386,32 +4522,6 @@ fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void...@@ -4386,32 +4522,6 @@ fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void
4386 }4522 }
4387}4523}
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
4415pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enum) {4525pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enum) {
4416 ok,4526 ok,
4417 bad_arch: []const std.Target.Cpu.Arch, // value is allowed archs for cc4527 bad_arch: []const std.Target.Cpu.Arch, // value is allowed archs for cc
...@@ -4747,6 +4857,304 @@ fn explainWhyFileIsInModule(...@@ -4747,6 +4857,304 @@ fn explainWhyFileIsInModule(
4747 }4857 }
4748}4858}
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
4750const TrackedUnitSema = struct {5158const TrackedUnitSema = struct {
4751 /// `null` means we created the node, so should end it.5159 /// `null` means we created the node, so should end it.
4752 old_name: ?[std.Progress.Node.max_name_len]u8,5160 old_name: ?[std.Progress.Node.max_name_len]u8,
src/Zcu/PerThread.zig+1060-1109
...@@ -27,7 +27,9 @@ const introspect = @import("../introspect.zig");...@@ -27,7 +27,9 @@ const introspect = @import("../introspect.zig");
27const Module = @import("../Package.zig").Module;27const Module = @import("../Package.zig").Module;
28const Sema = @import("../Sema.zig");28const Sema = @import("../Sema.zig");
29const target_util = @import("../target.zig");29const target_util = @import("../target.zig");
30const trace = @import("../tracy.zig").trace;30const tracy = @import("../tracy.zig");
31const trace = tracy.trace;
32const traceNamed = tracy.traceNamed;
31const Type = @import("../Type.zig");33const Type = @import("../Type.zig");
32const Value = @import("../Value.zig");34const Value = @import("../Value.zig");
33const Zcu = @import("../Zcu.zig");35const Zcu = @import("../Zcu.zig");
...@@ -125,6 +127,329 @@ pub fn deactivate(pt: Zcu.PerThread) void {...@@ -125,6 +127,329 @@ pub fn deactivate(pt: Zcu.PerThread) void {
125 pt.zcu.intern_pool.deactivate();127 pt.zcu.intern_pool.deactivate();
126}128}
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
128fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {453fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
129 const zcu = pt.zcu;454 const zcu = pt.zcu;
130 const gpa = zcu.gpa;455 const gpa = zcu.gpa;
...@@ -156,8 +481,8 @@ pub fn updateFile(...@@ -156,8 +481,8 @@ pub fn updateFile(
156) !void {481) !void {
157 dev.check(.ast_gen);482 dev.check(.ast_gen);
158483
159 const tracy = trace(@src());484 const tracy_trace = trace(@src());
160 defer tracy.end();485 defer tracy_trace.end();
161486
162 const zcu = pt.zcu;487 const zcu = pt.zcu;
163 const comp = zcu.comp;488 const comp = zcu.comp;
...@@ -484,7 +809,7 @@ fn cleanupUpdatedFiles(gpa: Allocator, updated_files: *std.AutoArrayHashMapUnman...@@ -484,7 +809,7 @@ fn cleanupUpdatedFiles(gpa: Allocator, updated_files: *std.AutoArrayHashMapUnman
484 updated_files.deinit(gpa);809 updated_files.deinit(gpa);
485}810}
486811
487pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {812fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
488 assert(pt.tid == .main);813 assert(pt.tid == .main);
489 const zcu = pt.zcu;814 const zcu = pt.zcu;
490 const comp = zcu.comp;815 const comp = zcu.comp;
...@@ -566,7 +891,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {...@@ -566,7 +891,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
566 const old_line = old_zir.getDeclaration(old_inst).src_line;891 const old_line = old_zir.getDeclaration(old_inst).src_line;
567 const new_line = new_zir.getDeclaration(new_inst).src_line;892 const new_line = new_zir.getDeclaration(new_inst).src_line;
568 if (old_line != new_line) {893 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 });
570 }895 }
571 },896 },
572 else => {},897 else => {},
...@@ -598,44 +923,38 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {...@@ -598,44 +923,38 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
598 // Value is whether the declaration is `pub`.923 // Value is whether the declaration is `pub`.
599 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, bool) = .empty;924 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, bool) = .empty;
600 defer old_names.deinit(zcu.gpa);925 defer old_names.deinit(zcu.gpa);
601 {926 for (old_zir.typeDecls(old_inst)) |decl_inst| {
602 var it = old_zir.declIterator(old_inst);927 const old_decl = old_zir.getDeclaration(decl_inst);
603 while (it.next()) |decl_inst| {928 if (old_decl.name == .empty) continue;
604 const old_decl = old_zir.getDeclaration(decl_inst);929 const name_ip = try zcu.intern_pool.getOrPutString(
605 if (old_decl.name == .empty) continue;930 zcu.gpa,
606 const name_ip = try zcu.intern_pool.getOrPutString(931 io,
607 zcu.gpa,932 pt.tid,
608 io,933 old_zir.nullTerminatedString(old_decl.name),
609 pt.tid,934 .no_embedded_nulls,
610 old_zir.nullTerminatedString(old_decl.name),935 );
611 .no_embedded_nulls,936 try old_names.put(zcu.gpa, name_ip, old_decl.is_pub);
612 );
613 try old_names.put(zcu.gpa, name_ip, old_decl.is_pub);
614 }
615 }937 }
616 var any_change = false;938 var any_change = false;
617 {939 for (new_zir.typeDecls(new_inst)) |decl_inst| {
618 var it = new_zir.declIterator(new_inst);940 const new_decl = new_zir.getDeclaration(decl_inst);
619 while (it.next()) |decl_inst| {941 if (new_decl.name == .empty) continue;
620 const new_decl = new_zir.getDeclaration(decl_inst);942 const name_ip = try zcu.intern_pool.getOrPutString(
621 if (new_decl.name == .empty) continue;943 zcu.gpa,
622 const name_ip = try zcu.intern_pool.getOrPutString(944 io,
623 zcu.gpa,945 pt.tid,
624 io,946 new_zir.nullTerminatedString(new_decl.name),
625 pt.tid,947 .no_embedded_nulls,
626 new_zir.nullTerminatedString(new_decl.name),948 );
627 .no_embedded_nulls,949 if (old_names.fetchSwapRemove(name_ip)) |kv| {
628 );950 if (kv.value == new_decl.is_pub) continue;
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 } });
638 }951 }
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 } });
639 }958 }
640 // The only elements remaining in `old_names` now are any names which were removed.959 // The only elements remaining in `old_names` now are any names which were removed.
641 for (old_names.keys()) |name_ip| {960 for (old_names.keys()) |name_ip| {
...@@ -674,32 +993,74 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {...@@ -674,32 +993,74 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
674 }993 }
675}994}
676995
677/// Ensures that `zcu.fileRootType` on this `file_index` gives an up-to-date answer.996/// Ensures that `zcu.fileRootType` on this `file_index` is populated (not `.none`). This implies
678/// Returns `error.AnalysisFail` if the file has an error.997/// that the file's namespace is scanned, discovering declarations.
679pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {998///
680 const file_root_type = pt.zcu.fileRootType(file_index);999/// Typical Zig compilations begin by claling this function on the root source file of the standard
681 if (file_root_type != .none) {1000/// library, `lib/std/std.zig`. The resulting namespace scan discovers a `comptime` declaration in
682 if (pt.ensureTypeUpToDate(file_root_type)) |_| {1001/// that file, which is queued for analysis, and everything goes from there.
683 return;1002pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Allocator.Error || Io.Cancelable)!void {
684 } else |err| switch (err) {1003 dev.check(.sema);
685 error.AnalysisFail => {1004
686 // The file's root `struct_decl` has, at some point, been lost, because the file failed AstGen.1005 const tracy_trace = trace(@src());
687 // Clear `file_root_type`, and try the `semaFile` call below, in case the instruction has since1006 defer tracy_trace.end();
688 // been discovered under a new `TrackedInst.Index`.1007
689 pt.zcu.setFileRootType(file_index, .none);1008 const zcu = pt.zcu;
690 },1009 const comp = zcu.comp;
691 else => |e| return e,1010 const io = comp.io;
692 }1011 const gpa = comp.gpa;
693 }1012 const ip = &zcu.intern_pool;
694 return pt.semaFile(file_index);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));
695}1051}
6961052
697/// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary.1053/// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary.
698/// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore1054/// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore
699/// this, since the error is already registered, but it must not use the value of memoized fields.1055/// 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 {1056pub fn ensureMemoizedStateUpToDate(
701 const tracy = trace(@src());1057 pt: Zcu.PerThread,
702 defer tracy.end();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
704 const zcu = pt.zcu;1065 const zcu = pt.zcu;
705 const gpa = zcu.gpa;1066 const gpa = zcu.gpa;
...@@ -710,19 +1071,11 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized...@@ -710,19 +1071,11 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
7101071
711 assert(!zcu.analysis_in_progress.contains(unit));1072 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);
714 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);1075 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);
7151076
716 if (was_outdated) {1077 if (was_outdated) {
717 dev.check(.incremental);1078 zcu.resetUnit(unit);
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);
726 } else {1079 } else {
727 if (prev_failed) return error.AnalysisFail;1080 if (prev_failed) return error.AnalysisFail;
728 // We use an arbitrary element to check if the state has been resolved yet.1081 // 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...@@ -741,7 +1094,7 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
741 info.deps.clearRetainingCapacity();1094 info.deps.clearRetainingCapacity();
742 }1095 }
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|
745 .{ any_changed or prev_failed, false }1098 .{ any_changed or prev_failed, false }
746 else |err| switch (err) {1099 else |err| switch (err) {
747 error.AnalysisFail => res: {1100 error.AnalysisFail => res: {
...@@ -774,39 +1127,20 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized...@@ -774,39 +1127,20 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
774 if (new_failed) return error.AnalysisFail;1127 if (new_failed) return error.AnalysisFail;
775}1128}
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 {
778 const zcu = pt.zcu;1135 const zcu = pt.zcu;
779 const ip = &zcu.intern_pool;
780 const comp = zcu.comp;1136 const comp = zcu.comp;
781 const gpa = comp.gpa;1137 const gpa = comp.gpa;
782 const io = comp.io;
7831138
784 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });1139 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);
787 defer assert(zcu.analysis_in_progress.swapRemove(unit));1142 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
810 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);1144 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
811 defer analysis_arena.deinit();1145 defer analysis_arena.deinit();
8121146
...@@ -827,30 +1161,15 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage)...@@ -827,30 +1161,15 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage)
827 };1161 };
828 defer sema.deinit();1162 defer sema.deinit();
8291163
830 var block: Sema.Block = .{1164 return sema.analyzeMemoizedState(stage);
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);
846}1165}
8471166
848/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis1167/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis
849/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is1168/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
850/// free to ignore this, since the error is already registered.1169/// free to ignore this, since the error is already registered.
851pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.SemaError!void {1170pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.SemaError!void {
852 const tracy = trace(@src());1171 const tracy_trace = trace(@src());
853 defer tracy.end();1172 defer tracy_trace.end();
8541173
855 const zcu = pt.zcu;1174 const zcu = pt.zcu;
856 const gpa = zcu.gpa;1175 const gpa = zcu.gpa;
...@@ -870,22 +1189,10 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU...@@ -870,22 +1189,10 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
870 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by1189 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by
871 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.1190 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.
8721191
873 const was_outdated = zcu.outdated.swapRemove(anal_unit) or1192 const was_outdated = zcu.clearOutdatedState(anal_unit);
874 zcu.potentially_outdated.swapRemove(anal_unit);
8751193
876 if (was_outdated) {1194 if (was_outdated) {
877 _ = zcu.outdated_ready.swapRemove(anal_unit);1195 zcu.resetUnit(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 }
889 } else {1196 } else {
890 // We can trust the current information about this unit.1197 // We can trust the current information about this unit.
891 if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail;1198 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...@@ -950,7 +1257,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
950 const file = zcu.fileByIndex(inst_resolved.file);1257 const file = zcu.fileByIndex(inst_resolved.file);
951 const zir = file.zir.?;1258 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);
954 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));1261 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
9551262
956 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);1263 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
...@@ -980,7 +1287,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu...@@ -980,7 +1287,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
980 .parent = null,1287 .parent = null,
981 .sema = &sema,1288 .sema = &sema,
982 .namespace = comptime_unit.namespace,1289 .namespace = comptime_unit.namespace,
983 .instructions = .{},1290 .instructions = .empty,
984 .inlining = null,1291 .inlining = null,
985 .comptime_reason = .{ .reason = .{1292 .comptime_reason = .{ .reason = .{
986 .src = .{1293 .src = .{
...@@ -1012,33 +1319,262 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu...@@ -1012,33 +1319,262 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
1012 try sema.flushExports();1319 try sema.flushExports();
1013}1320}
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
1015/// Ensures that the resolved value of the given `Nav` is fully up-to-date, performing re-analysis1562/// Ensures that the resolved value of the given `Nav` is fully up-to-date, performing re-analysis
1016/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is1563/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
1017/// free to ignore this, since the error is already registered.1564/// free to ignore this, since the error is already registered.
1018pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.SemaError!void {1565pub fn ensureNavValUpToDate(
1019 const tracy = trace(@src());1566 pt: Zcu.PerThread,
1020 defer tracy.end();1567 nav_id: InternPool.Nav.Index,
10211568 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
1022 // TODO: document this elsewhere mlugg!1569 reason: ?*const Zcu.DependencyReason,
1023 // For my own benefit, here's how a namespace update for a normal (non-file-root) type works:1570) Zcu.SemaError!void {
1024 // `const S = struct { ... };`1571 const tracy_trace = trace(@src());
1025 // We are adding or removing a declaration within this `struct`.1572 defer tracy_trace.end();
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
10351573
1036 const zcu = pt.zcu;1574 const zcu = pt.zcu;
1037 const gpa = zcu.gpa;1575 const gpa = zcu.gpa;
1038 const ip = &zcu.intern_pool;1576 const ip = &zcu.intern_pool;
10391577
1040 _ = zcu.nav_val_analysis_queued.swapRemove(nav_id);
1041
1042 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });1578 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
1043 const nav = ip.getNav(nav_id);1579 const nav = ip.getNav(nav_id);
10441580
...@@ -1046,6 +1582,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1046,6 +1582,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
10461582
1047 assert(!zcu.analysis_in_progress.contains(anal_unit));1583 assert(!zcu.analysis_in_progress.contains(anal_unit));
10481584
1585 try zcu.ensureNavValAnalysisQueued(nav_id);
1586
1049 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the1587 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
1050 // status is `.unresolved`, which indicates that the value is outdated because it has *never*1588 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
1051 // been analyzed so far.1589 // been analyzed so far.
...@@ -1055,30 +1593,18 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1055,30 +1593,18 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
1055 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by1593 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by
1056 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.1594 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.
10571595
1058 const was_outdated = zcu.outdated.swapRemove(anal_unit) or1596 const was_outdated = zcu.clearOutdatedState(anal_unit);
1059 zcu.potentially_outdated.swapRemove(anal_unit);
10601597
1061 const prev_failed = zcu.failed_analysis.contains(anal_unit) or1598 const prev_failed = zcu.failed_analysis.contains(anal_unit) or
1062 zcu.transitive_failed_analysis.contains(anal_unit);1599 zcu.transitive_failed_analysis.contains(anal_unit);
10631600
1064 if (was_outdated) {1601 if (was_outdated) {
1065 dev.check(.incremental);1602 zcu.resetUnit(anal_unit);
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);
1075 } else {1603 } else {
1076 // We can trust the current information about this unit.1604 // We can trust the current information about this unit.
1077 if (prev_failed) return error.AnalysisFail;1605 if (prev_failed) return error.AnalysisFail;
1078 switch (nav.status) {1606 assert(nav.status == .fully_resolved);
1079 .unresolved, .type_resolved => {},1607 return;
1080 .fully_resolved => return,
1081 }
1082 }1608 }
10831609
1084 if (zcu.comp.debugIncremental()) {1610 if (zcu.comp.debugIncremental()) {
...@@ -1090,7 +1616,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1090,7 +1616,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
1090 const unit_tracking = zcu.trackUnitSema(nav.fqn.toSlice(ip), nav.srcInst(ip));1616 const unit_tracking = zcu.trackUnitSema(nav.fqn.toSlice(ip), nav.srcInst(ip));
1091 defer unit_tracking.end(zcu);1617 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: {
1094 break :res .{1620 break :res .{
1095 // If the unit has gone from failed to success, we still need to invalidate the dependencies.1621 // If the unit has gone from failed to success, we still need to invalidate the dependencies.
1096 result.val_changed or prev_failed,1622 result.val_changed or prev_failed,
...@@ -1134,39 +1660,14 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1134,39 +1660,14 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
1134 }1660 }
1135 }1661 }
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
1166 if (new_failed) return error.AnalysisFail;1663 if (new_failed) return error.AnalysisFail;
1167}1664}
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 } {
1170 const zcu = pt.zcu;1671 const zcu = pt.zcu;
1171 const ip = &zcu.intern_pool;1672 const ip = &zcu.intern_pool;
1172 const comp = zcu.comp;1673 const comp = zcu.comp;
...@@ -1183,16 +1684,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1183,16 +1684,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1183 const zir = file.zir.?;1684 const zir = file.zir.?;
1184 const zir_decl = zir.getDeclaration(inst_resolved.inst);1685 const zir_decl = zir.getDeclaration(inst_resolved.inst);
11851686
1186 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});1687 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason);
1187 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);1688 defer assert(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 };
11961689
1197 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);1690 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
1198 defer analysis_arena.deinit();1691 defer analysis_arena.deinit();
...@@ -1225,7 +1718,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1225,7 +1718,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1225 .parent = null,1718 .parent = null,
1226 .sema = &sema,1719 .sema = &sema,
1227 .namespace = old_nav.analysis.?.namespace,1720 .namespace = old_nav.analysis.?.namespace,
1228 .instructions = .{},1721 .instructions = .empty,
1229 .inlining = null,1722 .inlining = null,
1230 .comptime_reason = undefined, // set below1723 .comptime_reason = undefined, // set below
1231 .src_base_inst = old_nav.analysis.?.zir_index,1724 .src_base_inst = old_nav.analysis.?.zir_index,
...@@ -1246,9 +1739,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1246,9 +1739,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
12461739
1247 const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: {1740 const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: {
1248 // Since we have a type body, the type is resolved separately!1741 // Since we have a type body, the type is resolved separately!
1249 // Of course, we need to make sure we depend on it properly.1742 try sema.ensureNavResolved(&block, init_src, nav_id, .type);
1250 try sema.declareDependency(.{ .nav_ty = nav_id });
1251 try pt.ensureNavTypeUpToDate(nav_id);
1252 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));1743 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));
1253 } else null;1744 } else null;
12541745
...@@ -1271,9 +1762,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1271,9 +1762,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
12711762
1272 const nav_ty: Type = maybe_ty orelse final_val.?.typeOf(zcu);1763 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
1277 const is_const = is_const: switch (zir_decl.kind) {1765 const is_const = is_const: switch (zir_decl.kind) {
1278 .@"comptime" => unreachable, // this is not a Nav1766 .@"comptime" => unreachable, // this is not a Nav
1279 .unnamed_test, .@"test", .decltest => {1767 .unnamed_test, .@"test", .decltest => {
...@@ -1360,7 +1848,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1360,7 +1848,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
13601848
1361 // This resolves the type of the resolved value, not that value itself. If `nav_val` is a struct type,1849 // This resolves the type of the resolved value, not that value itself. If `nav_val` is a struct type,
1362 // this resolves the type `type` (which needs no resolution), not the struct itself.1850 // 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
1365 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {1853 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {
1366 .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen1854 .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...@@ -1377,23 +1865,47 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1377 if (zir_decl.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) {1865 if (zir_decl.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) {
1378 return sema.fail(&block, align_src, "target does not support function alignment", .{});1866 return sema.fail(&block, align_src, "target does not support function alignment", .{});
1379 }1867 }
1380 } else if (try nav_ty.comptimeOnlySema(pt)) {1868 } else if (nav_ty.comptimeOnly(zcu)) {
1381 // alignment, linksection, addrspace annotations are not allowed for comptime-only types.1869 // 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())) {
1383 .func => "function alias", // slightly clearer message, since you *can* specify these on function *declarations*1871 .func => "function alias", // slightly clearer message, since you *can* specify these on function *declarations*
1384 else => "comptime-only type",1872 else => "comptime-only type",
1385 };1873 };
1386 if (zir_decl.align_body != null) {1874 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});
1388 }1876 }
1389 if (zir_decl.linksection_body != null) {1877 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});
1391 }1879 }
1392 if (zir_decl.addrspace_body != null) {1880 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});
1394 }1882 }
1395 }1883 }
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 }
1397 ip.resolveNavValue(io, nav_id, .{1909 ip.resolveNavValue(io, nav_id, .{
1398 .val = nav_val.toIntern(),1910 .val = nav_val.toIntern(),
1399 .is_const = is_const,1911 .is_const = is_const,
...@@ -1402,17 +1914,11 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1402,17 +1914,11 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1402 .@"addrspace" = modifiers.@"addrspace",1914 .@"addrspace" = modifiers.@"addrspace",
1403 });1915 });
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
1411 if (zir_decl.linkage == .@"export") {1917 if (zir_decl.linkage == .@"export") {
1412 const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) });1918 const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) });
1413 const name_slice = zir.nullTerminatedString(zir_decl.name);1919 const name_slice = zir.nullTerminatedString(zir_decl.name);
1414 const name_ip = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);1920 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);
1416 }1922 }
14171923
1418 try sema.flushExports();1924 try sema.flushExports();
...@@ -1420,25 +1926,37 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1420,25 +1926,37 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1420 queue_codegen: {1926 queue_codegen: {
1421 if (!queue_linker_work) break :queue_codegen;1927 if (!queue_linker_work) break :queue_codegen;
14221928
1423 if (!try nav_ty.hasRuntimeBitsSema(pt)) {1929 if (!nav_ty.hasRuntimeBits(zcu)) {
1424 if (zcu.comp.config.use_llvm) break :queue_codegen;1930 if (comp.config.use_llvm) break :queue_codegen;
1425 if (file.mod.?.strip) break :queue_codegen;1931 if (file.mod.?.strip) break :queue_codegen;
1426 }1932 }
14271933
1428 // This job depends on any resolve_type_fully jobs queued up before it.1934 comp.link_prog_node.increaseEstimatedTotalItems(1);
1429 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);1935 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .link_nav = nav_id });
1430 try zcu.comp.queueJob(.{ .link_nav = nav_id });
1431 }1936 }
14321937
1433 switch (old_nav.status) {1938 if (comp.config.is_test and zcu.test_functions.contains(nav_id)) {
1434 .unresolved, .type_resolved => return .{ .val_changed = true },1939 // We just analyzed a test function's "value" (essentially its signature); now we need to
1435 .fully_resolved => |old| return .{ .val_changed = old.val != nav_val.toIntern() },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());
1436 }1944 }
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 };
1437}1950}
14381951
1439pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.SemaError!void {1952pub fn ensureNavTypeUpToDate(
1440 const tracy = trace(@src());1953 pt: Zcu.PerThread,
1441 defer tracy.end();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
1443 const zcu = pt.zcu;1961 const zcu = pt.zcu;
1444 const gpa = zcu.gpa;1962 const gpa = zcu.gpa;
...@@ -1451,17 +1969,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1451,17 +1969,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
14511969
1452 assert(!zcu.analysis_in_progress.contains(anal_unit));1970 assert(!zcu.analysis_in_progress.contains(anal_unit));
14531971
1454 const type_resolved_by_value: bool = from_val: {1972 try zcu.ensureNavValAnalysisQueued(nav_id);
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 }
14651973
1466 // Determine whether or not this `Nav`'s type is outdated. This also includes checking if the1974 // Determine whether or not this `Nav`'s type is outdated. This also includes checking if the
1467 // status is `.unresolved`, which indicates that the value is outdated because it has *never*1975 // 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...@@ -1472,30 +1980,18 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
1472 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by1980 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by
1473 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.1981 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.
14741982
1475 const was_outdated = zcu.outdated.swapRemove(anal_unit) or1983 const was_outdated = zcu.clearOutdatedState(anal_unit);
1476 zcu.potentially_outdated.swapRemove(anal_unit);
14771984
1478 const prev_failed = zcu.failed_analysis.contains(anal_unit) or1985 const prev_failed = zcu.failed_analysis.contains(anal_unit) or
1479 zcu.transitive_failed_analysis.contains(anal_unit);1986 zcu.transitive_failed_analysis.contains(anal_unit);
14801987
1481 if (was_outdated) {1988 if (was_outdated) {
1482 dev.check(.incremental);1989 zcu.resetUnit(anal_unit);
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);
1492 } else {1990 } else {
1493 // We can trust the current information about this unit.1991 // We can trust the current information about this unit.
1494 if (prev_failed) return error.AnalysisFail;1992 if (prev_failed) return error.AnalysisFail;
1495 switch (nav.status) {1993 assert(nav.status != .unresolved);
1496 .unresolved => {},1994 return;
1497 .type_resolved, .fully_resolved => return,
1498 }
1499 }1995 }
15001996
1501 if (zcu.comp.debugIncremental()) {1997 if (zcu.comp.debugIncremental()) {
...@@ -1507,7 +2003,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1507,7 +2003,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
1507 const unit_tracking = zcu.trackUnitSema(nav.fqn.toSlice(ip), nav.srcInst(ip));2003 const unit_tracking = zcu.trackUnitSema(nav.fqn.toSlice(ip), nav.srcInst(ip));
1508 defer unit_tracking.end(zcu);2004 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: {
1511 break :res .{2007 break :res .{
1512 // If the unit has gone from failed to success, we still need to invalidate the dependencies.2008 // If the unit has gone from failed to success, we still need to invalidate the dependencies.
1513 result.type_changed or prev_failed,2009 result.type_changed or prev_failed,
...@@ -1554,7 +2050,11 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1554,7 +2050,11 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
1554 if (new_failed) return error.AnalysisFail;2050 if (new_failed) return error.AnalysisFail;
1555}2051}
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 } {
1558 const zcu = pt.zcu;2058 const zcu = pt.zcu;
1559 const comp = zcu.comp;2059 const comp = zcu.comp;
1560 const gpa = comp.gpa;2060 const gpa = comp.gpa;
...@@ -1570,11 +2070,10 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1570,11 +2070,10 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1570 const file = zcu.fileByIndex(inst_resolved.file);2070 const file = zcu.fileByIndex(inst_resolved.file);
1571 const zir = file.zir.?;2071 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);
1574 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));2074 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
15752075
1576 const zir_decl = zir.getDeclaration(inst_resolved.inst);2076 const zir_decl = zir.getDeclaration(inst_resolved.inst);
1577 const type_body = zir_decl.type_body.?;
15782077
1579 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);2078 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
1580 defer analysis_arena.deinit();2079 defer analysis_arena.deinit();
...@@ -1607,7 +2106,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1607,7 +2106,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1607 .parent = null,2106 .parent = null,
1608 .sema = &sema,2107 .sema = &sema,
1609 .namespace = old_nav.analysis.?.namespace,2108 .namespace = old_nav.analysis.?.namespace,
1610 .instructions = .{},2109 .instructions = .empty,
1611 .inlining = null,2110 .inlining = null,
1612 .comptime_reason = undefined, // set below2111 .comptime_reason = undefined, // set below
1613 .src_base_inst = old_nav.analysis.?.zir_index,2112 .src_base_inst = old_nav.analysis.?.zir_index,
...@@ -1616,6 +2115,34 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1616,6 +2115,34 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1616 defer block.instructions.deinit(gpa);2115 defer block.instructions.deinit(gpa);
16172116
1618 const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero });2117 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
1620 block.comptime_reason = .{ .reason = .{2147 block.comptime_reason = .{ .reason = .{
1621 .src = ty_src,2148 .src = ty_src,
...@@ -1628,7 +2155,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1628,7 +2155,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1628 break :ty .fromInterned(type_ref.toInterned().?);2155 break :ty .fromInterned(type_ref.toInterned().?);
1629 };2156 };
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
1633 // In the case where the type is specified, this function is also responsible for resolving2160 // In the case where the type is specified, this function is also responsible for resolving
1634 // the pointer modifiers, i.e. alignment, linksection, addrspace.2161 // the pointer modifiers, i.e. alignment, linksection, addrspace.
...@@ -1678,18 +2205,24 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1678,18 +2205,24 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1678 return .{ .type_changed = true };2205 return .{ .type_changed = true };
1679}2206}
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 {
1682 dev.check(.sema);2217 dev.check(.sema);
16832218
1684 const tracy = trace(@src());2219 const tracy_trace = trace(@src());
1685 defer tracy.end();2220 defer tracy_trace.end();
16862221
1687 const zcu = pt.zcu;2222 const zcu = pt.zcu;
1688 const gpa = zcu.gpa;2223 const gpa = zcu.gpa;
1689 const ip = &zcu.intern_pool;2224 const ip = &zcu.intern_pool;
16902225
1691 _ = zcu.func_body_analysis_queued.swapRemove(func_index);
1692
1693 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });2226 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });
16942227
1695 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});2228 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
...@@ -1700,27 +2233,17 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1700,27 +2233,17 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
17002233
1701 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one2234 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) or2236 const was_outdated = zcu.clearOutdatedState(anal_unit) or
1704 zcu.potentially_outdated.swapRemove(anal_unit);2237 ip.setWantRuntimeFnAnalysis(zcu.comp.io, func_index);
17052238
1706 const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit);2239 const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit);
17072240
1708 if (was_outdated) {2241 if (was_outdated) {
1709 dev.check(.incremental);2242 zcu.resetUnit(anal_unit);
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);
1718 } else {2243 } else {
1719 // We can trust the current information about this function.2244 // We can trust the current information about this function.
1720 if (prev_failed) {2245 if (prev_failed) return error.AnalysisFail;
1721 return error.AnalysisFail;2246 return;
1722 }
1723 if (func.analysisUnordered(ip).is_analyzed) return;
1724 }2247 }
17252248
1726 if (zcu.comp.debugIncremental()) {2249 if (zcu.comp.debugIncremental()) {
...@@ -1736,7 +2259,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1736,7 +2259,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
1736 );2259 );
1737 defer unit_tracking.end(zcu);2260 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|
1740 .{ prev_failed or result.ies_outdated, false }2263 .{ prev_failed or result.ies_outdated, false }
1741 else |err| switch (err) {2264 else |err| switch (err) {
1742 error.AnalysisFail => res: {2265 error.AnalysisFail => res: {
...@@ -1765,9 +2288,9 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1765,9 +2288,9 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
17652288
1766 if (was_outdated) {2289 if (was_outdated) {
1767 if (ies_outdated) {2290 if (ies_outdated) {
1768 try zcu.markDependeeOutdated(.marked_po, .{ .interned = func_index });2291 try zcu.markDependeeOutdated(.marked_po, .{ .func_ies = func_index });
1769 } else {2292 } else {
1770 try zcu.markPoDependeeUpToDate(.{ .interned = func_index });2293 try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index });
1771 }2294 }
1772 }2295 }
17732296
...@@ -1777,6 +2300,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1777,6 +2300,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
1777fn analyzeFuncBody(2300fn analyzeFuncBody(
1778 pt: Zcu.PerThread,2301 pt: Zcu.PerThread,
1779 func_index: InternPool.Index,2302 func_index: InternPool.Index,
2303 reason: ?*const Zcu.DependencyReason,
1780) Zcu.SemaError!struct { ies_outdated: bool } {2304) Zcu.SemaError!struct { ies_outdated: bool } {
1781 const zcu = pt.zcu;2305 const zcu = pt.zcu;
1782 const gpa = zcu.gpa;2306 const gpa = zcu.gpa;
...@@ -1785,29 +2309,6 @@ fn analyzeFuncBody(...@@ -1785,29 +2309,6 @@ fn analyzeFuncBody(
1785 const func = zcu.funcInfo(func_index);2309 const func = zcu.funcInfo(func_index);
1786 const anal_unit = AnalUnit.wrap(.{ .func = func_index });2310 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
1811 // We'll want to remember what the IES used to be before the update for2312 // We'll want to remember what the IES used to be before the update for
1812 // dependency invalidation purposes.2313 // dependency invalidation purposes.
1813 const old_resolved_ies = if (func.analysisUnordered(ip).inferred_error_set)2314 const old_resolved_ies = if (func.analysisUnordered(ip).inferred_error_set)
...@@ -1817,8 +2318,9 @@ fn analyzeFuncBody(...@@ -1817,8 +2318,9 @@ fn analyzeFuncBody(
18172318
1818 log.debug("analyze and generate fn body {f}", .{zcu.fmtAnalUnit(anal_unit)});2319 log.debug("analyze and generate fn body {f}", .{zcu.fmtAnalUnit(anal_unit)});
18192320
1820 var air = try pt.analyzeFnBodyInner(func_index);2321 var air = try pt.analyzeFuncBodyInner(func_index, reason);
1821 errdefer air.deinit(gpa);2322 var air_owned = true;
2323 defer if (air_owned) air.deinit(gpa);
18222324
1823 const ies_outdated = !func.analysisUnordered(ip).inferred_error_set or2325 const ies_outdated = !func.analysisUnordered(ip).inferred_error_set or
1824 func.resolvedErrorSetUnordered(ip) != old_resolved_ies;2326 func.resolvedErrorSetUnordered(ip) != old_resolved_ies;
...@@ -1828,103 +2330,24 @@ fn analyzeFuncBody(...@@ -1828,103 +2330,24 @@ fn analyzeFuncBody(
1828 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;2330 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;
1829 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);2331 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) {2333 if (comp.bin_file != null or zcu.llvm_object != null or dump_air or dump_llvm_ir) {
1832 air.deinit(gpa);2334 zcu.codegen_prog_node.increaseEstimatedTotalItems(1);
1833 return .{ .ies_outdated = ies_outdated };2335 comp.link_prog_node.increaseEstimatedTotalItems(1);
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;
18862336
1887 const tracked_inst = try ip.trackZir(gpa, io, pt.tid, .{2337 // Some linkers need to refer to the AIR. In that case, the linker is not running
1888 .file = file_index,2338 // concurrently, so we'll just keep ownership of the AIR for ourselves instead of
1889 .inst = .main_struct_inst,2339 // letting the codegen job destroy it.
1890 });2340 const disown_air = zcu.backendSupportsFeature(.separate_thread);
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);
19092341
1910 wip_ty.setName(ip, try file.internFullyQualifiedName(pt), .none);2342 // Begin the codegen task. If the codegen/link queue is backed up, this might
1911 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;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) {2347 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .link_func = codegen_task });
1914 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
1915 }2348 }
19162349
1917 try pt.scanNamespace(namespace_index, decls);2350 return .{ .ies_outdated = ies_outdated };
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);
1928}2351}
19292352
1930/// Re-scan the namespace of a file's root struct type on an incremental update.2353/// 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....@@ -1945,48 +2368,11 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.
1945 });2368 });
19462369
1947 const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu);2370 const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu);
1948 const decls = decls: {2371 const decls = file.zir.?.getStructDecl(.main_struct_inst).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 };
1961 try pt.scanNamespace(namespace_index, decls);2372 try pt.scanNamespace(namespace_index, decls);
1962 zcu.namespacePtr(namespace_index).generation = zcu.generation;2373 zcu.namespacePtr(namespace_index).generation = zcu.generation;
1963}2374}
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
1990/// Called by AstGen worker threads when an import is seen. If `new_file` is returned, the caller is2376/// Called by AstGen worker threads when an import is seen. If `new_file` is returned, the caller is
1991/// then responsible for queueing a new AstGen job for the new file.2377/// then responsible for queueing a new AstGen job for the new file.
1992/// Assumes that `comp.mutex` is NOT locked. It will be locked by this function where necessary.2378/// 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{...@@ -2214,7 +2600,7 @@ pub fn populateModuleRootTable(pt: Zcu.PerThread) error{
2214/// modify `pt.zcu.skip_analysis_this_update`.2600/// modify `pt.zcu.skip_analysis_this_update`.
2215///2601///
2216/// If an error is returned, `pt.zcu.alive_files` might contain undefined values.2602/// 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 {
2218 const zcu = pt.zcu;2604 const zcu = pt.zcu;
2219 const comp = zcu.comp;2605 const comp = zcu.comp;
2220 const gpa = zcu.gpa;2606 const gpa = zcu.gpa;
...@@ -2655,8 +3041,8 @@ pub fn scanNamespace(...@@ -2655,8 +3041,8 @@ pub fn scanNamespace(
2655 namespace_index: Zcu.Namespace.Index,3041 namespace_index: Zcu.Namespace.Index,
2656 decls: []const Zir.Inst.Index,3042 decls: []const Zir.Inst.Index,
2657) Allocator.Error!void {3043) Allocator.Error!void {
2658 const tracy = trace(@src());3044 const tracy_trace = trace(@src());
2659 defer tracy.end();3045 defer tracy_trace.end();
26603046
2661 const zcu = pt.zcu;3047 const zcu = pt.zcu;
2662 const ip = &zcu.intern_pool;3048 const ip = &zcu.intern_pool;
...@@ -2752,8 +3138,8 @@ const ScanDeclIter = struct {...@@ -2752,8 +3138,8 @@ const ScanDeclIter = struct {
2752 }3138 }
27533139
2754 fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {3140 fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {
2755 const tracy = trace(@src());3141 const tracy_trace = trace(@src());
2756 defer tracy.end();3142 defer tracy_trace.end();
27573143
2758 const pt = iter.pt;3144 const pt = iter.pt;
2759 const zcu = pt.zcu;3145 const zcu = pt.zcu;
...@@ -2806,89 +3192,76 @@ const ScanDeclIter = struct {...@@ -2806,89 +3192,76 @@ const ScanDeclIter = struct {
28063192
2807 const existing_unit = iter.existing_by_inst.get(tracked_inst);3193 const existing_unit = iter.existing_by_inst.get(tracked_inst);
28083194
2809 const unit, const want_analysis = switch (decl.kind) {3195 const name = maybe_name.unwrap() orelse {
2810 .@"comptime" => unit: {3196 // Only `comptime` declarations are unnamed.
2811 const cu = if (existing_unit) |eu|3197 assert(decl.kind == .@"comptime");
2812 eu.unwrap().@"comptime"3198 if (existing_unit) |unit| {
2813 else3199 try namespace.comptime_decls.append(gpa, unit.unwrap().@"comptime");
2814 try ip.createComptimeUnit(gpa, io, pt.tid, tracked_inst, namespace_index);3200 } else {
28153201 const cu = try ip.createComptimeUnit(gpa, io, pt.tid, tracked_inst, namespace_index);
2816 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });3202 try zcu.queueComptimeUnitAnalysis(cu);
2817
2818 try namespace.comptime_decls.append(gpa, cu);3203 try namespace.comptime_decls.append(gpa, cu);
3204 }
3205 return;
3206 };
28193207
2820 if (existing_unit == null) {3208 const fqn = try namespace.internFullyQualifiedName(ip, gpa, io, pt.tid, name);
2821 // For a `comptime` declaration, whether to analyze is based solely on whether the unit3209
2822 // is outdated. So, add this fresh one to `outdated` and `outdated_ready`.3210 const nav = if (existing_unit) |unit| nav: {
2823 try zcu.outdated.ensureUnusedCapacity(gpa, 1);3211 const nav = unit.unwrap().nav_val;
2824 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);3212 assert(ip.getNav(nav).name == name);
2825 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);3213 assert(ip.getNav(nav).fqn == fqn);
2826 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});3214 break :nav nav;
2827 }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;
2830 },3241 },
2831 else => unit: {3242 .@"const", .@"var" => a: {
2832 const name = maybe_name.unwrap().?;3243 if (decl.is_pub) {
2833 const fqn = try namespace.internFullyQualifiedName(ip, gpa, io, pt.tid, name);3244 try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
2834 const nav = if (existing_unit) |eu| eu.unwrap().nav_val else nav: {3245 } else {
2835 const nav = try ip.createDeclNav(gpa, io, pt.tid, name, fqn, tracked_inst, namespace_index);3246 try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
2836 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);3247 }
2837 break :nav nav;3248 break :a false;
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 };
2876 },3249 },
2877 };3250 };
28783251
2879 if (existing_unit == null and (want_analysis or decl.linkage == .@"export")) {3252 if (want_analysis or decl.linkage == .@"export") {
2880 log.debug(3253 try zcu.ensureNavValAnalysisQueued(nav);
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 });
2885 }3254 }
2886 }3255 }
2887};3256};
28883257
2889fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!Air {3258fn analyzeFuncBodyInner(
2890 const tracy = trace(@src());3259 pt: Zcu.PerThread,
2891 defer tracy.end();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
2893 const zcu = pt.zcu;3266 const zcu = pt.zcu;
2894 const comp = zcu.comp;3267 const comp = zcu.comp;
...@@ -2898,17 +3271,18 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2898,17 +3271,18 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
28983271
2899 const anal_unit = AnalUnit.wrap(.{ .func = func_index });3272 const anal_unit = AnalUnit.wrap(.{ .func = func_index });
2900 const func = zcu.funcInfo(func_index);3273 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, {});3275 // This is the `Nav` corresponding to the `declaration` instruction which the function or its generic owner originates from.
2906 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);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);3281 const file = zcu.fileByIndex(decl_analysis.zir_index.resolveFile(ip));
2909 if (func.analysisUnordered(ip).inferred_error_set) {3282 const zir = file.zir.?;
2910 func.setResolvedErrorSet(ip, io, .none);3283
2911 }3284 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason);
3285 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
29123286
2913 if (zcu.comp.time_report) |*tr| {3287 if (zcu.comp.time_report) |*tr| {
2914 if (func.generic_owner != .none) {3288 if (func.generic_owner != .none) {
...@@ -2916,16 +3290,8 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2916,16 +3290,8 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2916 }3290 }
2917 }3291 }
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
2925 const func_nav = ip.getNav(func.owner_nav);3293 const func_nav = ip.getNav(func.owner_nav);
29263294
2927 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
2928
2929 var analysis_arena = std.heap.ArenaAllocator.init(gpa);3295 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
2930 defer analysis_arena.deinit();3296 defer analysis_arena.deinit();
29313297
...@@ -2957,9 +3323,30 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2957,9 +3323,30 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
29573323
2958 // Every runtime function has a dependency on the source of the Decl it originates from.3324 // Every runtime function has a dependency on the source of the Decl it originates from.
2959 // It also depends on the value of its owner Decl.3325 // 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 });
2961 try sema.declareDependency(.{ .nav_val = func.owner_nav });3327 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
2963 if (func.analysisUnordered(ip).inferred_error_set) {3350 if (func.analysisUnordered(ip).inferred_error_set) {
2964 const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet);3351 const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet);
2965 ies.* = .{ .func = func_index };3352 ies.* = .{ .func = func_index };
...@@ -2977,11 +3364,11 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2977,11 +3364,11 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2977 var inner_block: Sema.Block = .{3364 var inner_block: Sema.Block = .{
2978 .parent = null,3365 .parent = null,
2979 .sema = &sema,3366 .sema = &sema,
2980 .namespace = decl_nav.analysis.?.namespace,3367 .namespace = decl_analysis.namespace,
2981 .instructions = .{},3368 .instructions = .empty,
2982 .inlining = null,3369 .inlining = null,
2983 .comptime_reason = null,3370 .comptime_reason = null,
2984 .src_base_inst = decl_nav.analysis.?.zir_index,3371 .src_base_inst = decl_analysis.zir_index,
2985 .type_name_ctx = func_nav.fqn,3372 .type_name_ctx = func_nav.fqn,
2986 };3373 };
2987 defer inner_block.instructions.deinit(gpa);3374 defer inner_block.instructions.deinit(gpa);
...@@ -3020,16 +3407,21 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -3020,16 +3407,21 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
3020 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);3407 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
3021 if (gop.found_existing) continue; // provided above by comptime arg3408 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]);
3024 runtime_param_index += 1;3411 runtime_param_index += 1;
30253412
3026 const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) {3413 if (param_ty.isGenericPoison()) {
3027 error.ComptimeReturn => unreachable,3414 // We're guaranteed to get a compile error on the `fnHasRuntimeBits` check after this
3028 error.ComptimeBreak => unreachable,3415 // loop (the generic poison means this is a generic function). But `continue` here to
3029 else => |e| return e,3416 // avoid an illegal call to `onePossibleValue` below.
3030 };3417 continue;
3031 if (opt_opv) |opv| {3418 }
3032 gop.value_ptr.* = Air.internedToRef(opv.toIntern());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);
3033 continue;3425 continue;
3034 }3426 }
3035 const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);3427 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...@@ -3038,12 +3430,31 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
3038 sema.air_instructions.appendAssumeCapacity(.{3430 sema.air_instructions.appendAssumeCapacity(.{
3039 .tag = .arg,3431 .tag = .arg,
3040 .data = .{ .arg = .{3432 .data = .{ .arg = .{
3041 .ty = Air.internedToRef(param_ty),3433 .ty = .fromIntern(param_ty.toIntern()),
3042 .zir_param_index = @intCast(zir_param_index),3434 .zir_param_index = @intCast(zir_param_index),
3043 } },3435 } },
3044 });3436 });
3045 }3437 }
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
3047 const last_arg_index = inner_block.instructions.items.len;3458 const last_arg_index = inner_block.instructions.items.len;
30483459
3049 // Save the error trace as our first action in the function.3460 // 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...@@ -3103,21 +3514,6 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
3103 func.setResolvedErrorSet(ip, io, ies.resolved);3514 func.setResolvedErrorSet(ip, io, ies.resolved);
3104 }3515 }
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
3121 try sema.flushExports();3517 try sema.flushExports();
31223518
3123 defer {3519 defer {
...@@ -3244,7 +3640,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -3244,7 +3640,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {
3244 break :gop .{ gop.value_ptr, gop.found_existing };3640 break :gop .{ gop.value_ptr, gop.found_existing };
3245 },3641 },
3246 };3642 };
3247 if (!found_existing) value_ptr.* = .{};3643 if (!found_existing) value_ptr.* = .empty;
3248 try value_ptr.append(gpa, export_idx);3644 try value_ptr.append(gpa, export_idx);
3249 }3645 }
32503646
...@@ -3273,7 +3669,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -3273,7 +3669,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {
3273 break :gop .{ gop.value_ptr, gop.found_existing };3669 break :gop .{ gop.value_ptr, gop.found_existing };
3274 },3670 },
3275 };3671 };
3276 if (!found_existing) value_ptr.* = .{};3672 if (!found_existing) value_ptr.* = .empty;
3277 try value_ptr.append(gpa, @enumFromInt(export_idx));3673 try value_ptr.append(gpa, @enumFromInt(export_idx));
3278 }3674 }
3279 }3675 }
...@@ -3545,36 +3941,45 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool...@@ -3545,36 +3941,45 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool
35453941
3546/// Essentially a shortcut for calling `intern_pool.getCoerced`.3942/// Essentially a shortcut for calling `intern_pool.getCoerced`.
3547/// However, this function also allows coercing `extern`s. The `InternPool` function can't do3943/// 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.
3549pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {3945pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {
3550 const ip = &pt.zcu.intern_pool;3946 const ip = &pt.zcu.intern_pool;
3551 const comp = pt.zcu.comp;3947 const comp = pt.zcu.comp;
3552 const gpa = comp.gpa;3948 const gpa = comp.gpa;
3553 const io = comp.io;3949 const io = comp.io;
3554 switch (ip.indexToKey(val.toIntern())) {3950 switch (ip.indexToKey(val.toIntern())) {
3555 .@"extern" => |e| {3951 .@"extern" => |@"extern"| {
3556 const coerced = try pt.getExtern(.{3952 // TODO: it's awkward to make this function cancelable. The problem is really that
3557 .name = e.name,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,
3558 .ty = new_ty.toIntern(),3960 .ty = new_ty.toIntern(),
3559 .lib_name = e.lib_name,3961 .lib_name = @"extern".lib_name,
3560 .is_const = e.is_const,3962 .is_const = @"extern".is_const,
3561 .is_threadlocal = e.is_threadlocal,3963 .is_threadlocal = @"extern".is_threadlocal,
3562 .linkage = e.linkage,3964 .linkage = @"extern".linkage,
3563 .visibility = e.visibility,3965 .visibility = @"extern".visibility,
3564 .is_dll_import = e.is_dll_import,3966 .is_dll_import = @"extern".is_dll_import,
3565 .relocation = e.relocation,3967 .relocation = @"extern".relocation,
3566 .decoration = e.decoration,3968 .decoration = @"extern".decoration,
3567 .alignment = e.alignment,3969 .alignment = @"extern".alignment,
3568 .@"addrspace" = e.@"addrspace",3970 .@"addrspace" = @"extern".@"addrspace",
3569 .zir_index = e.zir_index,3971 .zir_index = @"extern".zir_index,
3570 .owner_nav = undefined, // ignored by `getExtern`.3972 .owner_nav = undefined, // ignored by `getExtern`.
3571 .source = e.source,3973 .source = @"extern".source,
3572 });3974 }) catch |err| switch (err) {
3573 return Value.fromInterned(coerced);3975 error.Canceled => unreachable, // blocked above
3976 error.OutOfMemory => |e| return e,
3977 };
3978 return .fromInterned(coerced);
3574 },3979 },
3575 else => {},3980 else => {},
3576 }3981 }
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()));
3578}3983}
35793984
3580pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {3985pub 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!...@@ -3605,16 +4010,6 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!
36054010
3606 if (info.flags.size == .c) canon_info.flags.is_allowzero = true;4011 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
3618 switch (info.flags.vector_index) {4013 switch (info.flags.vector_index) {
3619 // Canonicalize host_size. If it matches the bit size of the pointee type,4014 // Canonicalize host_size. If it matches the bit size of the pointee type,
3620 // we change it to 0 here. If this causes an assertion trip, the pointee type4015 // 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!...@@ -3632,16 +4027,6 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!
3632 return Type.fromInterned(try pt.intern(.{ .ptr_type = canon_info }));4027 return Type.fromInterned(try pt.intern(.{ .ptr_type = canon_info }));
3633}4028}
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
3645pub fn singleMutPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {4030pub fn singleMutPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
3646 return pt.ptrType(.{ .child = child_type.toIntern() });4031 return pt.ptrType(.{ .child = child_type.toIntern() });
3647}4032}
...@@ -3741,29 +4126,54 @@ pub fn enumValueFieldIndex(pt: Zcu.PerThread, ty: Type, field_index: u32) Alloca...@@ -3741,29 +4126,54 @@ pub fn enumValueFieldIndex(pt: Zcu.PerThread, ty: Type, field_index: u32) Alloca
3741 const ip = &pt.zcu.intern_pool;4126 const ip = &pt.zcu.intern_pool;
3742 const enum_type = ip.loadEnumType(ty.toIntern());4127 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) {
3745 // Auto-numbered fields.4132 // Auto-numbered fields.
3746 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{4133 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
3747 .ty = ty.toIntern(),4134 .ty = ty.toIntern(),
3748 .int = try pt.intern(.{ .int = .{4135 .int = try pt.intern(.{ .int = .{
3749 .ty = enum_type.tag_ty,4136 .ty = enum_type.int_tag_type,
3750 .storage = .{ .u64 = field_index },4137 .storage = .{ .u64 = field_index },
3751 } }),4138 } }),
3752 } }));4139 } }));
3753 }4140 }
37544141
3755 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{4142 return .fromInterned(try pt.intern(.{ .enum_tag = .{
3756 .ty = ty.toIntern(),4143 .ty = ty.toIntern(),
3757 .int = enum_type.values.get(ip)[field_index],4144 .int = enum_type.field_values.get(ip)[field_index],
3758 } }));4145 } }));
3759}4146}
37604147
3761pub fn undefValue(pt: Zcu.PerThread, ty: Type) Allocator.Error!Value {4148pub 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() }));
3763}4173}
37644174
3765pub fn undefRef(pt: Zcu.PerThread, ty: Type) Allocator.Error!Air.Inst.Ref {4175pub 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));
3767}4177}
37684178
3769pub fn intValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value {4179pub 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...@@ -3839,7 +4249,7 @@ pub fn aggregateValue(pt: Zcu.PerThread, ty: Type, elems: []const InternPool.Ind
3839 for (elems) |elem| {4249 for (elems) |elem| {
3840 if (!Value.fromInterned(elem).isUndef(pt.zcu)) break;4250 if (!Value.fromInterned(elem).isUndef(pt.zcu)) break;
3841 } else if (elems.len > 0) {4251 } else if (elems.len > 0) {
3842 return pt.undefValue(ty); // all-undef4252 return pt.undefValue(ty);
3843 }4253 }
3844 return .fromInterned(try pt.intern(.{ .aggregate = .{4254 return .fromInterned(try pt.intern(.{ .aggregate = .{
3845 .ty = ty.toIntern(),4255 .ty = ty.toIntern(),
...@@ -3877,6 +4287,15 @@ pub fn floatValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value...@@ -3877,6 +4287,15 @@ pub fn floatValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value
3877 } }));4287 } }));
3878}4288}
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
3880pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value {4299pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value {
3881 assert(pt.zcu.intern_pool.isOptionalType(opt_ty.toIntern()));4300 assert(pt.zcu.intern_pool.isOptionalType(opt_ty.toIntern()));
3882 return Value.fromInterned(try pt.intern(.{ .opt = .{4301 return Value.fromInterned(try pt.intern(.{ .opt = .{
...@@ -3916,7 +4335,7 @@ pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type {...@@ -3916,7 +4335,7 @@ pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type {
3916 assert(Value.order(min, max, zcu).compare(.lte));4335 assert(Value.order(min, max, zcu).compare(.lte));
3917 }4336 }
39184337
3919 const sign = min.orderAgainstZero(zcu) == .lt;4338 const sign = min.compareHetero(.lt, .zero_comptime_int, zcu);
39204339
3921 const min_val_bits = pt.intBitsForValue(min, sign);4340 const min_val_bits = pt.intBitsForValue(min, sign);
3922 const max_val_bits = pt.intBitsForValue(max, sign);4341 const max_val_bits = pt.intBitsForValue(max, sign);
...@@ -3955,12 +4374,6 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {...@@ -3955,12 +4374,6 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {
39554374
3956 return @as(u16, @intCast(big.bitCountTwosComp()));4375 return @as(u16, @intCast(big.bitCountTwosComp()));
3957 },4376 },
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 },
3964 }4377 }
3965}4378}
39664379
...@@ -3975,10 +4388,7 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Err...@@ -3975,10 +4388,7 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Err
3975 return pt.ptrType(.{4388 return pt.ptrType(.{
3976 .child = ty,4389 .child = ty,
3977 .flags = .{4390 .flags = .{
3978 .alignment = if (alignment == Type.fromInterned(ty).abiAlignment(zcu))4391 .alignment = alignment,
3979 .none
3980 else
3981 alignment,
3982 .address_space = @"addrspace",4392 .address_space = @"addrspace",
3983 .is_const = is_const,4393 .is_const = is_const,
3984 },4394 },
...@@ -3988,392 +4398,19 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Err...@@ -3988,392 +4398,19 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Err
3988/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.4398/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
3989/// If necessary, the new `Nav` is queued for codegen.4399/// If necessary, the new `Nav` is queued for codegen.
3990/// `key.owner_nav` is ignored and may be `undefined`.4400/// `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 {
3992 const zcu = pt.zcu;4402 const zcu = pt.zcu;
3993 const comp = zcu.comp;4403 const comp = zcu.comp;
4404 Type.fromInterned(key.ty).assertHasLayout(zcu);
3994 const result = try zcu.intern_pool.getExtern(comp.gpa, comp.io, pt.tid, key);4405 const result = try zcu.intern_pool.getExtern(comp.gpa, comp.io, pt.tid, key);
3995 if (result.new_nav.unwrap()) |nav| {4406 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 });
3999 if (comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);4407 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 });
4000 }4410 }
4001 return result.index;4411 return result.index;
4002}4412}
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
4377/// Given a namespace, re-scan its declarations from the type definition if they have not4414/// Given a namespace, re-scan its declarations from the type definition if they have not
4378/// yet been re-scanned on this update.4415/// yet been re-scanned on this update.
4379/// If the type declaration instruction has been lost, returns `error.AnalysisFail`.4416/// 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...@@ -4396,7 +4433,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
4396 };4433 };
43974434
4398 const key = switch (full_key) {4435 const key = switch (full_key) {
4399 .reified, .generated_tag => {4436 .reified, .generated_union_tag => {
4400 // Namespace always empty, so up-to-date.4437 // Namespace always empty, so up-to-date.
4401 namespace.generation = zcu.generation;4438 namespace.generation = zcu.generation;
4402 return;4439 return;
...@@ -4408,123 +4445,37 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace...@@ -4408,123 +4445,37 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
44084445
4409 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;4446 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
4410 const file = zcu.fileByIndex(inst_info.file);4447 const file = zcu.fileByIndex(inst_info.file);
4411 const zir = file.zir.?;4448 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;
44154449
4416 const decls = switch (container) {4450 const decls = switch (container) {
4417 .@"struct" => decls: {4451 .@"struct" => zir.getStructDecl(inst_info.inst).decls,
4418 assert(extended.opcode == .struct_decl);4452 .@"union" => zir.getUnionDecl(inst_info.inst).decls,
4419 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);4453 .@"enum" => zir.getEnumDecl(inst_info.inst).decls,
4420 const extra = zir.extraData(Zir.Inst.StructDecl, extended.operand);4454 .@"opaque" => zir.getOpaqueDecl(inst_info.inst).decls,
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 },
4505 };4455 };
45064456
4507 try pt.scanNamespace(namespace_index, decls);4457 try pt.scanNamespace(namespace_index, decls);
4508 namespace.generation = zcu.generation;4458 namespace.generation = zcu.generation;
4509}4459}
45104460
4511pub fn refValue(pt: Zcu.PerThread, val: InternPool.Index) Zcu.SemaError!InternPool.Index {4461pub fn uavValue(pt: Zcu.PerThread, val: Value) Zcu.SemaError!Value {
4512 const ptr_ty = (try pt.ptrTypeSema(.{4462 const zcu = pt.zcu;
4513 .child = pt.zcu.intern_pool.typeOf(val),4463 const ptr_ty = try pt.ptrType(.{
4464 .child = val.typeOf(zcu).toIntern(),
4514 .flags = .{4465 .flags = .{
4515 .alignment = .none,4466 .alignment = .none,
4516 .is_const = true,4467 .is_const = true,
4517 .address_space = .generic,4468 .address_space = .generic,
4518 },4469 },
4519 })).toIntern();4470 });
4520 return pt.intern(.{ .ptr = .{4471 return .fromInterned(try pt.intern(.{ .ptr = .{
4521 .ty = ptr_ty,4472 .ty = ptr_ty.toIntern(),
4522 .base_addr = .{ .uav = .{4473 .base_addr = .{ .uav = .{
4523 .val = val,4474 .val = val.toIntern(),
4524 .orig_ty = ptr_ty,4475 .orig_ty = ptr_ty.toIntern(),
4525 } },4476 } },
4526 .byte_offset = 0,4477 .byte_offset = 0,
4527 } });4478 } }));
4528}4479}
45294480
4530pub fn addDependency(pt: Zcu.PerThread, unit: AnalUnit, dependee: InternPool.Dependee) Allocator.Error!void {4481pub 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(...@@ -343,11 +343,9 @@ pub fn generateSymbol(
343343
344 .undef => unreachable, // handled above344 .undef => unreachable, // handled above
345 .simple_value => |simple_value| switch (simple_value) {345 .simple_value => |simple_value| switch (simple_value) {
346 .undefined => unreachable, // non-runtime value
347 .void => unreachable, // non-runtime value346 .void => unreachable, // non-runtime value
348 .null => unreachable, // non-runtime value347 .null => unreachable, // non-runtime value
349 .@"unreachable" => unreachable, // non-runtime value348 .@"unreachable" => unreachable, // non-runtime value
350 .empty_tuple => return,
351 .false, .true => try w.writeByte(switch (simple_value) {349 .false, .true => try w.writeByte(switch (simple_value) {
352 .false => 0,350 .false => 0,
353 .true => 1,351 .true => 1,
...@@ -358,7 +356,6 @@ pub fn generateSymbol(...@@ -358,7 +356,6 @@ pub fn generateSymbol(
358 .@"extern",356 .@"extern",
359 .func,357 .func,
360 .enum_literal,358 .enum_literal,
361 .empty_enum_value,
362 => unreachable, // non-runtime values359 => unreachable, // non-runtime values
363 .int => {360 .int => {
364 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;361 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
...@@ -377,7 +374,7 @@ pub fn generateSymbol(...@@ -377,7 +374,7 @@ pub fn generateSymbol(
377 .payload => 0,374 .payload => 0,
378 };375 };
379376
380 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {377 if (!payload_ty.hasRuntimeBits(zcu)) {
381 try w.writeInt(u16, err_val, endian);378 try w.writeInt(u16, err_val, endian);
382 return;379 return;
383 }380 }
...@@ -571,46 +568,11 @@ pub fn generateSymbol(...@@ -571,46 +568,11 @@ pub fn generateSymbol(
571 .struct_type => {568 .struct_type => {
572 const struct_type = ip.loadStructType(ty.toIntern());569 const struct_type = ip.loadStructType(ty.toIntern());
573 switch (struct_type.layout) {570 switch (struct_type.layout) {
574 .@"packed" => {571 .@"packed" => unreachable,
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 },
610 .auto, .@"extern" => {572 .auto, .@"extern" => {
611 const struct_begin = w.end;573 const struct_begin = w.end;
612 const field_types = struct_type.field_types.get(ip);574 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
615 var it = struct_type.iterateRuntimeOrder(ip);577 var it = struct_type.iterateRuntimeOrder(ip);
616 while (it.next()) |field_index| {578 while (it.next()) |field_index| {
...@@ -635,13 +597,11 @@ pub fn generateSymbol(...@@ -635,13 +597,11 @@ pub fn generateSymbol(
635 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);597 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
636 }598 }
637599
638 const size = struct_type.sizeUnordered(ip);600 assert(struct_type.alignment.check(struct_type.size));
639 const alignment = struct_type.flagsUnordered(ip).alignment.toByteUnits().?;
640601
641 const padding = math.cast(602 const padding = math.cast(usize, struct_type.size - (w.end - struct_begin)) orelse {
642 usize,603 return error.Overflow;
643 std.mem.alignForward(u64, size, @max(alignment, 1)) - (w.end - struct_begin),604 };
644 ) orelse return error.Overflow;
645 if (padding > 0) try w.splatByteAll(0, padding);605 if (padding > 0) try w.splatByteAll(0, padding);
646 },606 },
647 }607 }
...@@ -686,6 +646,7 @@ pub fn generateSymbol(...@@ -686,6 +646,7 @@ pub fn generateSymbol(
686 }646 }
687 }647 }
688 },648 },
649 .bitpack => |bitpack| try generateSymbol(bin_file, pt, src_loc, .fromInterned(bitpack.backing_int_val), w, reloc_parent),
689 .memoized_call => unreachable,650 .memoized_call => unreachable,
690 }651 }
691}652}
...@@ -739,7 +700,14 @@ fn lowerPtr(...@@ -739,7 +700,14 @@ fn lowerPtr(
739 };700 };
740 return lowerPtr(bin_file, pt, src_loc, field.base, w, reloc_parent, offset + field_off);701 return lowerPtr(bin_file, pt, src_loc, field.base, w, reloc_parent, offset + field_off);
741 },702 },
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,
743 };711 };
744}712}
745713
...@@ -820,9 +788,8 @@ fn lowerNavRef(...@@ -820,9 +788,8 @@ fn lowerNavRef(
820 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);788 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
821 const is_obj = lf.comp.config.output_mode == .Obj;789 const is_obj = lf.comp.config.output_mode == .Obj;
822 const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));790 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) {
826 try w.splatByteAll(0xaa, ptr_width_bytes);793 try w.splatByteAll(0xaa, ptr_width_bytes);
827 return;794 return;
828 }795 }
...@@ -834,7 +801,7 @@ fn lowerNavRef(...@@ -834,7 +801,7 @@ fn lowerNavRef(
834 dev.check(link.File.Tag.wasm.devFeature());801 dev.check(link.File.Tag.wasm.devFeature());
835 const wasm = lf.cast(.wasm).?;802 const wasm = lf.cast(.wasm).?;
836 assert(reloc_parent == .none);803 assert(reloc_parent == .none);
837 if (is_fn_body) {804 if (nav_ty.zigTypeTag(zcu) == .@"fn") {
838 const gop = try wasm.zcu_indirect_function_set.getOrPut(gpa, nav_index);805 const gop = try wasm.zcu_indirect_function_set.getOrPut(gpa, nav_index);
839 if (!gop.found_existing) gop.value_ptr.* = {};806 if (!gop.found_existing) gop.value_ptr.* = {};
840 if (is_obj) {807 if (is_obj) {
...@@ -1060,51 +1027,41 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo...@@ -1060,51 +1027,41 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
10601027
1061 switch (ty.zigTypeTag(zcu)) {1028 switch (ty.zigTypeTag(zcu)) {
1062 .void => return .none,1029 .void => return .none,
1030 .bool => return .{ .immediate = @intFromBool(val.toBool()) },
1063 .pointer => switch (ty.ptrSize(zcu)) {1031 .pointer => switch (ty.ptrSize(zcu)) {
1064 .slice => {},1032 .slice => {},
1065 else => switch (val.toIntern()) {1033 .one, .many, .c => {
1066 .null_value => {1034 const ptr = ip.indexToKey(val.toIntern()).ptr;
1067 return .{ .immediate = 0 };1035 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1068 },1036 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1069 else => switch (ip.indexToKey(val.toIntern())) {1037 .int => unreachable, // handled above
1070 .int => {1038
1071 return .{ .immediate = val.toUnsignedInt(zcu) };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 }
1072 },1051 },
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| {1053 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1087 if (zcu.typeToFunc(fn_ty).?.is_generic) {1054 return .{ .lea_uav = uav };
1088 return .{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? };1055 } else {
1089 }1056 // Create the 0xaa bit pattern...
1090 } else if (ty.zigTypeTag(zcu) == .pointer) {1057 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1091 const elem_ty = ty.elemType2(zcu);1058 // ...but align the pointer
1092 if (!elem_ty.hasRuntimeBits(zcu)) {1059 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
1093 return .{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? };1060 return .{ .immediate = alignment.forward(undef_ptr_bits) };
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 => {},
1105 },1061 },
1062
1106 else => {},1063 else => {},
1107 },1064 };
1108 },1065 },
1109 },1066 },
1110 .int => {1067 .int => {
...@@ -1117,9 +1074,6 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo...@@ -1117,9 +1074,6 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
1117 return .{ .immediate = unsigned };1074 return .{ .immediate = unsigned };
1118 }1075 }
1119 },1076 },
1120 .bool => {
1121 return .{ .immediate = @intFromBool(val.toBool()) };
1122 },
1123 .optional => {1077 .optional => {
1124 if (ty.isPtrLikeOptional(zcu)) {1078 if (ty.isPtrLikeOptional(zcu)) {
1125 return lowerValue(1079 return lowerValue(
...@@ -1139,6 +1093,10 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo...@@ -1139,6 +1093,10 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
1139 target,1093 target,
1140 );1094 );
1141 },1095 },
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 },
1142 .error_set => {1100 .error_set => {
1143 const err_name = ip.indexToKey(val.toIntern()).err.name;1101 const err_name = ip.indexToKey(val.toIntern()).err.name;
1144 const error_index = ip.getErrorValueIfExists(err_name).?;1102 const error_index = ip.getErrorValueIfExists(err_name).?;
...@@ -1147,7 +1105,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo...@@ -1147,7 +1105,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
1147 .error_union => {1105 .error_union => {
1148 const err_type = ty.errorUnionSet(zcu);1106 const err_type = ty.errorUnionSet(zcu);
1149 const payload_type = ty.errorUnionPayload(zcu);1107 const payload_type = ty.errorUnionPayload(zcu);
1150 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {1108 if (!payload_type.hasRuntimeBits(zcu)) {
1151 // We use the error type directly as the type.1109 // We use the error type directly as the type.
1152 const err_int_ty = try pt.errorIntType();1110 const err_int_ty = try pt.errorIntType();
1153 switch (ip.indexToKey(val.toIntern()).error_union.val) {1111 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...@@ -1187,10 +1145,10 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
1187}1145}
11881146
1189pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {1147pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
1190 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;1148 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
1191 const payload_align = payload_ty.abiAlignment(zcu);1149 const payload_align = payload_ty.abiAlignment(zcu);
1192 const error_align = Type.anyerror.abiAlignment(zcu);1150 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)) {
1194 return 0;1152 return 0;
1195 } else {1153 } else {
1196 return payload_align.forward(Type.anyerror.abiSize(zcu));1154 return payload_align.forward(Type.anyerror.abiSize(zcu));
...@@ -1198,10 +1156,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {...@@ -1198,10 +1156,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
1198}1156}
11991157
1200pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {1158pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
1201 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;1159 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
1202 const payload_align = payload_ty.abiAlignment(zcu);1160 const payload_align = payload_ty.abiAlignment(zcu);
1203 const error_align = Type.anyerror.abiAlignment(zcu);1161 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)) {
1205 return error_align.forward(payload_ty.abiSize(zcu));1163 return error_align.forward(payload_ty.abiSize(zcu));
1206 } else {1164 } else {
1207 return 0;1165 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,...@@ -2464,7 +2464,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
24642464
2465 const ty_pl = air.data(air.inst_index).ty_pl;2465 const ty_pl = air.data(air.inst_index).ty_pl;
2466 const bin_op = isel.air.extraData(Air.Bin, ty_pl.payload).data;2466 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
2469 const base_vi = try isel.use(bin_op.lhs);2469 const base_vi = try isel.use(bin_op.lhs);
2470 var base_part_it = base_vi.field(ty_pl.ty.toType(), 0, 8);2470 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,...@@ -2791,17 +2791,17 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2791 } else return isel.fail("invalid constraint: '{s}'", .{constraint});2791 } else return isel.fail("invalid constraint: '{s}'", .{constraint});
2792 }2792 }
27932793
2794 const clobbers = ip.indexToKey(unwrapped_asm.clobbers).aggregate;2794 const clobbers_val: Constant = .fromInterned(unwrapped_asm.clobbers);
2795 const clobbers_ty: ZigType = .fromInterned(clobbers.ty);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);
2796 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {2798 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
2797 switch (switch (clobbers.storage) {2799 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
2798 .bytes => unreachable,2800 const limb_bits = @bitSizeOf(std.math.big.Limb);
2799 .elems => |elems| elems[field_index],2801 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
2800 .repeated_elem => |repeated_elem| repeated_elem,2802 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
2801 }) {2803 0 => continue, // field is false
2802 else => unreachable,2804 1 => {}, // field is true
2803 .bool_false => continue,
2804 .bool_true => {},
2805 }2805 }
2806 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;2806 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
2807 if (std.mem.eql(u8, clobber_name, "memory")) continue;2807 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,...@@ -2816,14 +2816,11 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2816 }2816 }
2817 }2817 }
2818 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {2818 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
2819 switch (switch (clobbers.storage) {2819 const limb_bits = @bitSizeOf(std.math.big.Limb);
2820 .bytes => unreachable,2820 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
2821 .elems => |elems| elems[field_index],2821 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
2822 .repeated_elem => |repeated_elem| repeated_elem,2822 0 => continue, // field is false
2823 }) {2823 1 => {}, // field is true
2824 else => unreachable,
2825 .bool_false => continue,
2826 .bool_true => {},
2827 }2824 }
2828 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;2825 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
2829 if (std.mem.eql(u8, clobber_name, "memory")) continue;2826 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,...@@ -2872,14 +2869,11 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2872 }2869 }
28732870
2874 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {2871 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
2875 switch (switch (clobbers.storage) {2872 const limb_bits = @bitSizeOf(std.math.big.Limb);
2876 .bytes => unreachable,2873 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
2877 .elems => |elems| elems[field_index],2874 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
2878 .repeated_elem => |repeated_elem| repeated_elem,2875 0 => continue, // field is false
2879 }) {2876 1 => {}, // field is true
2880 else => unreachable,
2881 .bool_false => continue,
2882 .bool_true => {},
2883 }2877 }
2884 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;2878 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
2885 if (std.mem.eql(u8, clobber_name, "memory")) continue;2879 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,...@@ -3289,8 +3283,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3289 } else if (dst_ty.isSliceAtRuntime(zcu) and src_ty.isSliceAtRuntime(zcu)) {3283 } else if (dst_ty.isSliceAtRuntime(zcu) and src_ty.isSliceAtRuntime(zcu)) {
3290 try dst_vi.value.move(isel, ty_op.operand);3284 try dst_vi.value.move(isel, ty_op.operand);
3291 } else if (dst_tag == .error_union and src_tag == .error_union) {3285 } else if (dst_tag == .error_union and src_tag == .error_union) {
3292 assert(dst_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu) ==3286 assert(dst_ty.errorUnionSet(zcu).hasRuntimeBits(zcu) ==
3293 src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));3287 src_ty.errorUnionSet(zcu).hasRuntimeBits(zcu));
3294 if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {3288 if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {
3295 try dst_vi.value.move(isel, ty_op.operand);3289 try dst_vi.value.move(isel, ty_op.operand);
3296 } else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });3290 } 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,...@@ -4568,7 +4562,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4568 }4562 }
4569 if (case.ranges.len == 0 and case.items.len == 1 and Constant.fromInterned(4563 if (case.ranges.len == 0 and case.items.len == 1 and Constant.fromInterned(
4570 case.items[0].toInterned().?,4564 case.items[0].toInterned().?,
4571 ).orderAgainstZero(zcu).compare(.eq)) {4565 ).compareHetero(.eq, .zero_comptime_int, zcu)) {
4572 try isel.emit(.cbnz(4566 try isel.emit(.cbnz(
4573 cond_reg,4567 cond_reg,
4574 @intCast((isel.instructions.items.len + 1 - next_label) << 2),4568 @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,...@@ -6145,7 +6139,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6145 } else {6139 } else {
6146 const elem_ptr_ra = try isel.allocIntReg();6140 const elem_ptr_ra = try isel.allocIntReg();
6147 defer isel.freeReg(elem_ptr_ra);6141 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, .{
6149 .@"volatile" = ptr_info.flags.is_volatile,6143 .@"volatile" = ptr_info.flags.is_volatile,
6150 })) break :unused;6144 })) break :unused;
6151 const slice_vi = try isel.use(bin_op.lhs);6145 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,...@@ -6253,7 +6247,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6253 } else {6247 } else {
6254 const elem_ptr_ra = try isel.allocIntReg();6248 const elem_ptr_ra = try isel.allocIntReg();
6255 defer isel.freeReg(elem_ptr_ra);6249 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, .{
6257 .@"volatile" = ptr_info.flags.is_volatile,6251 .@"volatile" = ptr_info.flags.is_volatile,
6258 })) break :unused;6252 })) break :unused;
6259 const base_vi = try isel.use(bin_op.lhs);6253 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,...@@ -6594,7 +6588,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6594 if (try isel.hasRepeatedByteRepr(.fromInterned(fill_val))) |fill_byte|6588 if (try isel.hasRepeatedByteRepr(.fromInterned(fill_val))) |fill_byte|
6595 break :fill_byte .{ .constant = fill_byte };6589 break :fill_byte .{ .constant = fill_byte };
6596 }6590 }
6597 switch (dst_ty.elemType2(zcu).abiSize(zcu)) {6591 switch (dst_ty.indexableElem(zcu).abiSize(zcu)) {
6598 0 => unreachable,6592 0 => unreachable,
6599 1 => break :fill_byte .{ .value = bin_op.rhs },6593 1 => break :fill_byte .{ .value = bin_op.rhs },
6600 2, 4, 8 => |size| {6594 2, 4, 8 => |size| {
...@@ -6899,11 +6893,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6899,11 +6893,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6899 var field_it = loaded_struct.iterateRuntimeOrder(ip);6893 var field_it = loaded_struct.iterateRuntimeOrder(ip);
6900 while (field_it.next()) |field_index| {6894 while (field_it.next()) |field_index| {
6901 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);6895 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
6902 field_offset = field_ty.structFieldAlignment(6896 field_offset = loaded_struct.field_offsets.get(ip)[field_index];
6903 loaded_struct.fieldAlign(ip, field_index),
6904 loaded_struct.layout,
6905 zcu,
6906 ).forward(field_offset);
6907 const field_size = field_ty.abiSize(zcu);6897 const field_size = field_ty.abiSize(zcu);
6908 if (field_size == 0) continue;6898 if (field_size == 0) continue;
6909 var agg_part_it = agg_vi.value.field(agg_ty, field_offset, field_size);6899 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,...@@ -6911,7 +6901,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6911 try agg_part_vi.?.move(isel, elems[field_index]);6901 try agg_part_vi.?.move(isel, elems[field_index]);
6912 field_offset += field_size;6902 field_offset += field_size;
6913 }6903 }
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));
6915 },6905 },
6916 .tuple_type => |tuple_type| {6906 .tuple_type => |tuple_type| {
6917 const elems: []const Air.Inst.Ref =6907 const elems: []const Air.Inst.Ref =
...@@ -6953,23 +6943,23 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6953,23 +6943,23 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6953 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);6943 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
69546944
6955 if (union_layout.tag_size > 0) unused_tag: {6945 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);
6957 var tag_it = union_vi.value.field(union_ty, union_layout.tagOffset(), union_layout.tag_size);6947 var tag_it = union_vi.value.field(union_ty, union_layout.tagOffset(), union_layout.tag_size);
6958 const tag_vi = try tag_it.only(isel);6948 const tag_vi = try tag_it.only(isel);
6959 const tag_ra = try tag_vi.?.defReg(isel) orelse break :unused_tag;6949 const tag_ra = try tag_vi.?.defReg(isel) orelse break :unused_tag;
6960 switch (union_layout.tag_size) {6950 switch (union_layout.tag_size) {
6961 0 => unreachable,6951 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) {
6963 0 => extra.field_index,6953 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) {
6965 .u64 => |imm| @intCast(imm),6955 .u64 => |imm| @intCast(imm),
6966 .i64 => |imm| @bitCast(@as(i32, @intCast(imm))),6956 .i64 => |imm| @bitCast(@as(i32, @intCast(imm))),
6967 else => unreachable,6957 else => unreachable,
6968 },6958 },
6969 })),6959 })),
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) {
6971 0 => extra.field_index,6961 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) {
6973 .u64 => |imm| imm,6963 .u64 => |imm| imm,
6974 .i64 => |imm| @bitCast(imm),6964 .i64 => |imm| @bitCast(imm),
6975 else => unreachable,6965 else => unreachable,
...@@ -7217,7 +7207,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -7217,7 +7207,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7217 const ptr_ra = try ptr_vi.value.defReg(isel) orelse break :unused;7207 const ptr_ra = try ptr_vi.value.defReg(isel) orelse break :unused;
72187208
7219 const ty_nav = air.data(air.inst_index).ty_nav;7209 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) {
7221 false => {7211 false => {
7222 try isel.nav_relocs.append(gpa, .{7212 try isel.nav_relocs.append(gpa, .{
7223 .nav = ty_nav.nav,7213 .nav = ty_nav.nav,
...@@ -7240,7 +7230,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -7240,7 +7230,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7240 });7230 });
7241 try isel.emit(.adrp(ptr_ra.x(), 0));7231 try isel.emit(.adrp(ptr_ra.x(), 0));
7242 },7232 },
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));
7244 }7234 }
7245 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;7235 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
7246 },7236 },
...@@ -10397,7 +10387,7 @@ pub const Value = struct {...@@ -10397,7 +10387,7 @@ pub const Value = struct {
10397 switch (loaded_struct.layout) {10387 switch (loaded_struct.layout) {
10398 .auto, .@"extern" => {},10388 .auto, .@"extern" => {},
10399 .@"packed" => continue :type_key .{10389 .@"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,
10401 },10391 },
10402 }10392 }
10403 const min_part_log2_stride: u5 = if (size > 16) 4 else if (size > 8) 3 else 0;10393 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 {...@@ -10412,7 +10402,7 @@ pub const Value = struct {
10412 var field_it = loaded_struct.iterateRuntimeOrder(ip);10402 var field_it = loaded_struct.iterateRuntimeOrder(ip);
10413 while (field_it.next()) |field_index| {10403 while (field_it.next()) |field_index| {
10414 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);10404 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)) {
10416 .none => field_ty.abiAlignment(zcu),10406 .none => field_ty.abiAlignment(zcu),
10417 else => |field_align| field_align,10407 else => |field_align| field_align,
10418 }.forward(field_end);10408 }.forward(field_end);
...@@ -10510,7 +10500,7 @@ pub const Value = struct {...@@ -10510,7 +10500,7 @@ pub const Value = struct {
10510 },10500 },
10511 .union_type => {10501 .union_type => {
10512 const loaded_union = ip.loadUnionType(ty.toIntern());10502 const loaded_union = ip.loadUnionType(ty.toIntern());
10513 switch (loaded_union.flagsUnordered(ip).layout) {10503 switch (loaded_union.layout) {
10514 .auto, .@"extern" => {},10504 .auto, .@"extern" => {},
10515 .@"packed" => continue :type_key .{ .int_type = .{10505 .@"packed" => continue :type_key .{ .int_type = .{
10516 .signedness = .unsigned,10506 .signedness = .unsigned,
...@@ -10545,12 +10535,13 @@ pub const Value = struct {...@@ -10545,12 +10535,13 @@ pub const Value = struct {
10545 const field_signedness = field_signedness: switch (field) {10535 const field_signedness = field_signedness: switch (field) {
10546 .tag => {10536 .tag => {
10547 if (offset >= field_begin and offset + size <= field_begin + field_size) {10537 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);
10549 ty_size = field_size;10539 ty_size = field_size;
10550 offset -= field_begin;10540 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);
10552 }10542 }
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;
10554 },10545 },
10555 .payload => null,10546 .payload => null,
10556 };10547 };
...@@ -10580,7 +10571,7 @@ pub const Value = struct {...@@ -10580,7 +10571,7 @@ pub const Value = struct {
10580 }10571 }
10581 },10572 },
10582 .opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque },10573 .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),
10584 .error_set_type,10575 .error_set_type,
10585 .inferred_error_set_type,10576 .inferred_error_set_type,
10586 => continue :type_key .{ .simple_type = .anyerror },10577 => continue :type_key .{ .simple_type = .anyerror },
...@@ -10594,7 +10585,6 @@ pub const Value = struct {...@@ -10594,7 +10585,6 @@ pub const Value = struct {
10594 .error_union,10585 .error_union,
10595 .enum_literal,10586 .enum_literal,
10596 .enum_tag,10587 .enum_tag,
10597 .empty_enum_value,
10598 .float,10588 .float,
10599 .ptr,10589 .ptr,
10600 .slice,10590 .slice,
...@@ -10717,7 +10707,6 @@ pub const Value = struct {...@@ -10717,7 +10707,6 @@ pub const Value = struct {
10717 .inferred_error_set_type,10707 .inferred_error_set_type,
1071810708
10719 .enum_literal,10709 .enum_literal,
10720 .empty_enum_value,
10721 .memoized_call,10710 .memoized_call,
10722 => unreachable, // not a runtime value10711 => unreachable, // not a runtime value
10723 .undef => break :free try isel.emit(if (mat.ra.isVector()) .movi(switch (size) {10712 .undef => break :free try isel.emit(if (mat.ra.isVector()) .movi(switch (size) {
...@@ -10738,7 +10727,7 @@ pub const Value = struct {...@@ -10738,7 +10727,7 @@ pub const Value = struct {
10738 } }),10727 } }),
10739 }),10728 }),
10740 .simple_value => |simple_value| switch (simple_value) {10729 .simple_value => |simple_value| switch (simple_value) {
10741 .undefined, .void, .null, .empty_tuple, .@"unreachable" => unreachable,10730 .void, .null, .@"unreachable" => unreachable,
10742 .true => continue :constant_key .{ .int = .{10731 .true => continue :constant_key .{ .int = .{
10743 .ty = .bool_type,10732 .ty = .bool_type,
10744 .storage = .{ .u64 = 1 },10733 .storage = .{ .u64 = 1 },
...@@ -10748,7 +10737,7 @@ pub const Value = struct {...@@ -10748,7 +10737,7 @@ pub const Value = struct {
10748 .storage = .{ .u64 = 0 },10737 .storage = .{ .u64 = 0 },
10749 } },10738 } },
10750 },10739 },
10751 .int => |int| break :free storage: switch (int.storage) {10740 .int => |int| break :free switch (int.storage) {
10752 .u64 => |imm| try isel.movImmediate(switch (size) {10741 .u64 => |imm| try isel.movImmediate(switch (size) {
10753 else => unreachable,10742 else => unreachable,
10754 1...4 => mat.ra.w(),10743 1...4 => mat.ra.w(),
...@@ -10780,12 +10769,6 @@ pub const Value = struct {...@@ -10780,12 +10769,6 @@ pub const Value = struct {
10780 }10769 }
10781 try isel.movImmediate(mat.ra.x(), imm);10770 try isel.movImmediate(mat.ra.x(), imm);
10782 },10771 },
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 },
10789 },10772 },
10790 .err => |err| continue :constant_key .{ .int = .{10773 .err => |err| continue :constant_key .{ .int = .{
10791 .ty = err.ty,10774 .ty = err.ty,
...@@ -10931,7 +10914,7 @@ pub const Value = struct {...@@ -10931,7 +10914,7 @@ pub const Value = struct {
10931 .ptr => |ptr| {10914 .ptr => |ptr| {
10932 assert(offset == 0 and size == 8);10915 assert(offset == 0 and size == 8);
10933 break :free switch (ptr.base_addr) {10916 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) {
10935 false => {10918 false => {
10936 try isel.nav_relocs.append(zcu.gpa, .{10919 try isel.nav_relocs.append(zcu.gpa, .{
10937 .nav = nav,10920 .nav = nav,
...@@ -10965,9 +10948,9 @@ pub const Value = struct {...@@ -10965,9 +10948,9 @@ pub const Value = struct {
10965 },10948 },
10966 } else continue :constant_key .{ .int = .{10949 } else continue :constant_key .{ .int = .{
10967 .ty = .usize_type,10950 .ty = .usize_type,
10968 .storage = .{ .u64 = isel.pt.navAlignment(nav).forward(0xaaaaaaaaaaaaaaaa) },10951 .storage = .{ .u64 = zcu.navAlignment(nav).forward(0xaaaaaaaaaaaaaaaa) },
10969 } },10952 } },
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) {
10971 false => {10954 false => {
10972 try isel.uav_relocs.append(zcu.gpa, .{10955 try isel.uav_relocs.append(zcu.gpa, .{
10973 .uav = uav,10956 .uav = uav,
...@@ -11092,13 +11075,9 @@ pub const Value = struct {...@@ -11092,13 +11075,9 @@ pub const Value = struct {
11092 var field_offset: u64 = 0;11075 var field_offset: u64 = 0;
11093 var field_it = loaded_struct.iterateRuntimeOrder(ip);11076 var field_it = loaded_struct.iterateRuntimeOrder(ip);
11094 while (field_it.next()) |field_index| {11077 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;
11096 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);11079 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
11097 field_offset = field_ty.structFieldAlignment(11080 field_offset = loaded_struct.field_offsets.get(ip)[field_index];
11098 loaded_struct.fieldAlign(ip, field_index),
11099 loaded_struct.layout,
11100 zcu,
11101 ).forward(field_offset);
11102 const field_size = field_ty.abiSize(zcu);11081 const field_size = field_ty.abiSize(zcu);
11103 if (offset >= field_offset and offset + size <= field_offset + field_size) {11082 if (offset >= field_offset and offset + size <= field_offset + field_size) {
11104 offset -= field_offset;11083 offset -= field_offset;
...@@ -11140,7 +11119,7 @@ pub const Value = struct {...@@ -11140,7 +11119,7 @@ pub const Value = struct {
11140 .un => |un| {11119 .un => |un| {
11141 const loaded_union = ip.loadUnionType(un.ty);11120 const loaded_union = ip.loadUnionType(un.ty);
11142 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);11121 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
11143 if (loaded_union.hasTag(ip)) {11122 if (loaded_union.has_runtime_tag) {
11144 const tag_offset = union_layout.tagOffset();11123 const tag_offset = union_layout.tagOffset();
11145 if (offset >= tag_offset and offset + size <= tag_offset + union_layout.tag_size) {11124 if (offset >= tag_offset and offset + size <= tag_offset + union_layout.tag_size) {
11146 offset -= tag_offset;11125 offset -= tag_offset;
...@@ -11414,7 +11393,6 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e...@@ -11414,7 +11393,6 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e
11414 .inferred_error_set_type,11393 .inferred_error_set_type,
1141511394
11416 .enum_literal,11395 .enum_literal,
11417 .empty_enum_value,
11418 .memoized_call,11396 .memoized_call,
11419 => unreachable, // not a runtime value11397 => unreachable, // not a runtime value
11420 .err => |err| {11398 .err => |err| {
...@@ -11486,13 +11464,9 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e...@@ -11486,13 +11464,9 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e
11486 var field_offset: u64 = 0;11464 var field_offset: u64 = 0;
11487 var field_it = loaded_struct.iterateRuntimeOrder(ip);11465 var field_it = loaded_struct.iterateRuntimeOrder(ip);
11488 while (field_it.next()) |field_index| {11466 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;
11490 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);11468 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
11491 field_offset = field_ty.structFieldAlignment(11469 field_offset = loaded_struct.field_offsets.get(ip)[field_index];
11492 loaded_struct.fieldAlign(ip, field_index),
11493 loaded_struct.layout,
11494 zcu,
11495 ).forward(field_offset);
11496 const field_size = field_ty.abiSize(zcu);11470 const field_size = field_ty.abiSize(zcu);
11497 if (!try isel.writeToMemory(.fromInterned(switch (aggregate.storage) {11471 if (!try isel.writeToMemory(.fromInterned(switch (aggregate.storage) {
11498 .bytes => unreachable,11472 .bytes => unreachable,
...@@ -12091,7 +12065,7 @@ pub const CallAbiIterator = struct {...@@ -12091,7 +12065,7 @@ pub const CallAbiIterator = struct {
12091 const zcu = isel.pt.zcu;12065 const zcu = isel.pt.zcu;
12092 const ip = &zcu.intern_pool;12066 const ip = &zcu.intern_pool;
1209312067
12094 if (ty.isNoReturn(zcu) or !ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;12068 if (!ty.hasRuntimeBits(zcu)) return null;
12095 try isel.values.ensureUnusedCapacity(zcu.gpa, Value.max_parts);12069 try isel.values.ensureUnusedCapacity(zcu.gpa, Value.max_parts);
12096 const wip_vi = isel.initValue(ty);12070 const wip_vi = isel.initValue(ty);
12097 type_key: switch (ip.indexToKey(ty.toIntern())) {12071 type_key: switch (ip.indexToKey(ty.toIntern())) {
...@@ -12195,7 +12169,7 @@ pub const CallAbiIterator = struct {...@@ -12195,7 +12169,7 @@ pub const CallAbiIterator = struct {
12195 switch (loaded_struct.layout) {12169 switch (loaded_struct.layout) {
12196 .auto, .@"extern" => {},12170 .auto, .@"extern" => {},
12197 .@"packed" => continue :type_key .{12171 .@"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,
12199 },12173 },
12200 }12174 }
12201 const size = wip_vi.size(isel);12175 const size = wip_vi.size(isel);
...@@ -12219,7 +12193,7 @@ pub const CallAbiIterator = struct {...@@ -12219,7 +12193,7 @@ pub const CallAbiIterator = struct {
12219 const field_end = next_field_end;12193 const field_end = next_field_end;
12220 const next_field_begin = if (field_it.next()) |field_index| next_field_begin: {12194 const next_field_begin = if (field_it.next()) |field_index| next_field_begin: {
12221 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);12195 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)) {
12223 .none => field_ty.abiAlignment(zcu),12197 .none => field_ty.abiAlignment(zcu),
12224 else => |field_align| field_align,12198 else => |field_align| field_align,
12225 }.forward(field_end);12199 }.forward(field_end);
...@@ -12285,7 +12259,7 @@ pub const CallAbiIterator = struct {...@@ -12285,7 +12259,7 @@ pub const CallAbiIterator = struct {
12285 },12259 },
12286 .union_type => {12260 .union_type => {
12287 const loaded_union = ip.loadUnionType(ty.toIntern());12261 const loaded_union = ip.loadUnionType(ty.toIntern());
12288 switch (loaded_union.flagsUnordered(ip).layout) {12262 switch (loaded_union.layout) {
12289 .auto, .@"extern" => {},12263 .auto, .@"extern" => {},
12290 .@"packed" => continue :type_key .{ .int_type = .{12264 .@"packed" => continue :type_key .{ .int_type = .{
12291 .signedness = .unsigned,12265 .signedness = .unsigned,
...@@ -12318,7 +12292,9 @@ pub const CallAbiIterator = struct {...@@ -12318,7 +12292,9 @@ pub const CallAbiIterator = struct {
12318 }12292 }
12319 },12293 },
12320 .opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque },12294 .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 },
12322 .error_set_type,12298 .error_set_type,
12323 .inferred_error_set_type,12299 .inferred_error_set_type,
12324 => continue :type_key .{ .simple_type = .anyerror },12300 => continue :type_key .{ .simple_type = .anyerror },
...@@ -12332,7 +12308,6 @@ pub const CallAbiIterator = struct {...@@ -12332,7 +12308,6 @@ pub const CallAbiIterator = struct {
12332 .error_union,12308 .error_union,
12333 .enum_literal,12309 .enum_literal,
12334 .enum_tag,12310 .enum_tag,
12335 .empty_enum_value,
12336 .float,12311 .float,
12337 .ptr,12312 .ptr,
12338 .slice,12313 .slice,
...@@ -12424,8 +12399,8 @@ pub const CallAbiIterator = struct {...@@ -12424,8 +12399,8 @@ pub const CallAbiIterator = struct {
12424 const ip = &zcu.intern_pool;12399 const ip = &zcu.intern_pool;
12425 var common_fdt: ?FundamentalDataType = null;12400 var common_fdt: ?FundamentalDataType = null;
12426 for (0.., loaded_struct.field_types.get(ip)) |field_index, field_ty| {12401 for (0.., loaded_struct.field_types.get(ip)) |field_index, field_ty| {
12427 if (loaded_struct.fieldIsComptime(ip, field_index)) continue;12402 if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
12428 if (loaded_struct.fieldAlign(ip, field_index) != .none) return null;12403 if (loaded_struct.field_aligns.getOrNone(ip, field_index) != .none) return null;
12429 if (!ZigType.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;12404 if (!ZigType.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
12430 const fdt = homogeneousAggregateBaseType(zcu, field_ty);12405 const fdt = homogeneousAggregateBaseType(zcu, field_ty);
12431 if (common_fdt == null) common_fdt = fdt else if (fdt != common_fdt) return null;12406 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) {...@@ -13,7 +13,7 @@ pub const Class = union(enum) {
1313
14/// For `float_array` the second element will be the amount of floats.14/// For `float_array` the second element will be the amount of floats.
15pub fn classifyType(ty: Type, zcu: *Zcu) Class {15pub fn classifyType(ty: Type, zcu: *Zcu) Class {
16 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));16 assert(ty.hasRuntimeBits(zcu));
1717
18 var maybe_float_bits: ?u16 = null;18 var maybe_float_bits: ?u16 = null;
19 switch (ty.zigTypeTag(zcu)) {19 switch (ty.zigTypeTag(zcu)) {
src/codegen/arm/abi.zig+13-11
...@@ -23,7 +23,7 @@ pub const Class = union(enum) {...@@ -23,7 +23,7 @@ pub const Class = union(enum) {
23pub const Context = enum { ret, arg };23pub const Context = enum { ret, arg };
2424
25pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {25pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
26 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));26 assert(ty.hasRuntimeBits(zcu));
2727
28 var maybe_float_bits: ?u16 = null;28 var maybe_float_bits: ?u16 = null;
29 const max_byval_size = 512;29 const max_byval_size = 512;
...@@ -39,22 +39,22 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -39,22 +39,22 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
39 const float_count = countFloats(ty, zcu, &maybe_float_bits);39 const float_count = countFloats(ty, zcu, &maybe_float_bits);
40 if (float_count <= byval_float_count) return .byval;40 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
42 const fields = ty.structFieldCount(zcu);46 const fields = ty.structFieldCount(zcu);
43 var i: u32 = 0;47 var i: u32 = 0;
44 while (i < fields) : (i += 1) {48 while (i < fields) : (i += 1) {
45 const field_ty = ty.fieldType(i, zcu);49 const field_ty = ty.fieldType(i, zcu);
46 const field_alignment = ty.fieldAlignment(i, zcu);50 if (field_ty.bitSize(zcu) > 32) return Class.arrSize(bit_size, 64);
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 }
51 }51 }
52 return Class.arrSize(bit_size, 32);52 return Class.arrSize(bit_size, 32);
53 },53 },
54 .@"union" => {54 .@"union" => {
55 const bit_size = ty.bitSize(zcu);55 const bit_size = ty.bitSize(zcu);
56 const union_obj = zcu.typeToUnion(ty).?;56 const union_obj = zcu.typeToUnion(ty).?;
57 if (union_obj.flagsUnordered(ip).layout == .@"packed") {57 if (union_obj.layout == .@"packed") {
58 if (bit_size > 64) return .memory;58 if (bit_size > 64) return .memory;
59 return .byval;59 return .byval;
60 }60 }
...@@ -62,10 +62,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -62,10 +62,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
62 const float_count = countFloats(ty, zcu, &maybe_float_bits);62 const float_count = countFloats(ty, zcu, &maybe_float_bits);
63 if (float_count <= byval_float_count) return .byval;63 if (float_count <= byval_float_count) return .byval;
6464
65 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {65 if (union_obj.alignment.compareStrict(.gt, .@"32")) {
66 if (Type.fromInterned(field_ty).bitSize(zcu) > 32 or66 return Class.arrSize(bit_size, 64);
67 ty.fieldAlignment(field_index, zcu).compare(.gt, .@"32"))67 }
68 {68
69 for (union_obj.field_types.get(ip)) |field_ty| {
70 if (Type.fromInterned(field_ty).bitSize(zcu) > 32) {
69 return Class.arrSize(bit_size, 64);71 return Class.arrSize(bit_size, 64);
70 }72 }
71 }73 }
src/codegen/c.zig+2390-3190
...@@ -50,32 +50,39 @@ pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {...@@ -50,32 +50,39 @@ pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
50/// * The types used, so declarations can be emitted in `flush`50/// * The types used, so declarations can be emitted in `flush`
51/// * The lazy functions used, so definitions can be emitted in `flush`51/// * The lazy functions used, so definitions can be emitted in `flush`
52pub const Mir = struct {52pub 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,
53 /// This map contains all the UAVs we saw generating this function.57 /// This map contains all the UAVs we saw generating this function.
54 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.58 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
55 /// Key is the value of the UAV; value is the UAV's alignment, or59 /// Key is the value of the UAV; value is the UAV's alignment, or
56 /// `.none` for natural alignment. The specified alignment is never60 /// `.none` for natural alignment. The specified alignment is never
57 /// less than the natural alignment.61 /// less than the natural alignment.
58 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),62 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
59 // These remaining fields are essentially just an owned version of `link.C.AvBlock`.63 ctype_deps: CType.Dependencies,
60 code_header: []u8,64 /// Key is an enum type for which we need a generated `@tagName` function.
61 code: []u8,65 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
62 fwd_decl: []u8,66 /// Key is a function Nav for which we need a generated `zig_never_tail` wrapper.
63 ctype_pool: CType.Pool,67 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
64 lazy_fns: LazyFnMap,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
66 pub fn deinit(mir: *Mir, gpa: Allocator) void {71 pub fn deinit(mir: *Mir, gpa: Allocator) void {
67 mir.uavs.deinit(gpa);72 gpa.free(mir.fwd_decl);
68 gpa.free(mir.code_header);73 gpa.free(mir.code_header);
69 gpa.free(mir.code);74 gpa.free(mir.code);
70 gpa.free(mir.fwd_decl);75 mir.need_uavs.deinit(gpa);
71 mir.ctype_pool.deinit(gpa);76 mir.ctype_deps.deinit(gpa);
72 mir.lazy_fns.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);
73 }80 }
74};81};
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
80pub const CValue = union(enum) {87pub const CValue = union(enum) {
81 none: void,88 none: void,
...@@ -87,8 +94,6 @@ pub const CValue = union(enum) {...@@ -87,8 +94,6 @@ pub const CValue = union(enum) {
87 constant: Value,94 constant: Value,
88 /// Index into the parameters95 /// Index into the parameters
89 arg: usize,96 arg: usize,
90 /// The array field of a parameter
91 arg_array: usize,
92 /// Index into a tuple's fields97 /// Index into a tuple's fields
93 field: usize,98 field: usize,
94 /// By-value99 /// By-value
...@@ -100,8 +105,6 @@ pub const CValue = union(enum) {...@@ -100,8 +105,6 @@ pub const CValue = union(enum) {
100 identifier: []const u8,105 identifier: []const u8,
101 /// Rendered as "payload." followed by as identifier (using fmtIdent)106 /// Rendered as "payload." followed by as identifier (using fmtIdent)
102 payload_identifier: []const u8,107 payload_identifier: []const u8,
103 /// Rendered with fmtCTypePoolString
104 ctype_pool_string: CType.Pool.String,
105108
106 fn eql(lhs: CValue, rhs: CValue) bool {109 fn eql(lhs: CValue, rhs: CValue) bool {
107 return switch (lhs) {110 return switch (lhs) {
...@@ -122,10 +125,6 @@ pub const CValue = union(enum) {...@@ -122,10 +125,6 @@ pub const CValue = union(enum) {
122 .arg => |rhs_arg_index| lhs_arg_index == rhs_arg_index,125 .arg => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
123 else => false,126 else => false,
124 },127 },
125 .arg_array => |lhs_arg_index| switch (rhs) {
126 .arg_array => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
127 else => false,
128 },
129 .field => |lhs_field_index| switch (rhs) {128 .field => |lhs_field_index| switch (rhs) {
130 .field => |rhs_field_index| lhs_field_index == rhs_field_index,129 .field => |rhs_field_index| lhs_field_index == rhs_field_index,
131 else => false,130 else => false,
...@@ -150,10 +149,6 @@ pub const CValue = union(enum) {...@@ -150,10 +149,6 @@ pub const CValue = union(enum) {
150 .payload_identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),149 .payload_identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),
151 else => false,150 else => false,
152 },151 },
153 .ctype_pool_string => |lhs_str| switch (rhs) {
154 .ctype_pool_string => |rhs_str| lhs_str.index == rhs_str.index,
155 else => false,
156 },
157 };152 };
158 }153 }
159};154};
...@@ -163,53 +158,24 @@ const BlockData = struct {...@@ -163,53 +158,24 @@ const BlockData = struct {
163 result: CValue,158 result: CValue,
164};159};
165160
166pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);161const LocalType = struct {
167162 type: Type,
168pub const LazyFnKey = union(enum) {163 alignment: Alignment,
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 }
188};164};
189165
190const LocalIndex = u16;166const LocalIndex = u16;
191const LocalType = struct { ctype: CType, alignas: CType.AlignAs };
192const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void);167const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void);
193const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);168const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);
194169
195const ValueRenderLocation = enum {170const ValueRenderLocation = enum {
196 FunctionArgument,171 initializer,
197 Initializer,172 static_initializer,
198 StaticInitializer,173 other,
199 Other,
200174
201 fn isInitializer(loc: ValueRenderLocation) bool {175 fn isInitializer(loc: ValueRenderLocation) bool {
202 return switch (loc) {176 return switch (loc) {
203 .Initializer, .StaticInitializer => true,177 .initializer, .static_initializer => true,
204 else => false,178 .other => 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,
213 };179 };
214 }180 }
215};181};
...@@ -334,16 +300,31 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{...@@ -334,16 +300,31 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
334});300});
335301
336fn isReservedIdent(ident: []const u8) bool {302fn isReservedIdent(ident: []const u8) bool {
337 if (ident.len >= 2 and ident[0] == '_') { // C language303 // C language
304 if (ident.len >= 2 and ident[0] == '_') {
338 switch (ident[1]) {305 switch (ident[1]) {
339 'A'...'Z', '_' => return true,306 'A'...'Z', '_' => return true,
340 else => return false,307 else => {},
341 }308 }
342 } else if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or309 }
310
311 // windows.h
312 if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or
343 mem.startsWith(u8, ident, "DUMMYUNIONNAME"))313 mem.startsWith(u8, ident, "DUMMYUNIONNAME"))
344 { // windows.h314 {
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 {
345 return true;324 return true;
346 } else return reserved_idents.has(ident);325 }
326
327 return reserved_idents.has(ident);
347}328}
348329
349fn formatIdentSolo(ident: []const u8, w: *Writer) Writer.Error!void {330fn 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...@@ -361,7 +342,7 @@ fn formatIdentOptions(ident: []const u8, w: *Writer, solo: bool) Writer.Error!vo
361 for (ident, 0..) |c, i| {342 for (ident, 0..) |c, i| {
362 switch (c) {343 switch (c) {
363 'a'...'z', 'A'...'Z', '_' => try w.writeByte(c),344 'a'...'z', 'A'...'Z', '_' => try w.writeByte(c),
364 '.' => try w.writeByte('_'),345 '.', ' ' => try w.writeByte('_'),
365 '0'...'9' => if (i == 0) {346 '0'...'9' => if (i == 0) {
366 try w.print("_{x:2}", .{c});347 try w.print("_{x:2}", .{c});
367 } else {348 } else {
...@@ -380,29 +361,6 @@ pub fn fmtIdentUnsolo(ident: []const u8) std.fmt.Alt([]const u8, formatIdentUnso...@@ -380,29 +361,6 @@ pub fn fmtIdentUnsolo(ident: []const u8) std.fmt.Alt([]const u8, formatIdentUnso
380 return .{ .data = ident };361 return .{ .data = ident };
381}362}
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
406// Returns true if `formatIdent` would make any edits to ident.364// Returns true if `formatIdent` would make any edits to ident.
407// This must be kept in sync with `formatIdent`.365// This must be kept in sync with `formatIdent`.
408pub fn isMangledIdent(ident: []const u8, solo: bool) bool {366pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
...@@ -417,21 +375,26 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool {...@@ -417,21 +375,26 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
417 return false;375 return false;
418}376}
419377
420/// This data is available when outputting .c code for a `InternPool.Index`378/// This data is available when rendering C source code for an interned function.
421/// that corresponds to `func`.
422/// It is not available when generating .h file.
423pub const Function = struct {379pub const Function = struct {
424 air: Air,380 air: Air,
425 liveness: Air.Liveness,381 liveness: Air.Liveness,
426 value_map: CValueMap,382 value_map: std.AutoHashMap(Air.Inst.Ref, CValue),
427 blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .empty,383 blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .empty,
428 next_arg_index: u32 = 0,384 next_arg_index: u32 = 0,
429 next_block_index: u32 = 0,385 next_block_index: u32 = 0,
430 object: Object,386 dg: DeclGen,
431 lazy_fns: LazyFnMap,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),
432 func_index: InternPool.Index,395 func_index: InternPool.Index,
433 /// All the locals, to be emitted at the top of the function.396 /// All the locals, to be emitted at the top of the function.
434 locals: std.ArrayList(Local) = .empty,397 locals: std.ArrayList(LocalType) = .empty,
435 /// Which locals are available for reuse, based on Type.398 /// Which locals are available for reuse, based on Type.
436 free_locals_map: LocalsMap = .{},399 free_locals_map: LocalsMap = .{},
437 /// Locals which will not be freed by Liveness. This is used after a400 /// Locals which will not be freed by Liveness. This is used after a
...@@ -445,37 +408,41 @@ pub const Function = struct {...@@ -445,37 +408,41 @@ pub const Function = struct {
445 /// for the switch cond. Dispatches should set this local to the new cond.408 /// for the switch cond. Dispatches should set this local to the new cond.
446 loop_switch_conds: std.AutoHashMapUnmanaged(Air.Inst.Index, LocalIndex) = .empty,409 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
448 fn resolveInst(f: *Function, ref: Air.Inst.Ref) !CValue {435 fn resolveInst(f: *Function, ref: Air.Inst.Ref) !CValue {
449 const gop = try f.value_map.getOrPut(ref);436 const gop = try f.value_map.getOrPut(ref);
450 if (gop.found_existing) return gop.value_ptr.*;437 if (!gop.found_existing) {
451438 const val = try f.air.value(ref, f.dg.pt);
452 const pt = f.object.dg.pt;439 gop.value_ptr.* = .{ .constant = val.? };
453 const zcu = pt.zcu;440 }
454 const val = (try f.air.value(ref, pt)).?;441 return gop.value_ptr.*;
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;
475 }442 }
476443
477 fn wantSafety(f: *Function) bool {444 fn wantSafety(f: *Function) bool {
478 return switch (f.object.dg.pt.zcu.optimizeMode()) {445 return switch (f.dg.pt.zcu.optimizeMode()) {
479 .Debug, .ReleaseSafe => true,446 .Debug, .ReleaseSafe => true,
480 .ReleaseFast, .ReleaseSmall => false,447 .ReleaseFast, .ReleaseSmall => false,
481 };448 };
...@@ -485,18 +452,16 @@ pub const Function = struct {...@@ -485,18 +452,16 @@ pub const Function = struct {
485 /// those which go into `allocs`. This function does not add the resulting local into `allocs`;452 /// those which go into `allocs`. This function does not add the resulting local into `allocs`;
486 /// that responsibility lies with the caller.453 /// that responsibility lies with the caller.
487 fn allocLocalValue(f: *Function, local_type: LocalType) !CValue {454 fn allocLocalValue(f: *Function, local_type: LocalType) !CValue {
488 try f.locals.ensureUnusedCapacity(f.object.dg.gpa, 1);455 try f.locals.ensureUnusedCapacity(f.dg.gpa, 1);
489 defer f.locals.appendAssumeCapacity(.{456 const index = f.locals.items.len;
490 .ctype = local_type.ctype,457 f.locals.appendAssumeCapacity(local_type);
491 .flags = .{ .alignas = local_type.alignas },458 return .{ .new_local = @intCast(index) };
492 });
493 return .{ .new_local = @intCast(f.locals.items.len) };
494 }459 }
495460
496 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {461 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {
497 return f.allocAlignedLocal(inst, .{462 return f.allocAlignedLocal(inst, .{
498 .ctype = try f.ctypeFromType(ty, .complete),463 .type = ty,
499 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.pt.zcu)),464 .alignment = .none,
500 });465 });
501 }466 }
502467
...@@ -524,11 +489,10 @@ pub const Function = struct {...@@ -524,11 +489,10 @@ pub const Function = struct {
524 .none => unreachable,489 .none => unreachable,
525 .new_local, .local => |i| try w.print("t{d}", .{i}),490 .new_local, .local => |i| try w.print("t{d}", .{i}),
526 .local_ref => |i| try w.print("&t{d}", .{i}),491 .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),
528 .arg => |i| try w.print("a{d}", .{i}),493 .arg => |i| try w.print("a{d}", .{i}),
529 .arg_array => |i| try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),494 .undef => |ty| try f.dg.renderUndefValue(w, ty, location),
530 .undef => |ty| try f.object.dg.renderUndefValue(w, ty, location),495 else => try f.dg.writeCValue(w, c_value),
531 else => try f.object.dg.writeCValue(w, c_value),
532 }496 }
533 }497 }
534498
...@@ -537,17 +501,12 @@ pub const Function = struct {...@@ -537,17 +501,12 @@ pub const Function = struct {
537 .none => unreachable,501 .none => unreachable,
538 .new_local, .local, .constant => {502 .new_local, .local, .constant => {
539 try w.writeAll("(*");503 try w.writeAll("(*");
540 try f.writeCValue(w, c_value, .Other);504 try f.writeCValue(w, c_value, .other);
541 try w.writeByte(')');505 try w.writeByte(')');
542 },506 },
543 .local_ref => |i| try w.print("t{d}", .{i}),507 .local_ref => |i| try w.print("t{d}", .{i}),
544 .arg => |i| try w.print("(*a{d})", .{i}),508 .arg => |i| try w.print("(*a{d})", .{i}),
545 .arg_array => |i| {509 else => try f.dg.writeCValueDeref(w, c_value),
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),
551 }510 }
552 }511 }
553512
...@@ -558,119 +517,77 @@ pub const Function = struct {...@@ -558,119 +517,77 @@ pub const Function = struct {
558 member: CValue,517 member: CValue,
559 ) Error!void {518 ) Error!void {
560 switch (c_value) {519 switch (c_value) {
561 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {520 .new_local, .local, .local_ref, .constant, .arg => {
562 try f.writeCValue(w, c_value, .Other);521 try f.writeCValue(w, c_value, .other);
563 try w.writeByte('.');522 try w.writeByte('.');
564 try f.writeCValue(w, member, .Other);523 try f.writeCValue(w, member, .other);
565 },524 },
566 else => return f.object.dg.writeCValueMember(w, c_value, member),525 else => return f.dg.writeCValueMember(w, c_value, member),
567 }526 }
568 }527 }
569528
570 fn writeCValueDerefMember(f: *Function, w: *Writer, c_value: CValue, member: CValue) !void {529 fn writeCValueDerefMember(f: *Function, w: *Writer, c_value: CValue, member: CValue) !void {
571 switch (c_value) {530 switch (c_value) {
572 .new_local, .local, .arg, .arg_array => {531 .new_local, .local, .arg => {
573 try f.writeCValue(w, c_value, .Other);532 try f.writeCValue(w, c_value, .other);
574 try w.writeAll("->");533 try w.writeAll("->");
575 },534 },
576 .constant => {535 .constant => {
577 try w.writeByte('(');536 try w.writeByte('(');
578 try f.writeCValue(w, c_value, .Other);537 try f.writeCValue(w, c_value, .other);
579 try w.writeAll(")->");538 try w.writeAll(")->");
580 },539 },
581 .local_ref => {540 .local_ref => {
582 try f.writeCValueDeref(w, c_value);541 try f.writeCValueDeref(w, c_value);
583 try w.writeByte('.');542 try w.writeByte('.');
584 },543 },
585 else => return f.object.dg.writeCValueDerefMember(w, c_value, member),544 else => return f.dg.writeCValueDerefMember(w, c_value, member),
586 }545 }
587 try f.writeCValue(w, member, .Other);546 try f.writeCValue(w, member, .other);
588 }547 }
589548
590 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {549 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {
591 return f.object.dg.fail(format, args);550 return f.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);
604 }551 }
605552
606 fn renderCType(f: *Function, w: *Writer, ctype: CType) !void {553 fn renderType(f: *Function, w: *Writer, ty: Type) !void {
607 return f.object.dg.renderCType(w, ctype);554 return f.dg.renderType(w, ty);
608 }555 }
609556
610 fn renderIntCast(f: *Function, w: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {557 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);
612 }559 }
613560
614 fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {561 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);
616 }563 }
617564
618 fn fmtIntLiteralHex(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {565 fn fmtIntLiteralHex(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
619 return f.object.dg.fmtIntLiteralHex(val, .Other);566 return f.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).?;
652 }567 }
653568
654 pub fn deinit(f: *Function) void {569 pub fn deinit(f: *Function) void {
655 const gpa = f.object.dg.gpa;570 const gpa = f.dg.gpa;
656 f.allocs.deinit(gpa);571 f.allocs.deinit(gpa);
657 f.locals.deinit(gpa);572 f.locals.deinit(gpa);
658 deinitFreeLocalsMap(gpa, &f.free_locals_map);573 deinitFreeLocalsMap(gpa, &f.free_locals_map);
659 f.blocks.deinit(gpa);574 f.blocks.deinit(gpa);
660 f.value_map.deinit();575 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);
662 f.loop_switch_conds.deinit(gpa);579 f.loop_switch_conds.deinit(gpa);
663 }580 }
664581
665 fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {582 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);
667 }584 }
668585
669 fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {586 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);
671 }588 }
672589
673 fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void {590 fn copyCValue(f: *Function, dst: CValue, src: CValue) !void {
674 switch (dst) {591 switch (dst) {
675 .new_local, .local => |dst_local_index| switch (src) {592 .new_local, .local => |dst_local_index| switch (src) {
676 .new_local, .local => |src_local_index| if (dst_local_index == src_local_index) return,593 .new_local, .local => |src_local_index| if (dst_local_index == src_local_index) return,
...@@ -678,12 +595,12 @@ pub const Function = struct {...@@ -678,12 +595,12 @@ pub const Function = struct {
678 },595 },
679 else => {},596 else => {},
680 }597 }
681 const w = &f.object.code.writer;598 const w = &f.code.writer;
682 const a = try Assignment.start(f, w, ctype);599 try f.writeCValue(w, dst, .other);
683 try f.writeCValue(w, dst, .Other);600 try w.writeAll(" = ");
684 try a.assign(f, w);601 try f.writeCValue(w, src, .other);
685 try f.writeCValue(w, src, .Other);602 try w.writeByte(';');
686 try a.end(f, w);603 try f.newline();
687 }604 }
688605
689 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {606 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {
...@@ -694,7 +611,7 @@ pub const Function = struct {...@@ -694,7 +611,7 @@ pub const Function = struct {
694 else => {611 else => {
695 try freeCValue(f, inst, src);612 try freeCValue(f, inst, src);
696 const dst = try f.allocLocal(inst, ty);613 const dst = try f.allocLocal(inst, ty);
697 try f.copyCValue(try f.ctypeFromType(ty, .complete), dst, src);614 try f.copyCValue(dst, src);
698 return dst;615 return dst;
699 },616 },
700 }617 }
...@@ -708,51 +625,17 @@ pub const Function = struct {...@@ -708,51 +625,17 @@ pub const Function = struct {
708 }625 }
709};626};
710627
711/// This data is available when outputting .c code for a `Zcu`.628/// This data is available when rendering *any* C source code (function or otherwise).
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.
745pub const DeclGen = struct {629pub const DeclGen = struct {
746 gpa: Allocator,630 gpa: Allocator,
631 arena: Allocator,
747 pt: Zcu.PerThread,632 pt: Zcu.PerThread,
748 mod: *Module,633 mod: *Module,
749 pass: Pass,634 owner_nav: InternPool.Nav.Index.Optional,
750 is_naked_fn: bool,635 is_naked_fn: bool,
751 expected_block: ?u32,636 expected_block: ?u32,
752 fwd_decl: Writer.Allocating,
753 error_msg: ?*Zcu.ErrorMsg,637 error_msg: ?*Zcu.ErrorMsg,
754 ctype_pool: CType.Pool,638 ctype_deps: CType.Dependencies,
755 scratch: std.ArrayList(u32),
756 /// This map contains all the UAVs we saw generating this function.639 /// This map contains all the UAVs we saw generating this function.
757 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.640 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
758 /// Key is the value of the UAV; value is the UAV's alignment, or641 /// Key is the value of the UAV; value is the UAV's alignment, or
...@@ -760,16 +643,10 @@ pub const DeclGen = struct {...@@ -760,16 +643,10 @@ pub const DeclGen = struct {
760 /// less than the natural alignment.643 /// less than the natural alignment.
761 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),644 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
769 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {646 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
770 @branchHint(.cold);647 @branchHint(.cold);
771 const zcu = dg.pt.zcu;648 const zcu = dg.pt.zcu;
772 const src_loc = zcu.navSrcLoc(dg.pass.nav);649 const src_loc = zcu.navSrcLoc(dg.owner_nav.unwrap().?);
773 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);650 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
774 return error.AnalysisFail;651 return error.AnalysisFail;
775 }652 }
...@@ -783,14 +660,13 @@ pub const DeclGen = struct {...@@ -783,14 +660,13 @@ pub const DeclGen = struct {
783 const pt = dg.pt;660 const pt = dg.pt;
784 const zcu = pt.zcu;661 const zcu = pt.zcu;
785 const ip = &zcu.intern_pool;662 const ip = &zcu.intern_pool;
786 const ctype_pool = &dg.ctype_pool;
787 const uav_val = Value.fromInterned(uav.val);663 const uav_val = Value.fromInterned(uav.val);
788 const uav_ty = uav_val.typeOf(zcu);664 const uav_ty = uav_val.typeOf(zcu);
789665
790 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.666 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
791 const ptr_ty: Type = .fromInterned(uav.orig_ty);667 const ptr_ty: Type = .fromInterned(uav.orig_ty);
792 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) {668 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
793 return dg.writeCValue(w, .{ .undef = ptr_ty });669 return dg.renderUndefValue(w, ptr_ty, location);
794 }670 }
795671
796 // Chase function values in order to be able to reference the original function.672 // Chase function values in order to be able to reference the original function.
...@@ -805,14 +681,12 @@ pub const DeclGen = struct {...@@ -805,14 +681,12 @@ pub const DeclGen = struct {
805 // them). The analysis until now should ensure that the C function681 // them). The analysis until now should ensure that the C function
806 // pointers are compatible. If they are not, then there is a bug682 // pointers are compatible. If they are not, then there is a bug
807 // somewhere and we should let the C compiler tell us about it.683 // somewhere and we should let the C compiler tell us about it.
808 const ptr_ctype = try dg.ctypeFromType(ptr_ty, .complete);684 const elem_ty = ptr_ty.childType(zcu);
809 const elem_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;685 const need_cast = elem_ty.toIntern() != uav_ty.toIntern() and
810 const uav_ctype = try dg.ctypeFromType(uav_ty, .complete);686 elem_ty.zigTypeTag(zcu) != .@"fn" or uav_ty.zigTypeTag(zcu) != .@"fn";
811 const need_cast = !elem_ctype.eql(uav_ctype) and
812 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
813 if (need_cast) {687 if (need_cast) {
814 try w.writeAll("((");688 try w.writeAll("((");
815 try dg.renderCType(w, ptr_ctype);689 try dg.renderType(w, ptr_ty);
816 try w.writeByte(')');690 try w.writeByte(')');
817 }691 }
818 try w.writeByte('&');692 try w.writeByte('&');
...@@ -842,11 +716,9 @@ pub const DeclGen = struct {...@@ -842,11 +716,9 @@ pub const DeclGen = struct {
842 nav_index: InternPool.Nav.Index,716 nav_index: InternPool.Nav.Index,
843 location: ValueRenderLocation,717 location: ValueRenderLocation,
844 ) Error!void {718 ) Error!void {
845 _ = location;
846 const pt = dg.pt;719 const pt = dg.pt;
847 const zcu = pt.zcu;720 const zcu = pt.zcu;
848 const ip = &zcu.intern_pool;721 const ip = &zcu.intern_pool;
849 const ctype_pool = &dg.ctype_pool;
850722
851 // Chase function values in order to be able to reference the original function.723 // Chase function values in order to be able to reference the original function.
852 const owner_nav = switch (ip.getNav(nav_index).status) {724 const owner_nav = switch (ip.getNav(nav_index).status) {
...@@ -862,26 +734,24 @@ pub const DeclGen = struct {...@@ -862,26 +734,24 @@ pub const DeclGen = struct {
862 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.734 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
863 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));735 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));
864 const ptr_ty = try pt.navPtrType(owner_nav);736 const ptr_ty = try pt.navPtrType(owner_nav);
865 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {737 if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
866 return dg.writeCValue(w, .{ .undef = ptr_ty });738 return dg.renderUndefValue(w, ptr_ty, location);
867 }739 }
868740
869 // We shouldn't cast C function pointers as this is UB (when you call741 // We shouldn't cast C function pointers as this is UB (when you call
870 // them). The analysis until now should ensure that the C function742 // them). The analysis until now should ensure that the C function
871 // pointers are compatible. If they are not, then there is a bug743 // pointers are compatible. If they are not, then there is a bug
872 // somewhere and we should let the C compiler tell us about it.744 // somewhere and we should let the C compiler tell us about it.
873 const ctype = try dg.ctypeFromType(ptr_ty, .complete);745 const elem_ty = ptr_ty.childType(zcu);
874 const elem_ctype = ctype.info(ctype_pool).pointer.elem_ctype;746 const need_cast = elem_ty.toIntern() != nav_ty.toIntern() and
875 const nav_ctype = try dg.ctypeFromType(nav_ty, .complete);747 elem_ty.zigTypeTag(zcu) != .@"fn" or nav_ty.zigTypeTag(zcu) != .@"fn";
876 const need_cast = !elem_ctype.eql(nav_ctype) and
877 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
878 if (need_cast) {748 if (need_cast) {
879 try w.writeAll("((");749 try w.writeAll("((");
880 try dg.renderCType(w, ctype);750 try dg.renderType(w, ptr_ty);
881 try w.writeByte(')');751 try w.writeByte(')');
882 }752 }
883 try w.writeByte('&');753 try w.writeByte('&');
884 try dg.renderNavName(w, owner_nav);754 try renderNavName(w, owner_nav, ip);
885 if (need_cast) try w.writeByte(')');755 if (need_cast) try w.writeByte(')');
886 }756 }
887757
...@@ -896,11 +766,10 @@ pub const DeclGen = struct {...@@ -896,11 +766,10 @@ pub const DeclGen = struct {
896 switch (derivation) {766 switch (derivation) {
897 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,767 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,
898 .int => |int| {768 .int => |int| {
899 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);
900 const addr_val = try pt.intValue(.usize, int.addr);769 const addr_val = try pt.intValue(.usize, int.addr);
901 try w.writeByte('(');770 try w.writeByte('(');
902 try dg.renderCType(w, ptr_ctype);771 try dg.renderType(w, int.ptr_ty);
903 try w.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .Other)});772 try w.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .other)});
904 },773 },
905774
906 .nav_ptr => |nav| try dg.renderNav(w, nav, location),775 .nav_ptr => |nav| try dg.renderNav(w, nav, location),
...@@ -915,14 +784,10 @@ pub const DeclGen = struct {...@@ -915,14 +784,10 @@ pub const DeclGen = struct {
915 .field_ptr => |field| {784 .field_ptr => |field| {
916 const parent_ptr_ty = try field.parent.ptrType(pt);785 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
921 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, zcu)) {787 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, zcu)) {
922 .begin => {788 .begin => {
923 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
924 try w.writeByte('(');789 try w.writeByte('(');
925 try dg.renderCType(w, ptr_ctype);790 try dg.renderType(w, field.result_ptr_ty);
926 try w.writeByte(')');791 try w.writeByte(')');
927 try dg.renderPointer(w, field.parent.*, location);792 try dg.renderPointer(w, field.parent.*, location);
928 },793 },
...@@ -933,51 +798,40 @@ pub const DeclGen = struct {...@@ -933,51 +798,40 @@ pub const DeclGen = struct {
933 try dg.writeCValue(w, name);798 try dg.writeCValue(w, name);
934 },799 },
935 .byte_offset => |byte_offset| {800 .byte_offset => |byte_offset| {
936 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
937 try w.writeByte('(');801 try w.writeByte('(');
938 try dg.renderCType(w, ptr_ctype);802 try dg.renderType(w, field.result_ptr_ty);
939 try w.writeByte(')');803 try w.writeByte(')');
940 const offset_val = try pt.intValue(.usize, byte_offset);804 const offset_val = try pt.intValue(.usize, byte_offset);
941 try w.writeAll("((char *)");805 try w.writeAll("((char *)");
942 try dg.renderPointer(w, field.parent.*, location);806 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)});
944 },808 },
945 }809 }
946 },810 },
947811
948 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {812 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {
949 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.813 // 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);
951 try w.writeByte('(');814 try w.writeByte('(');
952 try dg.renderCType(w, ptr_ctype);815 try dg.renderType(w, elem.result_ptr_ty);
953 try w.writeByte(')');816 try w.writeByte(')');
954 try dg.renderPointer(w, elem.parent.*, location);817 try dg.renderPointer(w, elem.parent.*, location);
955 } else {818 } else {
956 const index_val = try pt.intValue(.usize, elem.elem_idx);819 const index_val = try pt.intValue(.usize, elem.elem_idx);
957 // We want to do pointer arithmetic on a pointer to the element type.820 try w.writeByte('(');
958 // We might have a pointer-to-array. In this case, we must cast first.821 // We want to do pointer arithmetic on a pointer to the element type, but the parent
959 const result_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);822 // might be a pointer-to-array, in which case we must cast it.
960 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);823 if (elem.result_ptr_ty.toIntern() != (try elem.parent.ptrType(pt)).toIntern()) {
961 if (result_ctype.eql(parent_ctype)) {
962 // The pointer already has an appropriate type - just do the arithmetic.
963 try w.writeByte('(');824 try w.writeByte('(');
964 try dg.renderPointer(w, elem.parent.*, location);825 try dg.renderType(w, elem.result_ptr_ty);
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);
971 try w.writeByte(')');826 try w.writeByte(')');
972 try dg.renderPointer(w, elem.parent.*, location);
973 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});
974 }827 }
828 try dg.renderPointer(w, elem.parent.*, location);
829 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .other)});
975 },830 },
976831
977 .offset_and_cast => |oac| {832 .offset_and_cast => |oac| {
978 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);
979 try w.writeByte('(');833 try w.writeByte('(');
980 try dg.renderCType(w, ptr_ctype);834 try dg.renderType(w, oac.new_ptr_ty);
981 try w.writeByte(')');835 try w.writeByte(')');
982 if (oac.byte_offset == 0) {836 if (oac.byte_offset == 0) {
983 try dg.renderPointer(w, oac.parent.*, location);837 try dg.renderPointer(w, oac.parent.*, location);
...@@ -985,14 +839,40 @@ pub const DeclGen = struct {...@@ -985,14 +839,40 @@ pub const DeclGen = struct {
985 const offset_val = try pt.intValue(.usize, oac.byte_offset);839 const offset_val = try pt.intValue(.usize, oac.byte_offset);
986 try w.writeAll("((char *)");840 try w.writeAll("((char *)");
987 try dg.renderPointer(w, oac.parent.*, location);841 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)});
989 }843 }
990 },844 },
991 }845 }
992 }846 }
993847
994 fn renderErrorName(dg: *DeclGen, w: *Writer, err_name: InternPool.NullTerminatedString) !void {848 fn renderValueAsLvalue(
995 try w.print("zig_error_{f}", .{fmtIdentUnsolo(err_name.toSlice(&dg.pt.zcu.intern_pool))});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);
996 }876 }
997877
998 fn renderValue(878 fn renderValue(
...@@ -1005,16 +885,13 @@ pub const DeclGen = struct {...@@ -1005,16 +885,13 @@ pub const DeclGen = struct {
1005 const zcu = pt.zcu;885 const zcu = pt.zcu;
1006 const ip = &zcu.intern_pool;886 const ip = &zcu.intern_pool;
1007 const target = &dg.mod.resolved_target.result;887 const target = &dg.mod.resolved_target.result;
1008 const ctype_pool = &dg.ctype_pool;
1009888
1010 const initializer_type: ValueRenderLocation = switch (location) {889 const initializer_type: ValueRenderLocation = switch (location) {
1011 .StaticInitializer => .StaticInitializer,890 .static_initializer => .static_initializer,
1012 else => .Initializer,891 else => .initializer,
1013 };892 };
1014893
1015 const ty = val.typeOf(zcu);894 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());
1018 switch (ip.indexToKey(val.toIntern())) {895 switch (ip.indexToKey(val.toIntern())) {
1019 // types, not values896 // types, not values
1020 .int_type,897 .int_type,
...@@ -1037,13 +914,11 @@ pub const DeclGen = struct {...@@ -1037,13 +914,11 @@ pub const DeclGen = struct {
1037 .memoized_call,914 .memoized_call,
1038 => unreachable,915 => unreachable,
1039916
1040 .undef => unreachable, // handled above917 .undef => try dg.renderUndefValue(w, ty, location),
1041 .simple_value => |simple_value| switch (simple_value) {918 .simple_value => |simple_value| switch (simple_value) {
1042 // non-runtime values919 // non-runtime values
1043 .undefined => unreachable,
1044 .void => unreachable,920 .void => unreachable,
1045 .null => unreachable,921 .null => unreachable,
1046 .empty_tuple => unreachable,
1047 .@"unreachable" => unreachable,922 .@"unreachable" => unreachable,
1048923
1049 .false => try w.writeAll("false"),924 .false => try w.writeAll("false"),
...@@ -1053,59 +928,30 @@ pub const DeclGen = struct {...@@ -1053,59 +928,30 @@ pub const DeclGen = struct {
1053 .@"extern",928 .@"extern",
1054 .func,929 .func,
1055 .enum_literal,930 .enum_literal,
1056 .empty_enum_value,
1057 => unreachable, // non-runtime values931 => unreachable, // non-runtime values
1058 .int => |int| switch (int.storage) {932 .int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),
1059 .u64, .i64, .big_int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),933 .err => |err| try renderErrorName(w, err.name.toSlice(ip)),
1060 .lazy_align, .lazy_size => {934 .error_union => |error_union| {
1061 try w.writeAll("((");935 if (!location.isInitializer()) {
1062 try dg.renderCType(w, ctype);936 try w.writeByte('(');
1063 try w.print("){f})", .{try dg.fmtIntLiteralHex(937 try dg.renderType(w, ty);
1064 try pt.intValue(.usize, val.toUnsignedInt(zcu)),938 try w.writeByte(')');
1065 .Other,939 }
1066 )});940 try w.writeAll("{ .error = ");
1067 },941 switch (error_union.val) {
1068 },942 .err_name => |err_name| try renderErrorName(w, err_name.toSlice(ip)),
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),
1073 .payload => try w.writeByte('0'),943 .payload => try w.writeByte('0'),
1074 },944 }
1075 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,945 if (ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
1076 .aggregate => |aggregate| {946 try w.writeAll(", .payload = ");
1077 if (!location.isInitializer()) {947 switch (error_union.val) {
1078 try w.writeByte('(');948 .err_name => try dg.renderUndefValue(w, ty.errorUnionPayload(zcu), initializer_type),
1079 try dg.renderCType(w, ctype);949 .payload => |payload| try dg.renderValue(w, .fromInterned(payload), initializer_type),
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 }
1104 }950 }
1105 try w.writeByte('}');951 }
1106 },952 try w.writeAll(" }");
1107 },953 },
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),
1109 .float => {955 .float => {
1110 const bits = ty.floatBits(target);956 const bits = ty.floatBits(target);
1111 const f128_val = val.toFloat(f128, zcu);957 const f128_val = val.toFloat(f128, zcu);
...@@ -1156,7 +1002,7 @@ pub const DeclGen = struct {...@@ -1156,7 +1002,7 @@ pub const DeclGen = struct {
1156 else1002 else
1157 unreachable;1003 unreachable;
11581004
1159 if (location == .StaticInitializer) {1005 if (location == .static_initializer) {
1160 if (!std.math.isNan(f128_val) and std.math.isSignalNan(f128_val))1006 if (!std.math.isNan(f128_val) and std.math.isSignalNan(f128_val))
1161 return dg.fail("TODO: C backend: implement nans rendering in static initializers", .{});1007 return dg.fail("TODO: C backend: implement nans rendering in static initializers", .{});
11621008
...@@ -1167,9 +1013,11 @@ pub const DeclGen = struct {...@@ -1167,9 +1013,11 @@ pub const DeclGen = struct {
1167 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});1013 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});
1168 }1014 }
11691015
1170 try w.writeAll("zig_");1016 if (location == .static_initializer) {
1171 try w.writeAll(if (location == .StaticInitializer) "init" else "make");1017 try w.writeAll("zig_init_special_");
1172 try w.writeAll("_special_");1018 } else {
1019 try w.writeAll("zig_make_special_");
1020 }
1173 try dg.renderTypeForBuiltinFnName(w, ty);1021 try dg.renderTypeForBuiltinFnName(w, ty);
1174 try w.writeByte('(');1022 try w.writeByte('(');
1175 if (std.math.signbit(f128_val)) try w.writeByte('-');1023 if (std.math.signbit(f128_val)) try w.writeByte('-');
...@@ -1196,105 +1044,85 @@ pub const DeclGen = struct {...@@ -1196,105 +1044,85 @@ pub const DeclGen = struct {
1196 if (!empty) try w.writeByte(')');1044 if (!empty) try w.writeByte(')');
1197 },1045 },
1198 .slice => |slice| {1046 .slice => |slice| {
1199 const aggregate = ctype.info(ctype_pool).aggregate;
1200 if (!location.isInitializer()) {1047 if (!location.isInitializer()) {
1201 try w.writeByte('(');1048 try w.writeByte('(');
1202 try dg.renderCType(w, ctype);1049 try dg.renderType(w, ty);
1203 try w.writeByte(')');1050 try w.writeByte(')');
1204 }1051 }
1205 try w.writeByte('{');1052 try w.writeByte('{');
1206 for (0..aggregate.fields.len) |field_index| {1053 try dg.renderValue(w, .fromInterned(slice.ptr), initializer_type);
1207 if (field_index > 0) try w.writeByte(',');1054 try w.writeByte(',');
1208 try dg.renderValue(w, Value.fromInterned(1055 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);
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 }
1216 try w.writeByte('}');1056 try w.writeByte('}');
1217 },1057 },
1218 .ptr => {1058 .ptr => {
1219 var arena = std.heap.ArenaAllocator.init(zcu.gpa);1059 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1220 defer arena.deinit();1060 try w.writeByte('(');
1221 const derivation = try val.pointerDerivation(arena.allocator(), pt);
1222 try dg.renderPointer(w, derivation, location);1061 try dg.renderPointer(w, derivation, location);
1062 try w.writeByte(')');
1223 },1063 },
1224 .opt => |opt| switch (ctype.info(ctype_pool)) {1064 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {
1225 .basic => if (ctype.isBool()) try w.writeAll(switch (opt.val) {1065 .npv_payload => unreachable, // opv optional
1226 .none => "true",1066 .opv_payload => {
1227 else => "false",1067 if (!location.isInitializer()) {
1228 }) else switch (opt.val) {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) {
1229 .none => try w.writeByte('0'),1078 .none => try w.writeByte('0'),
1230 else => |payload| switch (ip.indexToKey(payload)) {1079 else => |payload_val| try dg.renderValue(w, .fromInterned(payload_val), location),
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 },
1239 },1080 },
1240 .pointer => switch (opt.val) {1081 .ptr_like => switch (opt.val) {
1241 .none => try w.writeAll("NULL"),1082 .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),
1243 },1084 },
1244 .aligned, .array, .vector, .fwd_decl, .function => unreachable,1085 .slice_like => switch (opt.val) {
1245 .aggregate => |aggregate| {1086 .none => {
1246 switch (opt.val) {1087 if (!location.isInitializer()) {
1247 .none => {},1088 try w.writeByte('(');
1248 else => |payload| switch (aggregate.fields.at(0, ctype_pool).name.index) {1089 try dg.renderType(w, ty);
1249 .is_null, .payload => {},1090 try w.writeByte(')');
1250 .ptr, .len => return dg.renderValue(1091 }
1251 w,1092 try w.writeAll("{NULL,");
1252 Value.fromInterned(payload),1093 try dg.renderUndefValue(w, .usize, initializer_type);
1253 location,1094 try w.writeByte('}');
1254 ),1095 },
1255 else => unreachable,1096 else => |payload_val| try dg.renderValue(w, .fromInterned(payload_val), location),
1256 },1097 },
1257 }1098 .@"struct" => {
1258 if (!location.isInitializer()) {1099 if (!location.isInitializer()) {
1259 try w.writeByte('(');1100 try w.writeByte('(');
1260 try dg.renderCType(w, ctype);1101 try dg.renderType(w, ty);
1261 try w.writeByte(')');1102 try w.writeByte(')');
1262 }1103 }
1263 try w.writeByte('{');1104 switch (opt.val) {
1264 for (0..aggregate.fields.len) |field_index| {1105 .none => {
1265 if (field_index > 0) try w.writeByte(',');1106 try w.writeAll("{ .is_null = true, .payload = ");
1266 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1107 try dg.renderUndefValue(w, ty.optionalChild(zcu), initializer_type);
1267 .is_null => try w.writeAll(switch (opt.val) {1108 try w.writeAll(" }");
1268 .none => "true",1109 },
1269 else => "false",1110 else => |payload_val| {
1270 }),1111 try w.writeAll("{ .is_null = false, .payload = ");
1271 .payload => switch (opt.val) {1112 try dg.renderValue(w, .fromInterned(payload_val), initializer_type);
1272 .none => try dg.renderUndefValue(1113 try w.writeAll(" }");
1273 w,1114 },
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 }
1287 }1115 }
1288 try w.writeByte('}');
1289 },1116 },
1290 },1117 },
1291 .aggregate => switch (ip.indexToKey(ty.toIntern())) {1118 .aggregate => switch (ip.indexToKey(ty.toIntern())) {
1292 .array_type, .vector_type => {1119 .array_type, .vector_type => {
1293 if (location == .FunctionArgument) {1120 if (!location.isInitializer()) {
1294 try w.writeByte('(');1121 try w.writeByte('(');
1295 try dg.renderCType(w, ctype);1122 try dg.renderType(w, ty);
1296 try w.writeByte(')');1123 try w.writeByte(')');
1297 }1124 }
1125 try w.writeByte('{');
1298 const ai = ty.arrayInfo(zcu);1126 const ai = ty.arrayInfo(zcu);
1299 if (ai.elem_type.eql(.u8, zcu)) {1127 if (ai.elem_type.eql(.u8, zcu)) {
1300 var literal: StringLiteral = .init(w, @intCast(ty.arrayLenIncludingSentinel(zcu)));1128 var literal: StringLiteral = .init(w, @intCast(ty.arrayLenIncludingSentinel(zcu)));
...@@ -1327,11 +1155,12 @@ pub const DeclGen = struct {...@@ -1327,11 +1155,12 @@ pub const DeclGen = struct {
1327 }1155 }
1328 try w.writeByte('}');1156 try w.writeByte('}');
1329 }1157 }
1158 try w.writeByte('}');
1330 },1159 },
1331 .tuple_type => |tuple| {1160 .tuple_type => |tuple| {
1332 if (!location.isInitializer()) {1161 if (!location.isInitializer()) {
1333 try w.writeByte('(');1162 try w.writeByte('(');
1334 try dg.renderCType(w, ctype);1163 try dg.renderType(w, ty);
1335 try w.writeByte(')');1164 try w.writeByte(')');
1336 }1165 }
13371166
...@@ -1341,7 +1170,7 @@ pub const DeclGen = struct {...@@ -1341,7 +1170,7 @@ pub const DeclGen = struct {
1341 const comptime_val = tuple.values.get(ip)[field_index];1170 const comptime_val = tuple.values.get(ip)[field_index];
1342 if (comptime_val != .none) continue;1171 if (comptime_val != .none) continue;
1343 const field_ty: Type = .fromInterned(tuple.types.get(ip)[field_index]);1172 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
1346 if (!empty) try w.writeByte(',');1175 if (!empty) try w.writeByte(',');
13471176
...@@ -1363,139 +1192,95 @@ pub const DeclGen = struct {...@@ -1363,139 +1192,95 @@ pub const DeclGen = struct {
1363 },1192 },
1364 .struct_type => {1193 .struct_type => {
1365 const loaded_struct = ip.loadStructType(ty.toIntern());1194 const loaded_struct = ip.loadStructType(ty.toIntern());
1366 switch (loaded_struct.layout) {1195 assert(loaded_struct.layout != .@"packed");
1367 .auto, .@"extern" => {
1368 if (!location.isInitializer()) {
1369 try w.writeByte('(');
1370 try dg.renderCType(w, ctype);
1371 try w.writeByte(')');
1372 }
13731196
1374 try w.writeByte('{');1197 if (!location.isInitializer()) {
1375 var field_it = loaded_struct.iterateRuntimeOrder(ip);1198 try w.writeByte('(');
1376 var need_comma = false;1199 try dg.renderType(w, ty);
1377 while (field_it.next()) |field_index| {1200 try w.writeByte(')');
1378 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);1201 }
1379 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
13801202
1381 if (need_comma) try w.writeByte(',');1203 try w.writeByte('{');
1382 need_comma = true;1204 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1383 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1205 var need_comma = false;
1384 .bytes => |bytes| try pt.intern(.{ .int = .{1206 while (field_it.next()) |field_index| {
1385 .ty = field_ty.toIntern(),1207 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1386 .storage = .{ .u64 = bytes.at(field_index, ip) },1208 if (!field_ty.hasRuntimeBits(zcu)) continue;
1387 } }),1209
1388 .elems => |elems| elems[field_index],1210 if (need_comma) try w.writeByte(',');
1389 .repeated_elem => |elem| elem,1211 need_comma = true;
1390 };1212 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1391 try dg.renderValue(w, Value.fromInterned(field_val), initializer_type);1213 .bytes => |bytes| try pt.intern(.{ .int = .{
1392 }1214 .ty = field_ty.toIntern(),
1393 try w.writeByte('}');1215 .storage = .{ .u64 = bytes.at(field_index, ip) },
1394 },1216 } }),
1395 .@"packed" => {1217 .elems => |elems| elems[field_index],
1396 // https://github.com/ziglang/zig/issues/24657 will eliminate most of the1218 .repeated_elem => |elem| elem,
1397 // following logic, leaving only the recursive `renderValue` call. Once1219 };
1398 // that proposal is implemented, a `packed struct` will literally be1220 try dg.renderValue(w, Value.fromInterned(field_val), initializer_type);
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 },
1412 }1221 }
1222 try w.writeByte('}');
1413 },1223 },
1414 else => unreachable,1224 else => unreachable,
1415 },1225 },
1226 .bitpack => |bitpack| return dg.renderValue(w, .fromInterned(bitpack.backing_int_val), location),
1416 .un => |un| {1227 .un => |un| {
1417 const loaded_union = ip.loadUnionType(ty.toIntern());1228 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 }
1435 if (un.tag == .none) {1229 if (un.tag == .none) {
1436 const backing_ty = try ty.unionBackingType(pt);1230 assert(loaded_union.layout == .@"extern");
1437 assert(loaded_union.flagsUnordered(ip).layout == .@"extern");1231 if (location == .static_initializer) {
1438 if (location == .StaticInitializer) {
1439 return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});1232 return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});
1440 }1233 }
14411234
1442 const ptr_ty = try pt.singleConstPtrType(ty);1235 const ptr_ty = try pt.singleConstPtrType(ty);
1443 try w.writeAll("*((");1236 try w.writeAll("*(");
1444 try dg.renderType(w, ptr_ty);1237 try dg.renderType(w, ptr_ty);
1445 try w.writeAll(")(");1238 try w.writeAll(")&");
1446 try dg.renderType(w, backing_ty);1239 // We need an lvalue for '&'.
1447 try w.writeAll("){");1240 try dg.renderValueAsLvalue(w, .fromInterned(un.val));
1448 try dg.renderValue(w, Value.fromInterned(un.val), location);
1449 try w.writeAll("})");
1450 } else {1241 } else {
1451 if (!location.isInitializer()) {1242 if (!location.isInitializer()) {
1452 try w.writeByte('(');1243 try w.writeByte('(');
1453 try dg.renderCType(w, ctype);1244 try dg.renderType(w, ty);
1454 try w.writeByte(')');1245 try w.writeByte(')');
1455 }1246 }
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)).?;1255 if (loaded_union.layout == .auto) try w.writeByte('{');
1458 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);1256
1459 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];1257 if (loaded_union.has_runtime_tag) {
14601258 try w.writeAll(" .tag = ");
1461 const has_tag = loaded_union.hasTag(ip);1259 try dg.renderValue(w, .fromInterned(un.tag), initializer_type);
1462 if (has_tag) try w.writeByte('{');1260 try w.writeAll(", .payload = ");
1463 const aggregate = ctype.info(ctype_pool).aggregate;1261 }
1464 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {1262
1465 if (outer_field_index > 0) try w.writeByte(',');1263 const enum_tag_ty: Type = .fromInterned(loaded_union.enum_tag_type);
1466 switch (if (has_tag)1264 const active_field_index = enum_tag_ty.enumTagFieldIndex(.fromInterned(un.tag), zcu).?;
1467 aggregate.fields.at(outer_field_index, ctype_pool).name.index1265 const active_field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[active_field_index]);
1468 else1266 if (active_field_ty.hasRuntimeBits(zcu)) {
1469 .payload) {1267 const active_field_name = enum_tag_ty.enumFieldName(active_field_index, zcu);
1470 .tag => try dg.renderValue(1268 try w.print("{{ .{f} = ", .{fmtIdentSolo(active_field_name.toSlice(ip))});
1471 w,1269 try dg.renderValue(w, .fromInterned(un.val), initializer_type);
1472 Value.fromInterned(un.tag),1270 try w.writeAll(" }");
1473 initializer_type,1271 } else {
1474 ),1272 const first_field_ty: Type = for (loaded_union.field_types.get(ip)) |field_ty_ip| {
1475 .payload => {1273 const field_ty: Type = .fromInterned(field_ty_ip);
1476 try w.writeByte('{');1274 if (!field_ty.hasRuntimeBits(pt.zcu)) continue;
1477 if (field_ty.hasRuntimeBits(zcu)) {1275 break field_ty;
1478 try w.print(" .{f} = ", .{fmtIdentSolo(field_name.toSlice(ip))});1276 } else unreachable;
1479 try dg.renderValue(1277 try w.writeByte('{');
1480 w,1278 try dg.renderUndefValue(w, first_field_ty, initializer_type);
1481 Value.fromInterned(un.val),1279 try w.writeByte('}');
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 }
1497 }1280 }
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('}');
1499 }1284 }
1500 },1285 },
1501 }1286 }
...@@ -1511,11 +1296,10 @@ pub const DeclGen = struct {...@@ -1511,11 +1296,10 @@ pub const DeclGen = struct {
1511 const zcu = pt.zcu;1296 const zcu = pt.zcu;
1512 const ip = &zcu.intern_pool;1297 const ip = &zcu.intern_pool;
1513 const target = &dg.mod.resolved_target.result;1298 const target = &dg.mod.resolved_target.result;
1514 const ctype_pool = &dg.ctype_pool;
15151299
1516 const initializer_type: ValueRenderLocation = switch (location) {1300 const initializer_type: ValueRenderLocation = switch (location) {
1517 .StaticInitializer => .StaticInitializer,1301 .static_initializer => .static_initializer,
1518 else => .Initializer,1302 else => .initializer,
1519 };1303 };
15201304
1521 const safety_on = switch (zcu.optimizeMode()) {1305 const safety_on = switch (zcu.optimizeMode()) {
...@@ -1523,7 +1307,6 @@ pub const DeclGen = struct {...@@ -1523,7 +1307,6 @@ pub const DeclGen = struct {
1523 .ReleaseFast, .ReleaseSmall => false,1307 .ReleaseFast, .ReleaseSmall => false,
1524 };1308 };
15251309
1526 const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());
1527 switch (ty.toIntern()) {1310 switch (ty.toIntern()) {
1528 .c_longdouble_type,1311 .c_longdouble_type,
1529 .f16_type,1312 .f16_type,
...@@ -1548,76 +1331,109 @@ pub const DeclGen = struct {...@@ -1548,76 +1331,109 @@ pub const DeclGen = struct {
1548 else => unreachable,1331 else => unreachable,
1549 }1332 }
1550 try w.writeAll(", ");1333 try w.writeAll(", ");
1551 try dg.renderUndefValue(w, repr_ty, .FunctionArgument);1334 try dg.renderUndefValue(w, repr_ty, .other);
1552 return w.writeByte(')');1335 return w.writeByte(')');
1553 },1336 },
1554 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),1337 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),
1555 else => switch (ip.indexToKey(ty.toIntern())) {1338 else => switch (ip.indexToKey(ty.toIntern())) {
1556 .simple_type,1339 .simple_type, // anyerror, c_char (etc), usize, isize
1557 .int_type,1340 .int_type,
1558 .enum_type,1341 .enum_type,
1559 .error_set_type,1342 .error_set_type,
1560 .inferred_error_set_type,1343 .inferred_error_set_type,
1561 => return w.print("{f}", .{1344 => switch (CType.classifyInt(ty, zcu)) {
1562 try dg.fmtIntLiteralHex(try pt.undefValue(ty), location),1345 .void => unreachable, // opv
1563 }),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 },
1564 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1387 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1565 .one, .many, .c => {1388 .one, .many, .c => {
1566 try w.writeAll("((");1389 try w.writeAll("((");
1567 try dg.renderCType(w, ctype);1390 try dg.renderType(w, ty);
1568 return w.print("){f})", .{1391 try w.writeByte(')');
1569 try dg.fmtIntLiteralHex(.undef_usize, .Other),1392 try dg.renderUndefValue(w, .usize, location);
1570 });1393 try w.writeByte(')');
1571 },1394 },
1572 .slice => {1395 .slice => {
1573 if (!location.isInitializer()) {1396 if (!location.isInitializer()) {
1574 try w.writeByte('(');1397 try w.writeByte('(');
1575 try dg.renderCType(w, ctype);1398 try dg.renderType(w, ty);
1576 try w.writeByte(')');1399 try w.writeByte(')');
1577 }1400 }
15781401
1579 try w.writeAll("{(");1402 try w.writeByte('{');
1580 const ptr_ty = ty.slicePtrFieldType(zcu);1403 try dg.renderUndefValue(w, ty.slicePtrFieldType(zcu), initializer_type);
1581 try dg.renderType(w, ptr_ty);1404 try w.writeByte(',');
1582 return w.print("){f}, {0f}}}", .{1405 try dg.renderUndefValue(w, .usize, initializer_type);
1583 try dg.fmtIntLiteralHex(.undef_usize, .Other),1406 try w.writeByte('}');
1584 });
1585 },1407 },
1586 },1408 },
1587 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {1409 .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) {
1588 .basic, .pointer => try dg.renderUndefValue(1410 .npv_payload => unreachable, // opv optional
1589 w,1411
1590 .fromInterned(if (ctype.isBool()) .bool_type else child_type),1412 .error_set,
1591 location,1413 .ptr_like,
1592 ),1414 .slice_like,
1593 .aligned, .array, .vector, .fwd_decl, .function => unreachable,1415 => try dg.renderUndefValue(w, .fromInterned(child_type), location),
1594 .aggregate => |aggregate| {1416
1595 switch (aggregate.fields.at(0, ctype_pool).name.index) {1417 .opv_payload => {
1596 .is_null, .payload => {},
1597 .ptr, .len => return dg.renderUndefValue(
1598 w,
1599 .fromInterned(child_type),
1600 location,
1601 ),
1602 else => unreachable,
1603 }
1604 if (!location.isInitializer()) {1418 if (!location.isInitializer()) {
1605 try w.writeByte('(');1419 try w.writeByte('(');
1606 try dg.renderCType(w, ctype);1420 try dg.renderType(w, ty);
1607 try w.writeByte(')');1421 try w.writeByte(')');
1608 }1422 }
1609 try w.writeByte('{');1423 try w.writeAll(if (safety_on) "{.is_null=0xaa}" else "{.is_null=false}");
1610 for (0..aggregate.fields.len) |field_index| {1424 },
1611 if (field_index > 0) try w.writeByte(',');1425
1612 try dg.renderUndefValue(w, .fromInterned(1426 .@"struct" => {
1613 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1427 if (!location.isInitializer()) {
1614 .is_null => .bool_type,1428 try w.writeByte('(');
1615 .payload => child_type,1429 try dg.renderType(w, ty);
1616 else => unreachable,1430 try w.writeByte(')');
1617 },
1618 ), initializer_type);
1619 }1431 }
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(" }");
1621 },1437 },
1622 },1438 },
1623 .struct_type => {1439 .struct_type => {
...@@ -1626,16 +1442,15 @@ pub const DeclGen = struct {...@@ -1626,16 +1442,15 @@ pub const DeclGen = struct {
1626 .auto, .@"extern" => {1442 .auto, .@"extern" => {
1627 if (!location.isInitializer()) {1443 if (!location.isInitializer()) {
1628 try w.writeByte('(');1444 try w.writeByte('(');
1629 try dg.renderCType(w, ctype);1445 try dg.renderType(w, ty);
1630 try w.writeByte(')');1446 try w.writeByte(')');
1631 }1447 }
1632
1633 try w.writeByte('{');1448 try w.writeByte('{');
1634 var field_it = loaded_struct.iterateRuntimeOrder(ip);1449 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1635 var need_comma = false;1450 var need_comma = false;
1636 while (field_it.next()) |field_index| {1451 while (field_it.next()) |field_index| {
1637 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);1452 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
1640 if (need_comma) try w.writeByte(',');1455 if (need_comma) try w.writeByte(',');
1641 need_comma = true;1456 need_comma = true;
...@@ -1643,17 +1458,13 @@ pub const DeclGen = struct {...@@ -1643,17 +1458,13 @@ pub const DeclGen = struct {
1643 }1458 }
1644 return w.writeByte('}');1459 return w.writeByte('}');
1645 },1460 },
1646 .@"packed" => return dg.renderUndefValue(1461 .@"packed" => return dg.renderUndefValue(w, ty.bitpackBackingInt(zcu), location),
1647 w,
1648 .fromInterned(loaded_struct.backingIntTypeUnordered(ip)),
1649 location,
1650 ),
1651 }1462 }
1652 },1463 },
1653 .tuple_type => |tuple_info| {1464 .tuple_type => |tuple_info| {
1654 if (!location.isInitializer()) {1465 if (!location.isInitializer()) {
1655 try w.writeByte('(');1466 try w.writeByte('(');
1656 try dg.renderCType(w, ctype);1467 try dg.renderType(w, ty);
1657 try w.writeByte(')');1468 try w.writeByte(')');
1658 }1469 }
16591470
...@@ -1662,7 +1473,7 @@ pub const DeclGen = struct {...@@ -1662,7 +1473,7 @@ pub const DeclGen = struct {
1662 for (0..tuple_info.types.len) |field_index| {1473 for (0..tuple_info.types.len) |field_index| {
1663 if (tuple_info.values.get(ip)[field_index] != .none) continue;1474 if (tuple_info.values.get(ip)[field_index] != .none) continue;
1664 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);1475 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
1667 if (need_comma) try w.writeByte(',');1478 if (need_comma) try w.writeByte(',');
1668 need_comma = true;1479 need_comma = true;
...@@ -1672,88 +1483,65 @@ pub const DeclGen = struct {...@@ -1672,88 +1483,65 @@ pub const DeclGen = struct {
1672 },1483 },
1673 .union_type => {1484 .union_type => {
1674 const loaded_union = ip.loadUnionType(ty.toIntern());1485 const loaded_union = ip.loadUnionType(ty.toIntern());
1675 switch (loaded_union.flagsUnordered(ip).layout) {1486 switch (loaded_union.layout) {
1676 .auto, .@"extern" => {1487 .auto, .@"extern" => {
1677 if (!location.isInitializer()) {1488 if (!location.isInitializer()) {
1678 try w.writeByte('(');1489 try w.writeByte('(');
1679 try dg.renderCType(w, ctype);1490 try dg.renderType(w, ty);
1680 try w.writeByte(')');1491 try w.writeByte(')');
1681 }1492 }
16821493
1683 const has_tag = loaded_union.hasTag(ip);1494 const first_field_ty: Type = for (loaded_union.field_types.get(ip)) |field_ty_ip| {
1684 if (has_tag) try w.writeByte('{');1495 const field_ty: Type = .fromInterned(field_ty_ip);
1685 const aggregate = ctype.info(ctype_pool).aggregate;1496 if (!field_ty.hasRuntimeBits(pt.zcu)) continue;
1686 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {1497 break field_ty;
1687 if (outer_field_index > 0) try w.writeByte(',');1498 } else {
1688 switch (if (has_tag)1499 assert(loaded_union.has_runtime_tag); // otherwise it does not have runtime bits
1689 aggregate.fields.at(outer_field_index, ctype_pool).name.index1500 try w.writeAll("{ .tag = ");
1690 else1501 try dg.renderUndefValue(w, .fromInterned(loaded_union.enum_tag_type), initializer_type);
1691 .payload) {1502 try w.writeAll(" }");
1692 .tag => try dg.renderUndefValue(1503 return;
1693 w,1504 };
1694 .fromInterned(loaded_union.enum_tag_ty),1505
1695 initializer_type,1506 if (loaded_union.layout == .auto) try w.writeByte('{');
1696 ),1507
1697 .payload => {1508 if (loaded_union.has_runtime_tag) {
1698 try w.writeByte('{');1509 try w.writeAll(" .tag = ");
1699 for (0..loaded_union.field_types.len) |inner_field_index| {1510 try dg.renderUndefValue(w, .fromInterned(loaded_union.enum_tag_type), initializer_type);
1700 const inner_field_ty: Type = .fromInterned(1511 try w.writeAll(", .payload = ");
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 }
1715 }1512 }
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('}');
1717 },1520 },
1718 .@"packed" => return dg.renderUndefValue(1521 .@"packed" => return dg.renderUndefValue(w, ty.bitpackBackingInt(zcu), location),
1719 w,
1720 try ty.unionBackingType(pt),
1721 location,
1722 ),
1723 }1522 }
1724 },1523 },
1725 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {1524 .error_union_type => |error_union| {
1726 .basic => try dg.renderUndefValue(1525 if (!location.isInitializer()) {
1727 w,1526 try w.writeByte('(');
1728 .fromInterned(error_union_type.error_set_type),1527 try dg.renderType(w, ty);
1729 location,1528 try w.writeByte(')');
1730 ),1529 }
1731 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,1530 try w.writeAll("{ .error = ");
1732 .aggregate => |aggregate| {1531 try dg.renderUndefValue(w, .fromInterned(error_union.error_set_type), initializer_type);
1733 if (!location.isInitializer()) {1532 if (Type.fromInterned(error_union.payload_type).hasRuntimeBits(zcu)) {
1734 try w.writeByte('(');1533 try w.writeAll(", .payload = ");
1735 try dg.renderCType(w, ctype);1534 try dg.renderUndefValue(w, .fromInterned(error_union.payload_type), initializer_type);
1736 try w.writeByte(')');1535 }
1737 }1536 try w.writeAll(" }");
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 },
1755 },1537 },
1756 .array_type, .vector_type => {1538 .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('{');
1757 const ai = ty.arrayInfo(zcu);1545 const ai = ty.arrayInfo(zcu);
1758 if (ai.elem_type.eql(.u8, zcu)) {1546 if (ai.elem_type.eql(.u8, zcu)) {
1759 var literal: StringLiteral = .init(w, @intCast(ty.arrayLenIncludingSentinel(zcu)));1547 var literal: StringLiteral = .init(w, @intCast(ty.arrayLenIncludingSentinel(zcu)));
...@@ -1764,14 +1552,8 @@ pub const DeclGen = struct {...@@ -1764,14 +1552,8 @@ pub const DeclGen = struct {
1764 const s_u8: u8 = @intCast(s.toUnsignedInt(zcu));1552 const s_u8: u8 = @intCast(s.toUnsignedInt(zcu));
1765 if (s_u8 != 0) try literal.writeChar(s_u8);1553 if (s_u8 != 0) try literal.writeChar(s_u8);
1766 }1554 }
1767 return literal.end();1555 try literal.end();
1768 } else {1556 } else {
1769 if (!location.isInitializer()) {
1770 try w.writeByte('(');
1771 try dg.renderCType(w, ctype);
1772 try w.writeByte(')');
1773 }
1774
1775 try w.writeByte('{');1557 try w.writeByte('{');
1776 var index: u64 = 0;1558 var index: u64 = 0;
1777 while (index < ai.len) : (index += 1) {1559 while (index < ai.len) : (index += 1) {
...@@ -1782,8 +1564,9 @@ pub const DeclGen = struct {...@@ -1782,8 +1564,9 @@ pub const DeclGen = struct {
1782 if (index > 0) try w.writeAll(", ");1564 if (index > 0) try w.writeAll(", ");
1783 try dg.renderValue(w, s, location);1565 try dg.renderValue(w, s, location);
1784 }1566 }
1785 return w.writeByte('}');1567 try w.writeByte('}');
1786 }1568 }
1569 try w.writeByte('}');
1787 },1570 },
1788 .anyframe_type,1571 .anyframe_type,
1789 .opaque_type,1572 .opaque_type,
...@@ -1800,13 +1583,13 @@ pub const DeclGen = struct {...@@ -1800,13 +1583,13 @@ pub const DeclGen = struct {
1800 .error_union,1583 .error_union,
1801 .enum_literal,1584 .enum_literal,
1802 .enum_tag,1585 .enum_tag,
1803 .empty_enum_value,
1804 .float,1586 .float,
1805 .ptr,1587 .ptr,
1806 .slice,1588 .slice,
1807 .opt,1589 .opt,
1808 .aggregate,1590 .aggregate,
1809 .un,1591 .un,
1592 .bitpack,
1810 .memoized_call,1593 .memoized_call,
1811 => unreachable, // values, not types1594 => unreachable, // values, not types
1812 },1595 },
...@@ -1818,10 +1601,11 @@ pub const DeclGen = struct {...@@ -1818,10 +1601,11 @@ pub const DeclGen = struct {
1818 w: *Writer,1601 w: *Writer,
1819 fn_val: Value,1602 fn_val: Value,
1820 fn_align: InternPool.Alignment,1603 fn_align: InternPool.Alignment,
1821 kind: CType.Kind,1604 kind: enum { forward_decl, definition },
1822 name: union(enum) {1605 name: union(enum) {
1823 nav: InternPool.Nav.Index,1606 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,
1825 @"export": struct {1609 @"export": struct {
1826 main_name: InternPool.NullTerminatedString,1610 main_name: InternPool.NullTerminatedString,
1827 extern_name: InternPool.NullTerminatedString,1611 extern_name: InternPool.NullTerminatedString,
...@@ -1832,14 +1616,12 @@ pub const DeclGen = struct {...@@ -1832,14 +1616,12 @@ pub const DeclGen = struct {
1832 const ip = &zcu.intern_pool;1616 const ip = &zcu.intern_pool;
18331617
1834 const fn_ty = fn_val.typeOf(zcu);1618 const fn_ty = fn_val.typeOf(zcu);
1835 const fn_ctype = try dg.ctypeFromType(fn_ty, kind);
18361619
1837 const fn_info = zcu.typeToFunc(fn_ty).?;1620 const fn_info = zcu.typeToFunc(fn_ty).?;
1838 if (fn_info.cc == .naked) {1621 if (fn_info.cc == .naked) {
1839 switch (kind) {1622 switch (kind) {
1840 .forward => try w.writeAll("zig_naked_decl "),1623 .forward_decl => try w.writeAll("zig_naked_decl "),
1841 .complete => try w.writeAll("zig_naked "),1624 .definition => try w.writeAll("zig_naked "),
1842 else => unreachable,
1843 }1625 }
1844 }1626 }
18451627
...@@ -1849,45 +1631,63 @@ pub const DeclGen = struct {...@@ -1849,45 +1631,63 @@ pub const DeclGen = struct {
1849 if (func_analysis.branch_hint == .cold)1631 if (func_analysis.branch_hint == .cold)
1850 try w.writeAll("zig_cold ");1632 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)
1853 try w.writeAll("zig_no_builtin ");1635 try w.writeAll("zig_no_builtin ");
1854 }1636 }
18551637
1856 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");1638 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)});
1860 if (toCallingConvention(fn_info.cc, zcu)) |call_conv| {1651 if (toCallingConvention(fn_info.cc, zcu)) |call_conv| {
1861 try w.print("{f}zig_callconv({s})", .{ trailing, call_conv });1652 try w.print("zig_callconv({s}) ", .{call_conv});
1862 trailing = .maybe_space;
1863 }1653 }
1864
1865 try w.print("{f}", .{trailing});
1866 switch (name) {1654 switch (name) {
1867 .nav => |nav| try dg.renderNavName(w, nav),1655 .nav => |nav| try renderNavName(w, nav, ip),
1868 .fmt_ctype_pool_string => |fmt| try w.print("{f}", .{fmt}),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 }),
1869 .@"export" => |@"export"| try w.print("{f}", .{fmtIdentSolo(@"export".extern_name.toSlice(ip))}),1662 .@"export" => |@"export"| try w.print("{f}", .{fmtIdentSolo(@"export".extern_name.toSlice(ip))}),
1870 }1663 }
18711664 {
1872 try renderTypeSuffix(1665 try w.writeByte('(');
1873 dg.pass,1666 var c_param_index: u32 = 0;
1874 &dg.ctype_pool,1667 for (fn_info.param_types.get(ip)) |param_ty_ip| {
1875 zcu,1668 const param_ty: Type = .fromInterned(param_ty_ip);
1876 w,1669 if (!param_ty.hasRuntimeBits(zcu)) continue;
1877 fn_ctype,1670 if (c_param_index != 0) try w.writeAll(", ");
1878 .suffix,1671 try dg.renderTypeAndName(w, param_ty, .{ .arg = c_param_index }, .{
1879 CQualifiers.init(.{ .@"const" = switch (kind) {1672 .@"const" = kind == .definition,
1880 .forward => false,1673 }, .none);
1881 .complete => true,1674 c_param_index += 1;
1882 else => unreachable,1675 }
1883 } }),1676 if (fn_info.is_var_args) {
1884 );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
1886 switch (kind) {1686 switch (kind) {
1887 .forward => {1687 .forward_decl => {
1888 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});1688 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});
1889 switch (name) {1689 switch (name) {
1890 .nav, .fmt_ctype_pool_string => {},1690 .nav, .nav_never_tail, .nav_never_inline => {},
1891 .@"export" => |@"export"| {1691 .@"export" => |@"export"| {
1892 const extern_name = @"export".extern_name.toSlice(ip);1692 const extern_name = @"export".extern_name.toSlice(ip);
1893 const is_mangled = isMangledIdent(extern_name, true);1693 const is_mangled = isMangledIdent(extern_name, true);
...@@ -1911,38 +1711,16 @@ pub const DeclGen = struct {...@@ -1911,38 +1711,16 @@ pub const DeclGen = struct {
1911 },1711 },
1912 }1712 }
1913 },1713 },
1914 .complete => {},1714 .definition => {},
1915 else => unreachable,
1916 }1715 }
1917 }1716 }
19181717
1919 fn ctypeFromType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType {1718 /// Renders the C lowering of the given Zig type to `w`. This renders the type name---to render
1920 defer std.debug.assert(dg.scratch.items.len == 0);1719 /// a declarator with this type, see instead `renderTypeAndName`.
1921 return dg.ctype_pool.fromType(dg.gpa, &dg.scratch, ty, dg.pt, dg.mod, kind);1720 fn renderType(dg: *DeclGen, w: *Writer, ty: Type) (Writer.Error || Allocator.Error)!void {
1922 }1721 const zcu = dg.pt.zcu;
19231722 const cty: CType = try .lower(ty, &dg.ctype_deps, dg.arena, zcu);
1924 fn byteSize(dg: *DeclGen, ctype: CType) u64 {1723 try w.print("{f}", .{cty.fmtTypeName(zcu)});
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, .{});
1946 }1724 }
19471725
1948 const IntCastContext = union(enum) {1726 const IntCastContext = union(enum) {
...@@ -2046,7 +1824,7 @@ pub const DeclGen = struct {...@@ -2046,7 +1824,7 @@ pub const DeclGen = struct {
2046 try w.writeAll("zig_lo_");1824 try w.writeAll("zig_lo_");
2047 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);1825 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
2048 try w.writeByte('(');1826 try w.writeByte('(');
2049 try context.writeValue(dg, w, .FunctionArgument);1827 try context.writeValue(dg, w, .other);
2050 try w.writeByte(')');1828 try w.writeByte(')');
2051 } else if (dest_bits > 64 and src_bits <= 64) {1829 } else if (dest_bits > 64 and src_bits <= 64) {
2052 try w.writeAll("zig_make_");1830 try w.writeAll("zig_make_");
...@@ -2057,7 +1835,7 @@ pub const DeclGen = struct {...@@ -2057,7 +1835,7 @@ pub const DeclGen = struct {
2057 try dg.renderType(w, src_eff_ty);1835 try dg.renderType(w, src_eff_ty);
2058 try w.writeByte(')');1836 try w.writeByte(')');
2059 }1837 }
2060 try context.writeValue(dg, w, .FunctionArgument);1838 try context.writeValue(dg, w, .other);
2061 try w.writeByte(')');1839 try w.writeByte(')');
2062 } else {1840 } else {
2063 assert(!src_is_ptr);1841 assert(!src_is_ptr);
...@@ -2066,23 +1844,16 @@ pub const DeclGen = struct {...@@ -2066,23 +1844,16 @@ pub const DeclGen = struct {
2066 try w.writeAll("(zig_hi_");1844 try w.writeAll("(zig_hi_");
2067 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);1845 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
2068 try w.writeByte('(');1846 try w.writeByte('(');
2069 try context.writeValue(dg, w, .FunctionArgument);1847 try context.writeValue(dg, w, .other);
2070 try w.writeAll("), zig_lo_");1848 try w.writeAll("), zig_lo_");
2071 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);1849 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
2072 try w.writeByte('(');1850 try w.writeByte('(');
2073 try context.writeValue(dg, w, .FunctionArgument);1851 try context.writeValue(dg, w, .other);
2074 try w.writeAll("))");1852 try w.writeAll("))");
2075 }1853 }
2076 }1854 }
20771855
2078 /// Renders a type and name in field declaration/definition format.1856 /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type.
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 ///
2086 fn renderTypeAndName(1857 fn renderTypeAndName(
2087 dg: *DeclGen,1858 dg: *DeclGen,
2088 w: *Writer,1859 w: *Writer,
...@@ -2090,73 +1861,47 @@ pub const DeclGen = struct {...@@ -2090,73 +1861,47 @@ pub const DeclGen = struct {
2090 name: CValue,1861 name: CValue,
2091 qualifiers: CQualifiers,1862 qualifiers: CQualifiers,
2092 alignment: Alignment,1863 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,
2114 ) !void {1864 ) !void {
2115 const zcu = dg.pt.zcu;1865 const zcu = dg.pt.zcu;
2116 switch (alignas.abiOrder()) {1866 const ip = &zcu.intern_pool;
2117 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),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().?}),
2118 .eq => {},1871 .eq => {},
2119 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),1872 .gt => try w.print("zig_align({d}) ", .{alignment.toByteUnits().?}),
2120 }1873 };
21211874 if (qualifiers.@"const") try w.writeAll("const ");
2122 try w.print("{f}", .{1875 if (qualifiers.@"volatile") try w.writeAll("volatile ");
2123 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, qualifiers),1876 if (qualifiers.restrict) try w.writeAll("restrict ");
2124 });1877 switch (name) {
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) {
2132 .new_local, .local => |i| try w.print("t{d}", .{i}),1878 .new_local, .local => |i| try w.print("t{d}", .{i}),
1879 .arg => |i| try w.print("a{d}", .{i}),
2133 .constant => |uav| try renderUavName(w, uav),1880 .constant => |uav| try renderUavName(w, uav),
2134 .nav => |nav| try dg.renderNavName(w, nav),1881 .nav => |nav| try renderNavName(w, nav, ip),
2135 .identifier => |ident| try w.print("{f}", .{fmtIdentSolo(ident)}),1882 .identifier => |ident| try w.print("{f}", .{fmtIdentSolo(ident)}),
2136 else => unreachable,1883 else => unreachable,
2137 }1884 }
1885 try w.print("{f}", .{cty.fmtDeclaratorSuffix(zcu)});
2138 }1886 }
21391887
2140 fn writeCValue(dg: *DeclGen, w: *Writer, c_value: CValue) Error!void {1888 fn writeCValue(dg: *DeclGen, w: *Writer, c_value: CValue) Error!void {
2141 switch (c_value) {1889 switch (c_value) {
2142 .none, .new_local, .local, .local_ref => unreachable,1890 .none, .new_local, .local, .local_ref => unreachable,
2143 .constant => |uav| try renderUavName(w, uav),1891 .constant => |uav| try renderUavName(w, uav),
2144 .arg, .arg_array => unreachable,1892 .arg => unreachable,
2145 .field => |i| try w.print("f{d}", .{i}),1893 .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),
2147 .nav_ref => |nav| {1895 .nav_ref => |nav| {
2148 try w.writeByte('&');1896 try w.writeByte('&');
2149 try dg.renderNavName(w, nav);1897 try renderNavName(w, nav, &dg.pt.zcu.intern_pool);
2150 },1898 },
2151 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),1899 .undef => |ty| try dg.renderUndefValue(w, ty, .other),
2152 .identifier => |ident| try w.print("{f}", .{fmtIdentSolo(ident)}),1900 .identifier => |ident| try w.print("{f}", .{fmtIdentSolo(ident)}),
2153 .payload_identifier => |ident| try w.print("{f}.{f}", .{1901 .payload_identifier => |ident| try w.print("{f}.{f}", .{
2154 fmtIdentSolo("payload"),1902 fmtIdentSolo("payload"),
2155 fmtIdentSolo(ident),1903 fmtIdentSolo(ident),
2156 }),1904 }),
2157 .ctype_pool_string => |string| try w.print("{f}", .{
2158 fmtCTypePoolString(string, &dg.ctype_pool, true),
2159 }),
2160 }1905 }
2161 }1906 }
21621907
...@@ -2168,16 +1913,14 @@ pub const DeclGen = struct {...@@ -2168,16 +1913,14 @@ pub const DeclGen = struct {
2168 .local_ref,1913 .local_ref,
2169 .constant,1914 .constant,
2170 .arg,1915 .arg,
2171 .arg_array,
2172 .ctype_pool_string,
2173 => unreachable,1916 => unreachable,
2174 .field => |i| try w.print("f{d}", .{i}),1917 .field => |i| try w.print("f{d}", .{i}),
2175 .nav => |nav| {1918 .nav => |nav| {
2176 try w.writeAll("(*");1919 try w.writeAll("(*");
2177 try dg.renderNavName(w, nav);1920 try renderNavName(w, nav, &dg.pt.zcu.intern_pool);
2178 try w.writeByte(')');1921 try w.writeByte(')');
2179 },1922 },
2180 .nav_ref => |nav| try dg.renderNavName(w, nav),1923 .nav_ref => |nav| try renderNavName(w, nav, &dg.pt.zcu.intern_pool),
2181 .undef => unreachable,1924 .undef => unreachable,
2182 .identifier => |ident| try w.print("(*{f})", .{fmtIdentSolo(ident)}),1925 .identifier => |ident| try w.print("(*{f})", .{fmtIdentSolo(ident)}),
2183 .payload_identifier => |ident| try w.print("(*{f}.{f})", .{1926 .payload_identifier => |ident| try w.print("(*{f}.{f})", .{
...@@ -2213,8 +1956,6 @@ pub const DeclGen = struct {...@@ -2213,8 +1956,6 @@ pub const DeclGen = struct {
2213 .field,1956 .field,
2214 .undef,1957 .undef,
2215 .arg,1958 .arg,
2216 .arg_array,
2217 .ctype_pool_string,
2218 => unreachable,1959 => unreachable,
2219 .nav, .identifier, .payload_identifier => {1960 .nav, .identifier, .payload_identifier => {
2220 try dg.writeCValue(w, c_value);1961 try dg.writeCValue(w, c_value);
...@@ -2228,101 +1969,36 @@ pub const DeclGen = struct {...@@ -2228,101 +1969,36 @@ pub const DeclGen = struct {
2228 try dg.writeCValue(w, member);1969 try dg.writeCValue(w, member);
2229 }1970 }
22301971
2231 fn renderFwdDecl(1972 fn renderTypeForBuiltinFnName(dg: *DeclGen, w: *Writer, ty: Type) !void {
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 {
2241 const zcu = dg.pt.zcu;1973 const zcu = dg.pt.zcu;
2242 const ip = &zcu.intern_pool;1974 switch (ty.zigTypeTag(zcu)) {
2243 const nav = ip.getNav(nav_index);1975 .bool => return w.writeAll("u8"),
2244 const fwd = &dg.fwd_decl.writer;1976 .float => return w.print("f{d}", .{ty.floatBits(zcu.getTarget())}),
2245 try fwd.writeAll(switch (flags.linkage) {1977 else => {},
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)}),
2257 }1978 }
2258 if (flags.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal ");1979 if (ty.isPtrAtRuntime(zcu)) {
2259 try dg.renderTypeAndName(1980 return w.print("p{d}", .{zcu.getTarget().ptrBitWidth()});
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 });
2286 }1981 }
2287 }1982 switch (CType.classifyInt(ty, zcu)) {
22881983 .void => unreachable, // opv
2289 fn renderUavName(w: *Writer, uav: Value) !void {1984 .small => try w.print("{c}{d}", .{
2290 try w.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});1985 signAbbrev(ty.intInfo(zcu).signedness),
2291 }1986 ty.abiSize(zcu) * 8,
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,
2311 }),1987 }),
2312 .array => try w.writeAll("big"),1988 .big => try w.writeAll("big"),
2313 }1989 }
2314 }1990 }
23151991
2316 fn renderBuiltinInfo(dg: *DeclGen, w: *Writer, ty: Type, info: BuiltinInfo) !void {1992 fn renderBuiltinInfo(dg: *DeclGen, w: *Writer, ty: Type, info: BuiltinInfo) !void {
2317 const ctype = try dg.ctypeFromType(ty, .complete);1993 const pt = dg.pt;
2318 const is_big = ctype.info(&dg.ctype_pool) == .array;1994 const zcu = pt.zcu;
1995
1996 const is_big = lowersToBigInt(ty, zcu);
2319 switch (info) {1997 switch (info) {
2320 .none => if (!is_big) return,1998 .none => if (!is_big) return,
2321 .bits => {},1999 .bits => {},
2322 }2000 }
23232001
2324 const pt = dg.pt;
2325 const zcu = pt.zcu;
2326 const int_info: std.builtin.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{2002 const int_info: std.builtin.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{
2327 .signedness = .unsigned,2003 .signedness = .unsigned,
2328 .bits = @intCast(ty.bitSize(zcu)),2004 .bits = @intCast(ty.bitSize(zcu)),
...@@ -2331,7 +2007,7 @@ pub const DeclGen = struct {...@@ -2331,7 +2007,7 @@ pub const DeclGen = struct {
2331 if (is_big) try w.print(", {}", .{int_info.signedness == .signed});2007 if (is_big) try w.print(", {}", .{int_info.signedness == .signed});
2332 try w.print(", {f}", .{try dg.fmtIntLiteralDec(2008 try w.print(", {f}", .{try dg.fmtIntLiteralDec(
2333 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),2009 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),
2334 .FunctionArgument,2010 .other,
2335 )});2011 )});
2336 }2012 }
23372013
...@@ -2342,15 +2018,13 @@ pub const DeclGen = struct {...@@ -2342,15 +2018,13 @@ pub const DeclGen = struct {
2342 base: u8,2018 base: u8,
2343 case: std.fmt.Case,2019 case: std.fmt.Case,
2344 ) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {2020 ) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
2345 const zcu = dg.pt.zcu;2021 // If there's a bigint type involved, mark a dependency on it.
2346 const kind = loc.toCTypeKind();2022 const cty: CType = try .lower(val.typeOf(dg.pt.zcu), &dg.ctype_deps, dg.arena, dg.pt.zcu);
2347 const ty = val.typeOf(zcu);
2348 return .{ .data = .{2023 return .{ .data = .{
2349 .dg = dg,2024 .dg = dg,
2350 .int_info = ty.intInfo(zcu),2025 .loc = loc,
2351 .kind = kind,
2352 .ctype = try dg.ctypeFromType(ty, kind),
2353 .val = val,2026 .val = val,
2027 .cty = cty,
2354 .base = base,2028 .base = base,
2355 .case = case,2029 .case = case,
2356 } };2030 } };
...@@ -2373,339 +2047,11 @@ pub const DeclGen = struct {...@@ -2373,339 +2047,11 @@ pub const DeclGen = struct {
2373 }2047 }
2374};2048};
23752049
2376const CTypeFix = enum { prefix, suffix };2050const CQualifiers = packed struct {
2377const CQualifiers = std.enums.EnumSet(enum { @"const", @"volatile", restrict });2051 @"const": bool = false,
2378const Const = CQualifiers.init(.{ .@"const" = true });2052 @"volatile": bool = false,
2379const RenderCTypeTrailing = enum {2053 restrict: bool = false,
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 }
2389};2054};
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
2710pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {2056pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
2711 for (zcu.global_assembly.values()) |asm_source| {2057 for (zcu.global_assembly.values()) |asm_source| {
...@@ -2713,200 +2059,128 @@ pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {...@@ -2713,200 +2059,128 @@ pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
2713 }2059 }
2714}2060}
27152061
2716pub fn genErrDecls(o: *Object) Error!void {2062pub fn genErrDecls(
2717 const pt = o.dg.pt;2063 zcu: *const Zcu,
2718 const zcu = pt.zcu;2064 w: *Writer,
2065 slice_const_u8_sentinel_0_type_name: []const u8,
2066) Writer.Error!void {
2719 const ip = &zcu.intern_pool;2067 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
2724 const names = ip.global_error_set.getNamesFromMainThread();2069 const names = ip.global_error_set.getNamesFromMainThread();
2070 // Don't generate an invalid empty enum if the global error set is empty!
2725 if (names.len > 0) {2071 if (names.len > 0) {
2726 try w.writeAll("enum {");2072 try w.writeAll("enum {\n");
2727 o.indent();
2728 try o.newline();
2729 for (names, 1..) |name_nts, value| {2073 for (names, 1..) |name_nts, value| {
2730 const name = name_nts.toSlice(ip);2074 try w.writeByte(' ');
2731 max_name_len = @max(name.len, max_name_len);2075 try renderErrorName(w, name_nts.toSlice(ip));
2732 const err_val = try pt.intern(.{ .err = .{2076 try w.print(" = {d}u,\n", .{value});
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();
2739 }2077 }
2740 try o.outdent();2078 try w.writeAll("};\n");
2741 try w.writeAll("};");2079 }
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 } });
27642080
2765 try w.writeAll("static ");2081 for (names) |name_nts| {
2766 try o.dg.renderTypeAndName(2082 const name = name_nts.toSlice(ip);
2767 w,2083 try w.print(
2768 name_ty,2084 "static uint8_t const zig_errorName_{f}[] = {f};\n",
2769 .{ .identifier = identifier },2085 .{ fmtIdentUnsolo(name), fmtStringLiteral(name, 0) },
2770 Const,
2771 .none,
2772 .complete,
2773 );2086 );
2774 try w.writeAll(" = ");
2775 try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer);
2776 try w.writeByte(';');
2777 try o.newline();
2778 }2087 }
27792088
2780 const name_array_ty = try pt.arrayType(.{2089 try w.print(
2781 .len = 1 + names.len,2090 "static {s} const zig_errorName[{d}] = {{",
2782 .child = .slice_const_u8_sentinel_0_type,2091 .{ slice_const_u8_sentinel_0_type_name, names.len },
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,
2793 );2092 );
2794 try w.writeAll(" = {");2093 if (names.len > 0) try w.writeByte('\n');
2795 for (names, 1..) |name_nts, val| {2094 for (names) |name_nts| {
2796 const name = name_nts.toSlice(ip);2095 const name = name_nts.toSlice(ip);
2797 if (val > 1) try w.writeAll(", ");2096 try w.print(
2798 try w.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{2097 " {{zig_errorName_{f},{d}}},\n",
2799 fmtIdentUnsolo(name),2098 .{ fmtIdentUnsolo(name), name.len },
2800 try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, name.len), .StaticInitializer),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),
2801 });2127 });
2802 }2128 }
2803 try w.writeAll("};");2129
2804 try o.newline();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 );
2805}2151}
28062152
2807pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) Error!void {2153pub fn genLazyCallModifierFn(
2808 const pt = o.dg.pt;2154 dg: *DeclGen,
2809 const zcu = pt.zcu;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;
2810 const ip = &zcu.intern_pool;2160 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}: {{", .{2162 const fn_val = zcu.navValue(fn_nav);
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");
28882163
2889 try w.print("zig_{s} ", .{@tagName(key)});2164 try w.print("static zig_{t} ", .{kind});
2890 try o.dg.renderFunctionSignature(w, fn_val, .none, .complete, .{2165 try dg.renderFunctionSignature(w, fn_val, .none, .definition, switch (kind) {
2891 .fmt_ctype_pool_string = fn_name,2166 .never_tail => .{ .nav_never_tail = fn_nav },
2892 });2167 .never_inline => .{ .nav_never_inline = fn_nav },
2893 try w.writeAll(" {");2168 });
2894 o.indent();2169 try w.writeAll(" {\n return ");
2895 try o.newline();2170 try renderNavName(w, fn_nav, ip);
2896 try w.writeAll("return ");2171 try w.writeByte('(');
2897 try o.dg.renderNavName(w, fn_nav_index);2172 {
2898 try w.writeByte('(');2173 const func_type = ip.indexToKey(fn_val.typeOf(zcu).toIntern()).func_type;
2899 for (0..fn_info.param_ctypes.len) |arg| {2174 var c_param_index: u32 = 0;
2900 if (arg > 0) try w.writeAll(", ");2175 for (func_type.param_types.get(ip)) |param_ty_ip| {
2901 try w.print("a{d}", .{arg});2176 const param_ty: Type = .fromInterned(param_ty_ip);
2902 }2177 if (!param_ty.hasRuntimeBits(zcu)) continue;
2903 try w.writeAll(");");2178 if (c_param_index != 0) try w.writeAll(", ");
2904 try o.newline();2179 try w.print("a{d}", .{c_param_index});
2905 try o.outdent();2180 c_param_index += 1;
2906 try w.writeByte('}');2181 }
2907 try o.newline();
2908 },
2909 }2182 }
2183 try w.writeAll(");\n}\n");
2910}2184}
29112185
2912pub fn generate(2186pub fn generate(
...@@ -2925,110 +2199,109 @@ pub fn generate(...@@ -2925,110 +2199,109 @@ pub fn generate(
29252199
2926 const func = zcu.funcInfo(func_index);2200 const func = zcu.funcInfo(func_index);
29272201
2202 var arena: std.heap.ArenaAllocator = .init(gpa);
2203 defer arena.deinit();
2204
2928 var function: Function = .{2205 var function: Function = .{
2929 .value_map = .init(gpa),2206 .value_map = .init(gpa),
2930 .air = air.*,2207 .air = air.*,
2931 .liveness = liveness.*.?,2208 .liveness = liveness.*.?,
2932 .func_index = func_index,2209 .func_index = func_index,
2933 .object = .{2210 .dg = .{
2934 .dg = .{2211 .gpa = gpa,
2935 .gpa = gpa,2212 .arena = arena.allocator(),
2936 .pt = pt,2213 .pt = pt,
2937 .mod = zcu.navFileScope(func.owner_nav).mod.?,2214 .mod = zcu.navFileScope(func.owner_nav).mod.?,
2938 .error_msg = null,2215 .error_msg = null,
2939 .pass = .{ .nav = func.owner_nav },2216 .owner_nav = func.owner_nav.toOptional(),
2940 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,2217 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
2941 .expected_block = null,2218 .expected_block = null,
2942 .fwd_decl = .init(gpa),2219 .ctype_deps = .empty,
2943 .ctype_pool = .empty,2220 .uavs = .empty,
2944 .scratch = .empty,
2945 .uavs = .empty,
2946 },
2947 .code_header = .init(gpa),
2948 .code = .init(gpa),
2949 .indent_counter = 0,
2950 },2221 },
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,
2952 };2227 };
2953 defer {2228 defer {
2954 function.object.code_header.deinit();2229 function.code.deinit();
2955 function.object.code.deinit();2230 function.dg.ctype_deps.deinit(gpa);
2956 function.object.dg.fwd_decl.deinit();2231 function.dg.uavs.deinit(gpa);
2957 function.object.dg.ctype_pool.deinit(gpa);
2958 function.object.dg.scratch.deinit(gpa);
2959 function.object.dg.uavs.deinit(gpa);
2960 function.deinit();2232 function.deinit();
2961 }2233 }
2962 try function.object.dg.ctype_pool.init(gpa);
29632234
2964 genFunc(&function) catch |err| switch (err) {2235 var fwd_decl: Writer.Allocating = .init(gpa);
2965 error.AnalysisFail => return zcu.codegenFailMsg(func.owner_nav, function.object.dg.error_msg.?),2236 defer fwd_decl.deinit();
2966 error.OutOfMemory => return error.OutOfMemory,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.?),
2967 error.WriteFailed => return error.OutOfMemory,2243 error.WriteFailed => return error.OutOfMemory,
2244 error.OutOfMemory => |e| return e,
2968 };2245 };
29692246
2970 var mir: Mir = .{2247 var mir: Mir = .{
2971 .uavs = .empty,
2972 .code = &.{},
2973 .code_header = &.{},
2974 .fwd_decl = &.{},2248 .fwd_decl = &.{},
2975 .ctype_pool = .empty,2249 .code_header = &.{},
2976 .lazy_fns = .empty,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(),
2977 };2256 };
2978 errdefer mir.deinit(gpa);2257 errdefer mir.deinit(gpa);
2979 mir.uavs = function.object.dg.uavs.move();2258 mir.fwd_decl = try fwd_decl.toOwnedSlice();
2980 mir.code_header = try function.object.code_header.toOwnedSlice();2259 mir.code_header = try code_header.toOwnedSlice();
2981 mir.code = try function.object.code.toOwnedSlice();2260 mir.code = try function.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();
2985 return mir;2261 return mir;
2986}2262}
29872263
2988pub fn genFunc(f: *Function) Error!void {2264pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) Error!void {
2989 const tracy = trace(@src());2265 const tracy = trace(@src());
2990 defer tracy.end();2266 defer tracy.end();
29912267
2992 const o = &f.object;2268 const zcu = f.dg.pt.zcu;
2993 const zcu = o.dg.pt.zcu;
2994 const ip = &zcu.intern_pool;2269 const ip = &zcu.intern_pool;
2995 const gpa = o.dg.gpa;2270 const gpa = f.dg.gpa;
2996 const nav_index = o.dg.pass.nav;2271 const nav_index = f.dg.owner_nav.unwrap().?;
2997 const nav_val = zcu.navValue(nav_index);2272 const nav_val = zcu.navValue(nav_index);
2998 const nav = ip.getNav(nav_index);2273 const nav = ip.getNav(nav_index);
29992274
3000 const fwd = &o.dg.fwd_decl.writer;2275 try fwd_decl_writer.writeAll("static ");
3001 try fwd.writeAll("static ");2276 try f.dg.renderFunctionSignature(
3002 try o.dg.renderFunctionSignature(2277 fwd_decl_writer,
3003 fwd,
3004 nav_val,2278 nav_val,
3005 nav.status.fully_resolved.alignment,2279 nav.status.fully_resolved.alignment,
3006 .forward,2280 .forward_decl,
3007 .{ .nav = nav_index },2281 .{ .nav = nav_index },
3008 );2282 );
3009 try fwd.writeAll(";\n");2283 try fwd_decl_writer.writeAll(";\n");
30102284
3011 const ch = &o.code_header.writer;
3012 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s|2285 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s|
3013 try ch.print("zig_linksection_fn({f}) ", .{fmtStringLiteral(s, null)});2286 try header_writer.print("zig_linksection_fn({f}) ", .{fmtStringLiteral(s, null)});
3014 try o.dg.renderFunctionSignature(2287 try f.dg.renderFunctionSignature(
3015 ch,2288 header_writer,
3016 nav_val,2289 nav_val,
3017 .none,2290 .none,
3018 .complete,2291 .definition,
3019 .{ .nav = nav_index },2292 .{ .nav = nav_index },
3020 );2293 );
3021 try ch.writeAll(" {\n ");2294 try header_writer.writeAll(" {\n ");
30222295
3023 f.free_locals_map.clearRetainingCapacity();2296 f.free_locals_map.clearRetainingCapacity();
30242297
3025 const main_body = f.air.getMainBody();2298 const main_body = f.air.getMainBody();
3026 o.indent();2299 f.indent();
3027 try genBodyResolveState(f, undefined, &.{}, main_body, true);2300 try genBodyResolveState(f, undefined, &.{}, main_body, true);
3028 try o.outdent();2301 try f.outdent();
3029 try o.code.writer.writeByte('}');2302 try f.code.writer.writeByte('}');
3030 try o.newline();2303 try f.newline();
3031 if (o.dg.expected_block) |_|2304 if (f.dg.expected_block) |_|
3032 return f.fail("runtime code not allowed in naked function", .{});2305 return f.fail("runtime code not allowed in naked function", .{});
30332306
3034 // Take advantage of the free_locals map to bucket locals per type. All2307 // Take advantage of the free_locals map to bucket locals per type. All
...@@ -3042,155 +2315,204 @@ pub fn genFunc(f: *Function) Error!void {...@@ -3042,155 +2315,204 @@ pub fn genFunc(f: *Function) Error!void {
3042 if (!should_emit) continue;2315 if (!should_emit) continue;
3043 const local = f.locals.items[local_index];2316 const local = f.locals.items[local_index];
3044 log.debug("inserting local {d} into free_locals", .{local_index});2317 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);
3046 if (!gop.found_existing) gop.value_ptr.* = .{};2319 if (!gop.found_existing) gop.value_ptr.* = .{};
3047 try gop.value_ptr.putNoClobber(gpa, local_index, {});2320 try gop.value_ptr.putNoClobber(gpa, local_index, {});
3048 }2321 }
30492322
3050 const SortContext = struct {2323 const SortContext = struct {
2324 zcu: *const Zcu,
3051 keys: []const LocalType,2325 keys: []const LocalType,
30522326
3053 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {2327 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
3054 const lhs_ty = ctx.keys[lhs_index];2328 const lhs = ctx.keys[lhs_index];
3055 const rhs_ty = ctx.keys[rhs_index];2329 const rhs = ctx.keys[rhs_index];
3056 return lhs_ty.alignas.order(rhs_ty.alignas).compare(.gt);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);
3057 }2339 }
3058 };2340 };
3059 free_locals.sort(SortContext{ .keys = free_locals.keys() });2341 free_locals.sort(SortContext{
2342 .zcu = zcu,
2343 .keys = free_locals.keys(),
2344 });
30602345
3061 for (free_locals.values()) |list| {2346 for (free_locals.values()) |list| {
3062 for (list.keys()) |local_index| {2347 for (list.keys()) |local_index| {
3063 const local = f.locals.items[local_index];2348 const local = f.locals.items[local_index];
3064 try o.dg.renderCTypeAndName(ch, local.ctype, .{ .local = local_index }, .{}, local.flags.alignas);2349 try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment);
3065 try ch.writeAll(";\n ");2350 try header_writer.writeAll(";\n ");
3066 }2351 }
3067 }2352 }
3068}2353}
30692354
3070pub fn genDecl(o: *Object) Error!void {2355pub fn genDecl(dg: *DeclGen, w: *Writer) Error!void {
3071 const tracy = trace(@src());2356 const tracy = trace(@src());
3072 defer tracy.end();2357 defer tracy.end();
30732358
3074 const pt = o.dg.pt;2359 const pt = dg.pt;
3075 const zcu = pt.zcu;2360 const zcu = pt.zcu;
3076 const ip = &zcu.intern_pool;2361 const ip = &zcu.intern_pool;
3077 const nav = ip.getNav(o.dg.pass.nav);2362 const nav = ip.getNav(dg.owner_nav.unwrap().?);
3078 const nav_ty: Type = .fromInterned(nav.typeOf(ip));2363 const nav_ty: Type = .fromInterned(nav.typeOf(ip));
30792364
3080 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return;2365 const is_const: bool, const is_threadlocal: bool, const init_val: Value = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
3081 switch (ip.indexToKey(nav.status.fully_resolved.val)) {2366 else => .{ true, false, .fromInterned(nav.status.fully_resolved.val) },
3082 .@"extern" => |@"extern"| {2367 .variable => |v| .{ false, v.is_threadlocal, .fromInterned(v.init) },
3083 if (!ip.isFunctionType(nav_ty.toIntern())) return o.dg.renderFwdDecl(o.dg.pass.nav, .{2368 .@"extern" => return,
3084 .is_const = @"extern".is_const,2369 };
3085 .is_threadlocal = @"extern".is_threadlocal,
3086 .linkage = @"extern".linkage,
3087 .visibility = @"extern".visibility,
3088 });
30892370
3090 const fwd = &o.dg.fwd_decl.writer;2371 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s| {
3091 try fwd.writeAll("zig_extern ");2372 try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)});
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 ),
3135 }2373 }
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 });
3136}2387}
2388pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void {
2389 const tracy = trace(@src());
2390 defer tracy.end();
31372391
3138pub fn genDeclValue(2392 const pt = dg.pt;
3139 o: *Object,2393 const zcu = pt.zcu;
3140 val: Value,2394 const ip = &zcu.intern_pool;
3141 decl_c_value: CValue,2395 const nav = ip.getNav(dg.owner_nav.unwrap().?);
3142 alignment: Alignment,2396 const nav_ty: Type = .fromInterned(nav.typeOf(ip));
3143 @"linksection": InternPool.OptionalNullTerminatedString,
3144) Error!void {
3145 const zcu = o.dg.pt.zcu;
3146 const ty = val.typeOf(zcu);
31472397
3148 const fwd = &o.dg.fwd_decl.writer;2398 const is_const: bool, const is_threadlocal: bool, const init_val: Value = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
3149 try fwd.writeAll("static ");2399 else => .{ true, false, .fromInterned(nav.status.fully_resolved.val) },
3150 try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete);2400 .variable => |v| .{ false, v.is_threadlocal, .fromInterned(v.init) },
3151 try fwd.writeAll(";\n");
31522401
3153 const w = &o.code.writer;2402 .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) {
3154 if (@"linksection".toSlice(&zcu.intern_pool)) |s|2403 .@"fn" => {
3155 try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)});2404 try w.writeAll("zig_extern ");
3156 try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete);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);
3157 try w.writeAll(" = ");2466 try w.writeAll(" = ");
3158 try o.dg.renderValue(w, val, .StaticInitializer);2467 try dg.renderValue(w, options.init_val, .static_initializer);
3159 try w.writeByte(';');2468 try w.writeAll(";\n");
3160 try o.newline();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");
3161}2484}
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 {
3164 const zcu = dg.pt.zcu;2487 const zcu = dg.pt.zcu;
3165 const ip = &zcu.intern_pool;2488 const ip = &zcu.intern_pool;
3166 const fwd = &dg.fwd_decl.writer;
31672489
3168 const main_name = export_indices[0].ptr(zcu).opts.name;2490 const main_name = export_indices[0].ptr(zcu).opts.name;
3169 try fwd.writeAll("#define ");2491 try w.writeAll("#define ");
3170 switch (exported) {2492 switch (exported) {
3171 .nav => |nav| try dg.renderNavName(fwd, nav),2493 .nav => |nav| try renderNavName(w, nav, ip),
3172 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),2494 .uav => |uav| try renderUavName(w, Value.fromInterned(uav)),
3173 }2495 }
3174 try fwd.writeByte(' ');2496 try w.writeByte(' ');
3175 try fwd.print("{f}", .{fmtIdentSolo(main_name.toSlice(ip))});2497 try w.print("{f}", .{fmtIdentSolo(main_name.toSlice(ip))});
3176 try fwd.writeByte('\n');2498 try w.writeByte('\n');
31772499
3178 const exported_val = exported.getValue(zcu);2500 const exported_val = exported.getValue(zcu);
3179 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {2501 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {
3180 const @"export" = export_index.ptr(zcu);2502 const @"export" = export_index.ptr(zcu);
3181 try fwd.writeAll("zig_extern ");2503 try w.writeAll("zig_extern ");
3182 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");2504 if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage_fn ");
3183 try dg.renderFunctionSignature(2505 try dg.renderFunctionSignature(
3184 fwd,2506 w,
3185 exported.getValue(zcu),2507 exported.getValue(zcu),
3186 exported.getAlign(zcu),2508 exported.getAlign(zcu),
3187 .forward,2509 .forward_decl,
3188 .{ .@"export" = .{2510 .{ .@"export" = .{
3189 .main_name = main_name,2511 .main_name = main_name,
3190 .extern_name = @"export".opts.name,2512 .extern_name = @"export".opts.name,
3191 } },2513 } },
3192 );2514 );
3193 try fwd.writeAll(";\n");2515 try w.writeAll(";\n");
3194 };2516 };
3195 const is_const = switch (ip.indexToKey(exported_val.toIntern())) {2517 const is_const = switch (ip.indexToKey(exported_val.toIntern())) {
3196 .func => unreachable,2518 .func => unreachable,
...@@ -3200,39 +2522,38 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3200,39 +2522,38 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3200 };2522 };
3201 for (export_indices) |export_index| {2523 for (export_indices) |export_index| {
3202 const @"export" = export_index.ptr(zcu);2524 const @"export" = export_index.ptr(zcu);
3203 try fwd.writeAll("zig_extern ");2525 try w.writeAll("zig_extern ");
3204 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage ");2526 if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage ");
3205 if (@"export".opts.section.toSlice(ip)) |s| try fwd.print("zig_linksection({f}) ", .{2527 if (@"export".opts.section.toSlice(ip)) |s| try w.print("zig_linksection({f}) ", .{
3206 fmtStringLiteral(s, null),2528 fmtStringLiteral(s, null),
3207 });2529 });
3208 const extern_name = @"export".opts.name.toSlice(ip);2530 const extern_name = @"export".opts.name.toSlice(ip);
3209 const is_mangled = isMangledIdent(extern_name, true);2531 const is_mangled = isMangledIdent(extern_name, true);
3210 const is_export = @"export".opts.name != main_name;2532 const is_export = @"export".opts.name != main_name;
3211 try dg.renderTypeAndName(2533 try dg.renderTypeAndName(
3212 fwd,2534 w,
3213 exported.getValue(zcu).typeOf(zcu),2535 exported.getValue(zcu).typeOf(zcu),
3214 .{ .identifier = extern_name },2536 .{ .identifier = extern_name },
3215 CQualifiers.init(.{ .@"const" = is_const }),2537 .{ .@"const" = is_const },
3216 exported.getAlign(zcu),2538 exported.getAlign(zcu),
3217 .complete,
3218 );2539 );
3219 if (is_mangled and is_export) {2540 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})", .{
3221 fmtIdentSolo(extern_name),2542 fmtIdentSolo(extern_name),
3222 fmtStringLiteral(extern_name, null),2543 fmtStringLiteral(extern_name, null),
3223 fmtStringLiteral(main_name.toSlice(ip), null),2544 fmtStringLiteral(main_name.toSlice(ip), null),
3224 });2545 });
3225 } else if (is_mangled) {2546 } else if (is_mangled) {
3226 try fwd.print(" zig_mangled({f}, {f})", .{2547 try w.print(" zig_mangled({f}, {f})", .{
3227 fmtIdentSolo(extern_name), fmtStringLiteral(extern_name, null),2548 fmtIdentSolo(extern_name), fmtStringLiteral(extern_name, null),
3228 });2549 });
3229 } else if (is_export) {2550 } else if (is_export) {
3230 try fwd.print(" zig_export({f}, {f})", .{2551 try w.print(" zig_export({f}, {f})", .{
3231 fmtStringLiteral(main_name.toSlice(ip), null),2552 fmtStringLiteral(main_name.toSlice(ip), null),
3232 fmtStringLiteral(extern_name, null),2553 fmtStringLiteral(extern_name, null),
3233 });2554 });
3234 }2555 }
3235 try fwd.writeAll(";\n");2556 try w.writeAll(";\n");
3236 }2557 }
3237}2558}
32382559
...@@ -3241,15 +2562,15 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3241,15 +2562,15 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3241/// have been added to `free_locals_map`. For a version of this function that restores this state,2562/// have been added to `free_locals_map`. For a version of this function that restores this state,
3242/// see `genBodyResolveState`.2563/// see `genBodyResolveState`.
3243fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {2564fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {
3244 const w = &f.object.code.writer;2565 const w = &f.code.writer;
3245 if (body.len == 0) {2566 if (body.len == 0) {
3246 try w.writeAll("{}");2567 try w.writeAll("{}");
3247 } else {2568 } else {
3248 try w.writeByte('{');2569 try w.writeByte('{');
3249 f.object.indent();2570 f.indent();
3250 try f.object.newline();2571 try f.newline();
3251 try genBodyInner(f, body);2572 try genBodyInner(f, body);
3252 try f.object.outdent();2573 try f.outdent();
3253 try w.writeByte('}');2574 try w.writeByte('}');
3254 }2575 }
3255}2576}
...@@ -3263,13 +2584,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {...@@ -3263,13 +2584,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {
3263fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []const Air.Inst.Index, body: []const Air.Inst.Index, inner: bool) Error!void {2584fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []const Air.Inst.Index, body: []const Air.Inst.Index, inner: bool) Error!void {
3264 if (body.len == 0) {2585 if (body.len == 0) {
3265 // Don't go to the expense of cloning everything!2586 // 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("{}");
3267 return;2588 return;
3268 }2589 }
32692590
3270 // TODO: we can probably avoid the copies in some other common cases too.2591 // 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
3274 // Save the original value_map and free_locals_map so that we can restore them after the body.2595 // Save the original value_map and free_locals_map so that we can restore them after the body.
3275 var old_value_map = try f.value_map.clone();2596 var old_value_map = try f.value_map.clone();
...@@ -3310,13 +2631,13 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con...@@ -3310,13 +2631,13 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
3310}2631}
33112632
3312fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {2633fn 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;
3314 const ip = &zcu.intern_pool;2635 const ip = &zcu.intern_pool;
3315 const air_tags = f.air.instructions.items(.tag);2636 const air_tags = f.air.instructions.items(.tag);
3316 const air_datas = f.air.instructions.items(.data);2637 const air_datas = f.air.instructions.items(.data);
33172638
3318 for (body) |inst| {2639 for (body) |inst| {
3319 if (f.object.dg.expected_block) |_|2640 if (f.dg.expected_block) |_|
3320 return f.fail("runtime code not allowed in naked function", .{});2641 return f.fail("runtime code not allowed in naked function", .{});
3321 if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip))2642 if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip))
3322 continue;2643 continue;
...@@ -3585,8 +2906,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {...@@ -3585,8 +2906,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
3585 .ret => return airRet(f, inst, false),2906 .ret => return airRet(f, inst, false),
3586 .ret_safe => return airRet(f, inst, false), // TODO2907 .ret_safe => return airRet(f, inst, false), // TODO
3587 .ret_load => return airRet(f, inst, true),2908 .ret_load => return airRet(f, inst, true),
3588 .trap => return airTrap(f, &f.object.code.writer),2909 .trap => return airTrap(f),
3589 .unreach => return airUnreach(&f.object),2910 .unreach => return airUnreach(f),
35902911
3591 // Instructions which may be `noreturn`.2912 // Instructions which may be `noreturn`.
3592 .block => res: {2913 .block => res: {
...@@ -3629,177 +2950,159 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3629,177 +2950,159 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
3629 const operand = try f.resolveInst(ty_op.operand);2950 const operand = try f.resolveInst(ty_op.operand);
3630 try reap(f, inst, &.{ty_op.operand});2951 try reap(f, inst, &.{ty_op.operand});
36312952
3632 const w = &f.object.code.writer;2953 const w = &f.code.writer;
3633 const local = try f.allocLocal(inst, inst_ty);2954 const local = try f.allocLocal(inst, inst_ty);
3634 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));2955 try f.writeCValue(w, local, .other);
3635 try f.writeCValue(w, local, .Other);2956 try w.writeAll(" = ");
3636 try a.assign(f, w);
3637 if (is_ptr) {2957 if (is_ptr) {
3638 try w.writeByte('&');2958 try w.writeByte('&');
3639 try f.writeCValueDerefMember(w, operand, .{ .identifier = field_name });2959 try f.writeCValueDerefMember(w, operand, .{ .identifier = field_name });
3640 } else try f.writeCValueMember(w, operand, .{ .identifier = field_name });2960 } else try f.writeCValueMember(w, operand, .{ .identifier = field_name });
3641 try a.end(f, w);2961 try w.writeByte(';');
2962 try f.newline();
3642 return local;2963 return local;
3643}2964}
36442965
3645fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {2966fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3646 const zcu = f.object.dg.pt.zcu;2967 const zcu = f.dg.pt.zcu;
3647 const inst_ty = f.typeOfIndex(inst);2968 const inst_ty = f.typeOfIndex(inst);
3648 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2969 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3649 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2970 assert(inst_ty.hasRuntimeBits(zcu));
3650 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3651 return .none;
3652 }
36532971
3654 const ptr = try f.resolveInst(bin_op.lhs);2972 const ptr = try f.resolveInst(bin_op.lhs);
3655 const index = try f.resolveInst(bin_op.rhs);2973 const index = try f.resolveInst(bin_op.rhs);
3656 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });2974 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36572975
3658 const w = &f.object.code.writer;2976 const w = &f.code.writer;
3659 const local = try f.allocLocal(inst, inst_ty);2977 const local = try f.allocLocal(inst, inst_ty);
3660 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));2978 try f.writeCValue(w, local, .other);
3661 try f.writeCValue(w, local, .Other);2979 try w.writeAll(" = ");
3662 try a.assign(f, w);2980 switch (f.typeOf(bin_op.lhs).ptrSize(zcu)) {
3663 try f.writeCValue(w, ptr, .Other);2981 .one => try f.writeCValueDerefMember(w, ptr, .{ .identifier = "array" }),
2982 .many, .c => try f.writeCValue(w, ptr, .other),
2983 .slice => unreachable,
2984 }
3664 try w.writeByte('[');2985 try w.writeByte('[');
3665 try f.writeCValue(w, index, .Other);2986 try f.writeCValue(w, index, .other);
3666 try w.writeByte(']');2987 try w.writeAll("];");
3667 try a.end(f, w);2988 try f.newline();
3668 return local;2989 return local;
3669}2990}
36702991
3671fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {2992fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3672 const pt = f.object.dg.pt;2993 const pt = f.dg.pt;
3673 const zcu = pt.zcu;2994 const zcu = pt.zcu;
3674 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2995 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3675 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;2996 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
36762997
3677 const inst_ty = f.typeOfIndex(inst);2998 const inst_ty = f.typeOfIndex(inst);
3678 const ptr_ty = f.typeOf(bin_op.lhs);2999 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
3681 const ptr = try f.resolveInst(bin_op.lhs);3002 const ptr = try f.resolveInst(bin_op.lhs);
3682 const index = try f.resolveInst(bin_op.rhs);3003 const index = try f.resolveInst(bin_op.rhs);
3683 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3004 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36843005
3685 const w = &f.object.code.writer;3006 const w = &f.code.writer;
3686 const local = try f.allocLocal(inst, inst_ty);3007 const local = try f.allocLocal(inst, inst_ty);
3687 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));3008 try f.writeCValue(w, local, .other);
3688 try f.writeCValue(w, local, .Other);3009 try w.writeAll(" = ");
3689 try a.assign(f, w);3010 try w.writeByte('&');
3690 try w.writeByte('(');3011 if (ptr_ty.ptrSize(zcu) == .one) {
3691 try f.renderType(w, inst_ty);3012 // `*[n]T` was turned into a pointer to `struct { T array[n]; }`
3692 try w.writeByte(')');3013 try f.writeCValueDerefMember(w, ptr, .{ .identifier = "array" });
3693 if (elem_has_bits) try w.writeByte('&');3014 } else {
3694 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {3015 try f.writeCValue(w, ptr, .other);
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(']');
3702 }3016 }
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();
3704 return local;3021 return local;
3705}3022}
37063023
3707fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3024fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3708 const zcu = f.object.dg.pt.zcu;3025 const zcu = f.dg.pt.zcu;
3709 const inst_ty = f.typeOfIndex(inst);3026 const inst_ty = f.typeOfIndex(inst);
3710 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3027 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3711 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3028 assert(inst_ty.hasRuntimeBits(zcu));
3712 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3713 return .none;
3714 }
37153029
3716 const slice = try f.resolveInst(bin_op.lhs);3030 const slice = try f.resolveInst(bin_op.lhs);
3717 const index = try f.resolveInst(bin_op.rhs);3031 const index = try f.resolveInst(bin_op.rhs);
3718 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3032 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37193033
3720 const w = &f.object.code.writer;3034 const w = &f.code.writer;
3721 const local = try f.allocLocal(inst, inst_ty);3035 const local = try f.allocLocal(inst, inst_ty);
3722 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));3036 try f.writeCValue(w, local, .other);
3723 try f.writeCValue(w, local, .Other);3037 try w.writeAll(" = ");
3724 try a.assign(f, w);
3725 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });3038 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
3726 try w.writeByte('[');3039 try w.writeByte('[');
3727 try f.writeCValue(w, index, .Other);3040 try f.writeCValue(w, index, .other);
3728 try w.writeByte(']');3041 try w.writeAll("];");
3729 try a.end(f, w);3042 try f.newline();
3730 return local;3043 return local;
3731}3044}
37323045
3733fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {3046fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3734 const pt = f.object.dg.pt;3047 const pt = f.dg.pt;
3735 const zcu = pt.zcu;3048 const zcu = pt.zcu;
3736 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3049 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3737 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3050 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
37383051
3739 const inst_ty = f.typeOfIndex(inst);3052 const inst_ty = f.typeOfIndex(inst);
3740 const slice_ty = f.typeOf(bin_op.lhs);3053 const slice_ty = f.typeOf(bin_op.lhs);
3741 const elem_ty = slice_ty.elemType2(zcu);3054 const elem_ty = slice_ty.childType(zcu);
3742 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu);3055 assert(elem_ty.hasRuntimeBits(zcu));
37433056
3744 const slice = try f.resolveInst(bin_op.lhs);3057 const slice = try f.resolveInst(bin_op.lhs);
3745 const index = try f.resolveInst(bin_op.rhs);3058 const index = try f.resolveInst(bin_op.rhs);
3746 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3059 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37473060
3748 const w = &f.object.code.writer;3061 const w = &f.code.writer;
3749 const local = try f.allocLocal(inst, inst_ty);3062 const local = try f.allocLocal(inst, inst_ty);
3750 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));3063 try f.writeCValue(w, local, .other);
3751 try f.writeCValue(w, local, .Other);3064 try w.writeAll(" = ");
3752 try a.assign(f, w);3065 try w.writeByte('&');
3753 if (elem_has_bits) try w.writeByte('&');
3754 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });3066 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
3755 if (elem_has_bits) {3067 try w.writeByte('[');
3756 try w.writeByte('[');3068 try f.writeCValue(w, index, .other);
3757 try f.writeCValue(w, index, .Other);3069 try w.writeAll("];");
3758 try w.writeByte(']');3070 try f.newline();
3759 }
3760 try a.end(f, w);
3761 return local;3071 return local;
3762}3072}
37633073
3764fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3074fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3765 const zcu = f.object.dg.pt.zcu;3075 const zcu = f.dg.pt.zcu;
3766 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3076 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3767 const inst_ty = f.typeOfIndex(inst);3077 const inst_ty = f.typeOfIndex(inst);
3768 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3078 assert(inst_ty.hasRuntimeBits(zcu));
3769 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3770 return .none;
3771 }
37723079
3773 const array = try f.resolveInst(bin_op.lhs);3080 const array = try f.resolveInst(bin_op.lhs);
3774 const index = try f.resolveInst(bin_op.rhs);3081 const index = try f.resolveInst(bin_op.rhs);
3775 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3082 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37763083
3777 const w = &f.object.code.writer;3084 const w = &f.code.writer;
3778 const local = try f.allocLocal(inst, inst_ty);3085 const local = try f.allocLocal(inst, inst_ty);
3779 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));3086 try f.writeCValue(w, local, .other);
3780 try f.writeCValue(w, local, .Other);3087 try w.writeAll(" = ");
3781 try a.assign(f, w);3088 try f.writeCValueMember(w, array, .{ .identifier = "array" });
3782 try f.writeCValue(w, array, .Other);
3783 try w.writeByte('[');3089 try w.writeByte('[');
3784 try f.writeCValue(w, index, .Other);3090 try f.writeCValue(w, index, .other);
3785 try w.writeByte(']');3091 try w.writeAll("];");
3786 try a.end(f, w);3092 try f.newline();
3787 return local;3093 return local;
3788}3094}
37893095
3790fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {3096fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3791 const pt = f.object.dg.pt;3097 const pt = f.dg.pt;
3792 const zcu = pt.zcu;3098 const zcu = pt.zcu;
3793 const inst_ty = f.typeOfIndex(inst);3099 const inst_ty = f.typeOfIndex(inst);
3794 const elem_ty = inst_ty.childType(zcu);3100 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
3797 const local = try f.allocLocalValue(.{3103 const local = try f.allocLocalValue(.{
3798 .ctype = try f.ctypeFromType(elem_ty, .complete),3104 .type = elem_ty,
3799 .alignas = CType.AlignAs.fromAlignment(.{3105 .alignment = inst_ty.ptrInfo(zcu).flags.alignment,
3800 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,
3801 .abi = elem_ty.abiAlignment(zcu),
3802 }),
3803 });3106 });
3804 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3107 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3805 try f.allocs.put(zcu.gpa, local.new_local, true);3108 try f.allocs.put(zcu.gpa, local.new_local, true);
...@@ -3810,11 +3113,11 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3810,11 +3113,11 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3810 // For packed aggregates, we zero-initialize to try and work around a design flaw3113 // For packed aggregates, we zero-initialize to try and work around a design flaw
3811 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`3114 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3812 // for details.3115 // for details.
3813 const w = &f.object.code.writer;3116 const w = &f.code.writer;
3814 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});3117 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3815 try f.renderType(w, elem_ty);3118 try f.renderType(w, elem_ty);
3816 try w.writeAll("));");3119 try w.writeAll("));");
3817 try f.object.newline();3120 try f.newline();
3818 },3121 },
3819 .auto, .@"extern" => {},3122 .auto, .@"extern" => {},
3820 },3123 },
...@@ -3825,18 +3128,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3825,18 +3128,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3825}3128}
38263129
3827fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {3130fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3828 const pt = f.object.dg.pt;3131 const pt = f.dg.pt;
3829 const zcu = pt.zcu;3132 const zcu = pt.zcu;
3830 const inst_ty = f.typeOfIndex(inst);3133 const inst_ty = f.typeOfIndex(inst);
3831 const elem_ty = inst_ty.childType(zcu);3134 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
3834 const local = try f.allocLocalValue(.{3137 const local = try f.allocLocalValue(.{
3835 .ctype = try f.ctypeFromType(elem_ty, .complete),3138 .type = elem_ty,
3836 .alignas = CType.AlignAs.fromAlignment(.{3139 .alignment = inst_ty.ptrInfo(zcu).flags.alignment,
3837 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,
3838 .abi = elem_ty.abiAlignment(zcu),
3839 }),
3840 });3140 });
3841 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3141 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3842 try f.allocs.put(zcu.gpa, local.new_local, true);3142 try f.allocs.put(zcu.gpa, local.new_local, true);
...@@ -3847,11 +3147,11 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3847,11 +3147,11 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3847 // For packed aggregates, we zero-initialize to try and work around a design flaw3147 // For packed aggregates, we zero-initialize to try and work around a design flaw
3848 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`3148 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
3849 // for details.3149 // for details.
3850 const w = &f.object.code.writer;3150 const w = &f.code.writer;
3851 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});3151 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
3852 try f.renderType(w, elem_ty);3152 try f.renderType(w, elem_ty);
3853 try w.writeAll("));");3153 try w.writeAll("));");
3854 try f.object.newline();3154 try f.newline();
3855 },3155 },
3856 .auto, .@"extern" => {},3156 .auto, .@"extern" => {},
3857 },3157 },
...@@ -3862,24 +3162,18 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3862,24 +3162,18 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3862}3162}
38633163
3864fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {3164fn 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
3868 const i = f.next_arg_index;3165 const i = f.next_arg_index;
3869 f.next_arg_index += 1;3166 f.next_arg_index += 1;
3870 const result: CValue = if (inst_ctype.eql(try f.ctypeFromType(inst_ty, .complete)))3167 const result: CValue = .{ .arg = i };
3871 .{ .arg = i }
3872 else
3873 .{ .arg_array = i };
38743168
3875 if (f.liveness.isUnused(inst)) {3169 if (f.liveness.isUnused(inst)) {
3876 const w = &f.object.code.writer;3170 const w = &f.code.writer;
3877 try w.writeByte('(');3171 try w.writeByte('(');
3878 try f.renderType(w, .void);3172 try f.renderType(w, .void);
3879 try w.writeByte(')');3173 try w.writeByte(')');
3880 try f.writeCValue(w, result, .Other);3174 try f.writeCValue(w, result, .other);
3881 try w.writeByte(';');3175 try w.writeByte(';');
3882 try f.object.newline();3176 try f.newline();
3883 return .none;3177 return .none;
3884 }3178 }
38853179
...@@ -3887,7 +3181,7 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3887,7 +3181,7 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3887}3181}
38883182
3889fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {3183fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3890 const pt = f.object.dg.pt;3184 const pt = f.dg.pt;
3891 const zcu = pt.zcu;3185 const zcu = pt.zcu;
3892 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3186 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 {...@@ -3900,10 +3194,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3900 // bit-pointers we see here are vector element pointers.3194 // bit-pointers we see here are vector element pointers.
3901 assert(ptr_info.packed_offset.host_size == 0 or ptr_info.flags.vector_index != .none);3195 assert(ptr_info.packed_offset.host_size == 0 or ptr_info.flags.vector_index != .none);
39023196
3903 if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3197 assert(src_ty.hasRuntimeBits(zcu));
3904 try reap(f, inst, &.{ty_op.operand});
3905 return .none;
3906 }
39073198
3908 const operand = try f.resolveInst(ty_op.operand);3199 const operand = try f.resolveInst(ty_op.operand);
39093200
...@@ -3913,94 +3204,69 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3913,94 +3204,69 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3913 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)3204 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)
3914 else3205 else
3915 true;3206 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;
3920 const local = try f.allocLocal(inst, src_ty);3209 const local = try f.allocLocal(inst, src_ty);
3921 const v = try Vectorize.start(f, inst, w, ptr_ty);3210 const v = try Vectorize.start(f, inst, w, ptr_ty);
39223211
3923 if (need_memcpy) {3212 if (!is_aligned) {
3924 try w.writeAll("memcpy(");3213 try w.writeAll("memcpy(&");
3925 if (!is_array) try w.writeByte('&');3214 try f.writeCValue(w, local, .other);
3926 try f.writeCValue(w, local, .Other);
3927 try v.elem(f, w);3215 try v.elem(f, w);
3928 try w.writeAll(", (const char *)");3216 try w.writeAll(", (const char *)");
3929 try f.writeCValue(w, operand, .Other);3217 try f.writeCValue(w, operand, .other);
3930 try v.elem(f, w);3218 try v.elem(f, w);
3931 try w.writeAll(", sizeof(");3219 try w.writeAll(", sizeof(");
3932 try f.renderType(w, src_ty);3220 try f.renderType(w, src_ty);
3933 try w.writeAll("))");3221 try w.writeAll("))");
3934 } else {3222 } else {
3935 try f.writeCValue(w, local, .Other);3223 try f.writeCValue(w, local, .other);
3936 try v.elem(f, w);3224 try v.elem(f, w);
3937 try w.writeAll(" = ");3225 try w.writeAll(" = ");
3938 try f.writeCValueDeref(w, operand);3226 try f.writeCValueDeref(w, operand);
3939 try v.elem(f, w);3227 try v.elem(f, w);
3940 }3228 }
3941 try w.writeByte(';');3229 try w.writeByte(';');
3942 try f.object.newline();3230 try f.newline();
3943 try v.end(f, inst, w);3231 try v.end(f, inst, w);
39443232
3945 return local;3233 return local;
3946}3234}
39473235
3948fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {3236fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
3949 const pt = f.object.dg.pt;3237 const pt = f.dg.pt;
3950 const zcu = pt.zcu;3238 const zcu = pt.zcu;
3951 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;3239 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;
3953 const op_inst = un_op.toIndex();3241 const op_inst = un_op.toIndex();
3954 const op_ty = f.typeOf(un_op);3242 const op_ty = f.typeOf(un_op);
3955 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;3243 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;
3956 const ret_ctype = try f.ctypeFromType(ret_ty, .parameter);
39573244
3958 if (op_inst != null and f.air.instructions.items(.tag)[@intFromEnum(op_inst.?)] == .call_always_tail) {3245 if (op_inst != null and f.air.instructions.items(.tag)[@intFromEnum(op_inst.?)] == .call_always_tail) {
3959 try reap(f, inst, &.{un_op});3246 try reap(f, inst, &.{un_op});
3960 _ = try airCall(f, op_inst.?, .always_tail);3247 _ = try airCall(f, op_inst.?, .always_tail);
3961 } else if (ret_ctype.index != .void) {3248 } else if (ret_ty.hasRuntimeBits(zcu)) {
3962 const operand = try f.resolveInst(un_op);3249 const operand = try f.resolveInst(un_op);
3963 try reap(f, inst, &.{un_op});3250 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
3986 try w.writeAll("return ");3252 try w.writeAll("return ");
3987 if (deref)3253 if (is_ptr) {
3988 try f.writeCValueDeref(w, ret_val)3254 try f.writeCValueDeref(w, operand);
3989 else3255 } else switch (operand) {
3990 try f.writeCValue(w, ret_val, .Other);3256 // Instead of 'return &local', emit 'return undefined'.
3991 try w.writeAll(";\n");3257 .local_ref => try f.dg.renderUndefValue(w, ret_ty, .other),
3992 if (is_array) {3258 else => try f.writeCValue(w, operand, .other),
3993 try freeLocal(f, inst, ret_val.new_local, null);
3994 }3259 }
3260 try w.writeAll(";\n");
3995 } else {3261 } else {
3996 try reap(f, inst, &.{un_op});3262 try reap(f, inst, &.{un_op});
3997 // Not even allowed to return void in a naked function.3263 // 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");
3999 }3265 }
4000}3266}
40013267
4002fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {3268fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
4003 const pt = f.object.dg.pt;3269 const pt = f.dg.pt;
4004 const zcu = pt.zcu;3270 const zcu = pt.zcu;
4005 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3271 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 {...@@ -4012,23 +3278,26 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
4012 const operand_ty = f.typeOf(ty_op.operand);3278 const operand_ty = f.typeOf(ty_op.operand);
4013 const scalar_ty = operand_ty.scalarType(zcu);3279 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;
4018 const local = try f.allocLocal(inst, inst_ty);3287 const local = try f.allocLocal(inst, inst_ty);
4019 const v = try Vectorize.start(f, inst, w, operand_ty);3288 const v = try Vectorize.start(f, inst, w, operand_ty);
4020 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));3289 try f.writeCValue(w, local, .other);
4021 try f.writeCValue(w, local, .Other);
4022 try v.elem(f, w);3290 try v.elem(f, w);
4023 try a.assign(f, w);3291 try w.writeAll(" = ");
4024 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .Other);3292 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .other);
4025 try a.end(f, w);3293 try w.writeByte(';');
3294 try f.newline();
4026 try v.end(f, inst, w);3295 try v.end(f, inst, w);
4027 return local;3296 return local;
4028}3297}
40293298
4030fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {3299fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4031 const pt = f.object.dg.pt;3300 const pt = f.dg.pt;
4032 const zcu = pt.zcu;3301 const zcu = pt.zcu;
4033 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3302 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 {...@@ -4050,13 +3319,12 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4050 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);3319 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
4051 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);3320 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;
4054 const local = try f.allocLocal(inst, inst_ty);3323 const local = try f.allocLocal(inst, inst_ty);
4055 const v = try Vectorize.start(f, inst, w, operand_ty);3324 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));3325 try f.writeCValue(w, local, .other);
4057 try f.writeCValue(w, local, .Other);
4058 try v.elem(f, w);3326 try v.elem(f, w);
4059 try a.assign(f, w);3327 try w.writeAll(" = ");
4060 if (need_cast) {3328 if (need_cast) {
4061 try w.writeByte('(');3329 try w.writeByte('(');
4062 try f.renderType(w, inst_scalar_ty);3330 try f.renderType(w, inst_scalar_ty);
...@@ -4064,18 +3332,18 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4064,18 +3332,18 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4064 }3332 }
4065 if (need_lo) {3333 if (need_lo) {
4066 try w.writeAll("zig_lo_");3334 try w.writeAll("zig_lo_");
4067 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);3335 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4068 try w.writeByte('(');3336 try w.writeByte('(');
4069 }3337 }
4070 if (!need_mask) {3338 if (!need_mask) {
4071 try f.writeCValue(w, operand, .Other);3339 try f.writeCValue(w, operand, .other);
4072 try v.elem(f, w);3340 try v.elem(f, w);
4073 } else switch (dest_int_info.signedness) {3341 } else switch (dest_int_info.signedness) {
4074 .unsigned => {3342 .unsigned => {
4075 try w.writeAll("zig_and_");3343 try w.writeAll("zig_and_");
4076 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);3344 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4077 try w.writeByte('(');3345 try w.writeByte('(');
4078 try f.writeCValue(w, operand, .FunctionArgument);3346 try f.writeCValue(w, operand, .other);
4079 try v.elem(f, w);3347 try v.elem(f, w);
4080 try w.print(", {f})", .{3348 try w.print(", {f})", .{
4081 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),3349 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
...@@ -4087,7 +3355,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4087,7 +3355,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4087 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);3355 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
40883356
4089 try w.writeAll("zig_shr_");3357 try w.writeAll("zig_shr_");
4090 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);3358 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4091 if (c_bits == 128) {3359 if (c_bits == 128) {
4092 try w.print("(zig_bitCast_i{d}(", .{c_bits});3360 try w.print("(zig_bitCast_i{d}(", .{c_bits});
4093 } else {3361 } else {
...@@ -4099,7 +3367,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4099,7 +3367,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4099 } else {3367 } else {
4100 try w.print("(uint{d}_t)", .{c_bits});3368 try w.print("(uint{d}_t)", .{c_bits});
4101 }3369 }
4102 try f.writeCValue(w, operand, .FunctionArgument);3370 try f.writeCValue(w, operand, .other);
4103 try v.elem(f, w);3371 try v.elem(f, w);
4104 if (c_bits == 128) try w.writeByte(')');3372 if (c_bits == 128) try w.writeByte(')');
4105 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});3373 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
...@@ -4108,13 +3376,14 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4108,13 +3376,14 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4108 },3376 },
4109 }3377 }
4110 if (need_lo) try w.writeByte(')');3378 if (need_lo) try w.writeByte(')');
4111 try a.end(f, w);3379 try w.writeByte(';');
3380 try f.newline();
4112 try v.end(f, inst, w);3381 try v.end(f, inst, w);
4113 return local;3382 return local;
4114}3383}
41153384
4116fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {3385fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4117 const pt = f.object.dg.pt;3386 const pt = f.dg.pt;
4118 const zcu = pt.zcu;3387 const zcu = pt.zcu;
4119 // *a = b;3388 // *a = b;
4120 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3389 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 {...@@ -4132,7 +3401,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41323401
4133 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |v| v.isUndef(zcu) else false;3402 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;
4136 if (val_is_undef) {3405 if (val_is_undef) {
4137 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3406 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
4138 if (safety and ptr_info.packed_offset.host_size == 0) {3407 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 {...@@ -4152,11 +3421,11 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4152 },3421 },
4153 };3422 };
4154 try w.writeAll("memset(");3423 try w.writeAll("memset(");
4155 try f.writeCValue(w, ptr_val, .FunctionArgument);3424 try f.writeCValue(w, ptr_val, .other);
4156 try w.print(", {s}, sizeof(", .{byte_str});3425 try w.print(", {s}, sizeof(", .{byte_str});
4157 try f.renderType(w, .fromInterned(ptr_info.child));3426 try f.renderType(w, .fromInterned(ptr_info.child));
4158 try w.writeAll("));");3427 try w.writeAll("));");
4159 try f.object.newline();3428 try f.newline();
4160 }3429 }
4161 return .none;3430 return .none;
4162 }3431 }
...@@ -4165,46 +3434,29 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4165,46 +3434,29 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4165 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)3434 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)
4166 else3435 else
4167 true;3436 true;
4168 const is_array = lowersToArray(.fromInterned(ptr_info.child), zcu);
4169 const need_memcpy = !is_aligned or is_array;
41703437
4171 const src_val = try f.resolveInst(bin_op.rhs);3438 const src_val = try f.resolveInst(bin_op.rhs);
4172 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3439 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
41733440
4174 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);3441 if (!is_aligned) {
4175 if (need_memcpy) {3442 // For this memcpy to safely work we need the rhs to have the same
4176 // For this memcpy to safely work we need the rhs to have the same3443 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
4177 // 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));
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;
41933445
4194 const v = try Vectorize.start(f, inst, w, ptr_ty);3446 const v = try Vectorize.start(f, inst, w, ptr_ty);
4195 try w.writeAll("memcpy((char *)");3447 try w.writeAll("memcpy((char *)");
4196 try f.writeCValue(w, ptr_val, .FunctionArgument);3448 try f.writeCValue(w, ptr_val, .other);
4197 try v.elem(f, w);3449 try v.elem(f, w);
4198 try w.writeAll(", ");3450 try w.writeAll(", &");
4199 if (!is_array) try w.writeByte('&');3451 switch (src_val) {
4200 try f.writeCValue(w, array_src, .FunctionArgument);3452 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
3453 else => try f.writeCValue(w, src_val, .other),
3454 }
4201 try v.elem(f, w);3455 try v.elem(f, w);
4202 try w.writeAll(", sizeof(");3456 try w.writeAll(", sizeof(");
4203 try f.renderType(w, src_ty);3457 try f.renderType(w, src_ty);
4204 try w.writeAll("))");3458 try w.writeAll("));");
4205 try f.freeCValue(inst, array_src);3459 try f.newline();
4206 try w.writeByte(';');
4207 try f.object.newline();
4208 try v.end(f, inst, w);3460 try v.end(f, inst, w);
4209 } else {3461 } else {
4210 switch (ptr_val) {3462 switch (ptr_val) {
...@@ -4216,20 +3468,20 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4216,20 +3468,20 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4216 else => {},3468 else => {},
4217 }3469 }
4218 const v = try Vectorize.start(f, inst, w, ptr_ty);3470 const v = try Vectorize.start(f, inst, w, ptr_ty);
4219 const a = try Assignment.start(f, w, src_scalar_ctype);
4220 try f.writeCValueDeref(w, ptr_val);3471 try f.writeCValueDeref(w, ptr_val);
4221 try v.elem(f, w);3472 try v.elem(f, w);
4222 try a.assign(f, w);3473 try w.writeAll(" = ");
4223 try f.writeCValue(w, src_val, .Other);3474 try f.writeCValue(w, src_val, .other);
4224 try v.elem(f, w);3475 try v.elem(f, w);
4225 try a.end(f, w);3476 try w.writeByte(';');
3477 try f.newline();
4226 try v.end(f, inst, w);3478 try v.end(f, inst, w);
4227 }3479 }
4228 return .none;3480 return .none;
4229}3481}
42303482
4231fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {3483fn 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;
4233 const zcu = pt.zcu;3485 const zcu = pt.zcu;
4234 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3486 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4235 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3487 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:...@@ -4242,7 +3494,9 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
4242 const operand_ty = f.typeOf(bin_op.lhs);3494 const operand_ty = f.typeOf(bin_op.lhs);
4243 const scalar_ty = operand_ty.scalarType(zcu);3495 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;
4246 const local = try f.allocLocal(inst, inst_ty);3500 const local = try f.allocLocal(inst, inst_ty);
4247 const v = try Vectorize.start(f, inst, w, operand_ty);3501 const v = try Vectorize.start(f, inst, w, operand_ty);
4248 try f.writeCValueMember(w, local, .{ .field = 1 });3502 try f.writeCValueMember(w, local, .{ .field = 1 });
...@@ -4250,26 +3504,28 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -4250,26 +3504,28 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
4250 try w.writeAll(" = zig_");3504 try w.writeAll(" = zig_");
4251 try w.writeAll(operation);3505 try w.writeAll(operation);
4252 try w.writeAll("o_");3506 try w.writeAll("o_");
4253 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);3507 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4254 try w.writeAll("(&");3508 try w.writeAll("(&");
4255 try f.writeCValueMember(w, local, .{ .field = 0 });3509 try f.writeCValueMember(w, local, .{ .field = 0 });
4256 try v.elem(f, w);3510 try v.elem(f, w);
4257 try w.writeAll(", ");3511 try w.writeAll(", ");
4258 try f.writeCValue(w, lhs, .FunctionArgument);3512 if (ref_arg) try w.writeByte('&');
3513 try f.writeCValue(w, lhs, .other);
4259 try v.elem(f, w);3514 try v.elem(f, w);
4260 try w.writeAll(", ");3515 try w.writeAll(", ");
4261 try f.writeCValue(w, rhs, .FunctionArgument);3516 if (ref_arg) try w.writeByte('&');
3517 try f.writeCValue(w, rhs, .other);
4262 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);3518 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);
4264 try w.writeAll(");");3520 try w.writeAll(");");
4265 try f.object.newline();3521 try f.newline();
4266 try v.end(f, inst, w);3522 try v.end(f, inst, w);
42673523
4268 return local;3524 return local;
4269}3525}
42703526
4271fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {3527fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
4272 const pt = f.object.dg.pt;3528 const pt = f.dg.pt;
4273 const zcu = pt.zcu;3529 const zcu = pt.zcu;
4274 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3530 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4275 const operand_ty = f.typeOf(ty_op.operand);3531 const operand_ty = f.typeOf(ty_op.operand);
...@@ -4281,17 +3537,17 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4281,17 +3537,17 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
42813537
4282 const inst_ty = f.typeOfIndex(inst);3538 const inst_ty = f.typeOfIndex(inst);
42833539
4284 const w = &f.object.code.writer;3540 const w = &f.code.writer;
4285 const local = try f.allocLocal(inst, inst_ty);3541 const local = try f.allocLocal(inst, inst_ty);
4286 const v = try Vectorize.start(f, inst, w, operand_ty);3542 const v = try Vectorize.start(f, inst, w, operand_ty);
4287 try f.writeCValue(w, local, .Other);3543 try f.writeCValue(w, local, .other);
4288 try v.elem(f, w);3544 try v.elem(f, w);
4289 try w.writeAll(" = ");3545 try w.writeAll(" = ");
4290 try w.writeByte('!');3546 try w.writeByte('!');
4291 try f.writeCValue(w, op, .Other);3547 try f.writeCValue(w, op, .other);
4292 try v.elem(f, w);3548 try v.elem(f, w);
4293 try w.writeByte(';');3549 try w.writeByte(';');
4294 try f.object.newline();3550 try f.newline();
4295 try v.end(f, inst, w);3551 try v.end(f, inst, w);
42963552
4297 return local;3553 return local;
...@@ -4304,7 +3560,7 @@ fn airBinOp(...@@ -4304,7 +3560,7 @@ fn airBinOp(
4304 operation: []const u8,3560 operation: []const u8,
4305 info: BuiltinInfo,3561 info: BuiltinInfo,
4306) !CValue {3562) !CValue {
4307 const pt = f.object.dg.pt;3563 const pt = f.dg.pt;
4308 const zcu = pt.zcu;3564 const zcu = pt.zcu;
4309 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3565 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4310 const operand_ty = f.typeOf(bin_op.lhs);3566 const operand_ty = f.typeOf(bin_op.lhs);
...@@ -4318,21 +3574,21 @@ fn airBinOp(...@@ -4318,21 +3574,21 @@ fn airBinOp(
43183574
4319 const inst_ty = f.typeOfIndex(inst);3575 const inst_ty = f.typeOfIndex(inst);
43203576
4321 const w = &f.object.code.writer;3577 const w = &f.code.writer;
4322 const local = try f.allocLocal(inst, inst_ty);3578 const local = try f.allocLocal(inst, inst_ty);
4323 const v = try Vectorize.start(f, inst, w, operand_ty);3579 const v = try Vectorize.start(f, inst, w, operand_ty);
4324 try f.writeCValue(w, local, .Other);3580 try f.writeCValue(w, local, .other);
4325 try v.elem(f, w);3581 try v.elem(f, w);
4326 try w.writeAll(" = ");3582 try w.writeAll(" = ");
4327 try f.writeCValue(w, lhs, .Other);3583 try f.writeCValue(w, lhs, .other);
4328 try v.elem(f, w);3584 try v.elem(f, w);
4329 try w.writeByte(' ');3585 try w.writeByte(' ');
4330 try w.writeAll(operator);3586 try w.writeAll(operator);
4331 try w.writeByte(' ');3587 try w.writeByte(' ');
4332 try f.writeCValue(w, rhs, .Other);3588 try f.writeCValue(w, rhs, .other);
4333 try v.elem(f, w);3589 try v.elem(f, w);
4334 try w.writeByte(';');3590 try w.writeByte(';');
4335 try f.object.newline();3591 try f.newline();
4336 try v.end(f, inst, w);3592 try v.end(f, inst, w);
43373593
4338 return local;3594 return local;
...@@ -4344,7 +3600,7 @@ fn airCmpOp(...@@ -4344,7 +3600,7 @@ fn airCmpOp(
4344 data: anytype,3600 data: anytype,
4345 operator: std.math.CompareOperator,3601 operator: std.math.CompareOperator,
4346) !CValue {3602) !CValue {
4347 const pt = f.object.dg.pt;3603 const pt = f.dg.pt;
4348 const zcu = pt.zcu;3604 const zcu = pt.zcu;
4349 const lhs_ty = f.typeOf(data.lhs);3605 const lhs_ty = f.typeOf(data.lhs);
4350 const scalar_ty = lhs_ty.scalarType(zcu);3606 const scalar_ty = lhs_ty.scalarType(zcu);
...@@ -4369,26 +3625,26 @@ fn airCmpOp(...@@ -4369,26 +3625,26 @@ fn airCmpOp(
43693625
4370 const rhs_ty = f.typeOf(data.rhs);3626 const rhs_ty = f.typeOf(data.rhs);
4371 const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);3627 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;
4373 const local = try f.allocLocal(inst, inst_ty);3629 const local = try f.allocLocal(inst, inst_ty);
4374 const v = try Vectorize.start(f, inst, w, lhs_ty);3630 const v = try Vectorize.start(f, inst, w, lhs_ty);
4375 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));3631 try f.writeCValue(w, local, .other);
4376 try f.writeCValue(w, local, .Other);
4377 try v.elem(f, w);3632 try v.elem(f, w);
4378 try a.assign(f, w);3633 try w.writeAll(" = ");
4379 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {3634 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {
4380 .lt, .neq, .gt => "false",3635 .lt, .neq, .gt => "false",
4381 .lte, .eq, .gte => "true",3636 .lte, .eq, .gte => "true",
4382 }) else {3637 }) else {
4383 if (need_cast) try w.writeAll("(void*)");3638 if (need_cast) try w.writeAll("(void*)");
4384 try f.writeCValue(w, lhs, .Other);3639 try f.writeCValue(w, lhs, .other);
4385 try v.elem(f, w);3640 try v.elem(f, w);
4386 try w.writeAll(compareOperatorC(operator));3641 try w.writeAll(compareOperatorC(operator));
4387 if (need_cast) try w.writeAll("(void*)");3642 if (need_cast) try w.writeAll("(void*)");
4388 try f.writeCValue(w, rhs, .Other);3643 try f.writeCValue(w, rhs, .other);
4389 try v.elem(f, w);3644 try v.elem(f, w);
4390 }3645 }
4391 try a.end(f, w);3646 try w.writeByte(';');
3647 try f.newline();
4392 try v.end(f, inst, w);3648 try v.end(f, inst, w);
43933649
4394 return local;3650 return local;
...@@ -4399,9 +3655,8 @@ fn airEquality(...@@ -4399,9 +3655,8 @@ fn airEquality(
4399 inst: Air.Inst.Index,3655 inst: Air.Inst.Index,
4400 operator: std.math.CompareOperator,3656 operator: std.math.CompareOperator,
4401) !CValue {3657) !CValue {
4402 const pt = f.object.dg.pt;3658 const pt = f.dg.pt;
4403 const zcu = pt.zcu;3659 const zcu = pt.zcu;
4404 const ctype_pool = &f.object.dg.ctype_pool;
4405 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3660 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
44063661
4407 const operand_ty = f.typeOf(bin_op.lhs);3662 const operand_ty = f.typeOf(bin_op.lhs);
...@@ -4422,54 +3677,64 @@ fn airEquality(...@@ -4422,54 +3677,64 @@ fn airEquality(
4422 const rhs = try f.resolveInst(bin_op.rhs);3677 const rhs = try f.resolveInst(bin_op.rhs);
4423 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3678 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;
4426 const local = try f.allocLocal(inst, .bool);3689 const local = try f.allocLocal(inst, .bool);
4427 const a = try Assignment.start(f, w, .bool);3690 try f.writeCValue(w, local, .other);
4428 try f.writeCValue(w, local, .Other);3691 try w.writeAll(" = ");
4429 try a.assign(f, w);
44303692
4431 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);3693 switch (operand_ty.zigTypeTag(zcu)) {
4432 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {3694 .optional => switch (CType.classifyOptional(operand_ty, zcu)) {
4433 .lt, .lte, .gte, .gt => unreachable,3695 .npv_payload => unreachable, // opv optional
4434 .neq => "false",3696
4435 .eq => "true",3697 .error_set, .ptr_like => {},
4436 }) else switch (operand_ctype.info(ctype_pool)) {3698
4437 .basic, .pointer => {3699 .slice_like => unreachable, // equality is not defined on slices
4438 try f.writeCValue(w, lhs, .Other);3700
4439 try w.writeAll(compareOperatorC(operator));3701 .opv_payload => {
4440 try f.writeCValue(w, rhs, .Other);3702 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4441 },3703 try w.writeAll(compareOperatorC(operator));
4442 .aligned, .array, .vector, .fwd_decl, .function => unreachable,3704 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4443 .aggregate => |aggregate| if (aggregate.fields.len == 2 and3705 try w.writeByte(';');
4444 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or3706 try f.newline();
4445 aggregate.fields.at(1, ctype_pool).name.index == .is_null))3707 return local;
4446 {3708 },
4447 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });3709
4448 try w.writeAll(" || ");3710 .@"struct" => {
4449 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });3711 // `lhs.is_null || rhs.is_null ? lhs.is_null == rhs.is_null : lhs.payload == rhs.payload`
4450 try w.writeAll(" ? ");3712 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4451 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });3713 try w.writeAll(" || ");
4452 try w.writeAll(compareOperatorC(operator));3714 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4453 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });3715 try w.writeAll(" ? ");
4454 try w.writeAll(" : ");3716 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4455 try f.writeCValueMember(w, lhs, .{ .identifier = "payload" });3717 try w.writeAll(compareOperatorC(operator));
4456 try w.writeAll(compareOperatorC(operator));3718 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4457 try f.writeCValueMember(w, rhs, .{ .identifier = "payload" });3719 try w.writeAll(" : ");
4458 } else for (0..aggregate.fields.len) |field_index| {3720 try f.writeCValueMember(w, lhs, .{ .identifier = "payload" });
4459 if (field_index > 0) try w.writeAll(switch (operator) {3721 try w.writeAll(compareOperatorC(operator));
4460 .lt, .lte, .gte, .gt => unreachable,3722 try f.writeCValueMember(w, rhs, .{ .identifier = "payload" });
4461 .eq => " && ",3723 try w.writeByte(';');
4462 .neq => " || ",3724 try f.newline();
4463 });3725 return local;
4464 const field_name: CValue = .{3726 },
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);
4470 },3727 },
3728 .bool, .int, .pointer, .@"enum", .error_set => {},
3729 .@"struct", .@"union" => assert(operand_ty.containerLayout(zcu) == .@"packed"),
3730 else => unreachable,
4471 }3731 }
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
4474 return local;3739 return local;
4475}3740}
...@@ -4480,18 +3745,18 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4480,18 +3745,18 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
4480 const operand = try f.resolveInst(un_op);3745 const operand = try f.resolveInst(un_op);
4481 try reap(f, inst, &.{un_op});3746 try reap(f, inst, &.{un_op});
44823747
4483 const w = &f.object.code.writer;3748 const w = &f.code.writer;
4484 const local = try f.allocLocal(inst, .bool);3749 const local = try f.allocLocal(inst, .bool);
4485 try f.writeCValue(w, local, .Other);3750 try f.writeCValue(w, local, .other);
4486 try w.writeAll(" = ");3751 try w.writeAll(" = ");
4487 try f.writeCValue(w, operand, .Other);3752 try f.writeCValue(w, operand, .other);
4488 try w.print(" < sizeof({f}) / sizeof(*{0f});", .{fmtIdentSolo("zig_errorName")});3753 try w.print(" < sizeof({f}) / sizeof(*{0f});", .{fmtIdentSolo("zig_errorName")});
4489 try f.object.newline();3754 try f.newline();
4490 return local;3755 return local;
4491}3756}
44923757
4493fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {3758fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4494 const pt = f.object.dg.pt;3759 const pt = f.dg.pt;
4495 const zcu = pt.zcu;3760 const zcu = pt.zcu;
4496 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3761 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4497 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3762 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 {...@@ -4502,40 +3767,36 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
45023767
4503 const inst_ty = f.typeOfIndex(inst);3768 const inst_ty = f.typeOfIndex(inst);
4504 const inst_scalar_ty = inst_ty.scalarType(zcu);3769 const inst_scalar_ty = inst_ty.scalarType(zcu);
4505 const elem_ty = inst_scalar_ty.elemType2(zcu);3770 const elem_ty = inst_scalar_ty.indexableElem(zcu);
4506 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs);3771 assert(elem_ty.hasRuntimeBits(zcu));
4507 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
45083772
4509 const local = try f.allocLocal(inst, inst_ty);3773 const local = try f.allocLocal(inst, inst_ty);
4510 const w = &f.object.code.writer;3774 const w = &f.code.writer;
4511 const v = try Vectorize.start(f, inst, w, inst_ty);3775 const v = try Vectorize.start(f, inst, w, inst_ty);
4512 const a = try Assignment.start(f, w, inst_scalar_ctype);3776 try f.writeCValue(w, local, .other);
4513 try f.writeCValue(w, local, .Other);
4514 try v.elem(f, w);3777 try v.elem(f, w);
4515 try a.assign(f, w);3778 try w.writeAll(" = ");
4516 // We must convert to and from integer types to prevent UB if the operation3779 // We must convert to and from integer types to prevent UB if the operation
4517 // results in a NULL pointer, or if LHS is NULL. The operation is only UB3780 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
4518 // if the result is NULL and then dereferenced.3781 // if the result is NULL and then dereferenced.
4519 try w.writeByte('(');3782 try w.writeByte('(');
4520 try f.renderCType(w, inst_scalar_ctype);3783 try f.renderType(w, inst_scalar_ty);
4521 try w.writeAll(")(((uintptr_t)");3784 try w.writeAll(")(((uintptr_t)");
4522 try f.writeCValue(w, lhs, .Other);3785 try f.writeCValue(w, lhs, .other);
4523 try v.elem(f, w);3786 try v.elem(f, w);
4524 try w.writeAll(") ");3787 try w.print(") {c} (", .{operator});
4525 try w.writeByte(operator);3788 try f.writeCValue(w, rhs, .other);
4526 try w.writeAll(" (");
4527 try f.writeCValue(w, rhs, .Other);
4528 try v.elem(f, w);3789 try v.elem(f, w);
4529 try w.writeAll("*sizeof(");3790 try w.writeAll("*sizeof(");
4530 try f.renderType(w, elem_ty);3791 try f.renderType(w, elem_ty);
4531 try w.writeAll(")))");3792 try w.writeAll(")));");
4532 try a.end(f, w);3793 try f.newline();
4533 try v.end(f, inst, w);3794 try v.end(f, inst, w);
4534 return local;3795 return local;
4535}3796}
45363797
4537fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {3798fn 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;
4539 const zcu = pt.zcu;3800 const zcu = pt.zcu;
4540 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3801 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...@@ -4549,36 +3810,34 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
4549 const rhs = try f.resolveInst(bin_op.rhs);3810 const rhs = try f.resolveInst(bin_op.rhs);
4550 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3811 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
45513812
4552 const w = &f.object.code.writer;3813 const w = &f.code.writer;
4553 const local = try f.allocLocal(inst, inst_ty);3814 const local = try f.allocLocal(inst, inst_ty);
4554 const v = try Vectorize.start(f, inst, w, inst_ty);3815 const v = try Vectorize.start(f, inst, w, inst_ty);
4555 try f.writeCValue(w, local, .Other);3816 try f.writeCValue(w, local, .other);
4556 try v.elem(f, w);3817 try v.elem(f, w);
4557 // (lhs <> rhs) ? lhs : rhs3818 // (lhs <> rhs) ? lhs : rhs
4558 try w.writeAll(" = (");3819 try w.writeAll(" = (");
4559 try f.writeCValue(w, lhs, .Other);3820 try f.writeCValue(w, lhs, .other);
4560 try v.elem(f, w);3821 try v.elem(f, w);
4561 try w.writeByte(' ');3822 try w.writeByte(' ');
4562 try w.writeByte(operator);3823 try w.writeByte(operator);
4563 try w.writeByte(' ');3824 try w.writeByte(' ');
4564 try f.writeCValue(w, rhs, .Other);3825 try f.writeCValue(w, rhs, .other);
4565 try v.elem(f, w);3826 try v.elem(f, w);
4566 try w.writeAll(") ? ");3827 try w.writeAll(") ? ");
4567 try f.writeCValue(w, lhs, .Other);3828 try f.writeCValue(w, lhs, .other);
4568 try v.elem(f, w);3829 try v.elem(f, w);
4569 try w.writeAll(" : ");3830 try w.writeAll(" : ");
4570 try f.writeCValue(w, rhs, .Other);3831 try f.writeCValue(w, rhs, .other);
4571 try v.elem(f, w);3832 try v.elem(f, w);
4572 try w.writeByte(';');3833 try w.writeByte(';');
4573 try f.object.newline();3834 try f.newline();
4574 try v.end(f, inst, w);3835 try v.end(f, inst, w);
45753836
4576 return local;3837 return local;
4577}3838}
45783839
4579fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {3840fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4580 const pt = f.object.dg.pt;
4581 const zcu = pt.zcu;
4582 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3841 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4583 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3842 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 {...@@ -4587,24 +3846,22 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4587 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3846 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
45883847
4589 const inst_ty = f.typeOfIndex(inst);3848 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;
4593 const local = try f.allocLocal(inst, inst_ty);3851 const local = try f.allocLocal(inst, inst_ty);
4594 {3852
4595 const a = try Assignment.start(f, w, try f.ctypeFromType(ptr_ty, .complete));3853 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
4596 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });3854 try w.writeAll(" = ");
4597 try a.assign(f, w);3855 try f.writeCValue(w, ptr, .other);
4598 try f.writeCValue(w, ptr, .Other);3856 try w.writeByte(';');
4599 try a.end(f, w);3857 try f.newline();
4600 }3858
4601 {3859 try f.writeCValueMember(w, local, .{ .identifier = "len" });
4602 const a = try Assignment.start(f, w, .usize);3860 try w.writeAll(" = ");
4603 try f.writeCValueMember(w, local, .{ .identifier = "len" });3861 try f.writeCValue(w, len, .other);
4604 try a.assign(f, w);3862 try w.writeByte(';');
4605 try f.writeCValue(w, len, .Other);3863 try f.newline();
4606 try a.end(f, w);3864
4607 }
4608 return local;3865 return local;
4609}3866}
46103867
...@@ -4613,14 +3870,14 @@ fn airCall(...@@ -4613,14 +3870,14 @@ fn airCall(
4613 inst: Air.Inst.Index,3870 inst: Air.Inst.Index,
4614 modifier: std.builtin.CallModifier,3871 modifier: std.builtin.CallModifier,
4615) !CValue {3872) !CValue {
4616 const pt = f.object.dg.pt;3873 const pt = f.dg.pt;
4617 const zcu = pt.zcu;3874 const zcu = pt.zcu;
4618 const ip = &zcu.intern_pool;3875 const ip = &zcu.intern_pool;
4619 // Not even allowed to call panic in a naked function.3876 // 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;3879 const gpa = f.dg.gpa;
4623 const w = &f.object.code.writer;3880 const w = &f.code.writer;
46243881
4625 const call = f.air.unwrapCall(inst);3882 const call = f.air.unwrapCall(inst);
4626 const args = call.args;3883 const args = call.args;
...@@ -4629,27 +3886,11 @@ fn airCall(...@@ -4629,27 +3886,11 @@ fn airCall(
4629 defer gpa.free(resolved_args);3886 defer gpa.free(resolved_args);
4630 for (resolved_args, args) |*resolved_arg, arg| {3887 for (resolved_args, args) |*resolved_arg, arg| {
4631 const arg_ty = f.typeOf(arg);3888 const arg_ty = f.typeOf(arg);
4632 const arg_ctype = try f.ctypeFromType(arg_ty, .parameter);3889 if (!arg_ty.hasRuntimeBits(zcu)) {
4633 if (arg_ctype.index == .void) {
4634 resolved_arg.* = .none;3890 resolved_arg.* = .none;
4635 continue;3891 continue;
4636 }3892 }
4637 resolved_arg.* = try f.resolveInst(arg);3893 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 }
4653 }3894 }
46543895
4655 const callee = try f.resolveInst(call.callee);3896 const callee = try f.resolveInst(call.callee);
...@@ -4668,28 +3909,22 @@ fn airCall(...@@ -4668,28 +3909,22 @@ fn airCall(
4668 };3909 };
4669 const fn_info = zcu.typeToFunc(if (callee_is_ptr) callee_ty.childType(zcu) else callee_ty).?;3910 const fn_info = zcu.typeToFunc(if (callee_is_ptr) callee_ty.childType(zcu) else callee_ty).?;
4670 const ret_ty: Type = .fromInterned(fn_info.return_type);3911 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
4676 const result_local = result: {3913 const result_local = result: {
4677 if (modifier == .always_tail) {3914 if (modifier == .always_tail) {
4678 try w.writeAll("zig_always_tail return ");3915 try w.writeAll("zig_always_tail return ");
4679 break :result .none;3916 break :result .none;
4680 } else if (ret_ctype.index == .void) {3917 } else if (!ret_ty.hasRuntimeBits(zcu)) {
4681 break :result .none;3918 break :result .none;
4682 } else if (f.liveness.isUnused(inst)) {3919 } else if (f.liveness.isUnused(inst)) {
4683 try w.writeByte('(');3920 try w.writeAll("(void)");
4684 try f.renderCType(w, .void);
4685 try w.writeByte(')');
4686 break :result .none;3921 break :result .none;
4687 } else {3922 } else {
4688 const local = try f.allocAlignedLocal(inst, .{3923 const local = try f.allocAlignedLocal(inst, .{
4689 .ctype = ret_ctype,3924 .type = ret_ty,
4690 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),3925 .alignment = .none,
4691 });3926 });
4692 try f.writeCValue(w, local, .Other);3927 try f.writeCValue(w, local, .other);
4693 try w.writeAll(" = ");3928 try w.writeAll(" = ");
4694 break :result local;3929 break :result local;
4695 }3930 }
...@@ -4716,8 +3951,19 @@ fn airCall(...@@ -4716,8 +3951,19 @@ fn airCall(
4716 if (!callee_is_ptr) try w.writeByte('&');3951 if (!callee_is_ptr) try w.writeByte('&');
4717 }3952 }
4718 switch (modifier) {3953 switch (modifier) {
4719 .auto, .always_tail => try f.object.dg.renderNavName(w, fn_nav),3954 .auto, .always_tail => try renderNavName(w, fn_nav, ip),
4720 inline .never_tail, .never_inline => |m| try w.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),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 },
4721 else => unreachable,3967 else => unreachable,
4722 }3968 }
4723 if (need_cast) try w.writeByte(')');3969 if (need_cast) try w.writeByte(')');
...@@ -4730,7 +3976,7 @@ fn airCall(...@@ -4730,7 +3976,7 @@ fn airCall(
4730 else => unreachable,3976 else => unreachable,
4731 }3977 }
4732 // Fall back to function pointer call.3978 // Fall back to function pointer call.
4733 try f.writeCValue(w, callee, .Other);3979 try f.writeCValue(w, callee, .other);
4734 }3980 }
47353981
4736 try w.writeByte('(');3982 try w.writeByte('(');
...@@ -4739,38 +3985,20 @@ fn airCall(...@@ -4739,38 +3985,20 @@ fn airCall(
4739 if (resolved_arg == .none) continue;3985 if (resolved_arg == .none) continue;
4740 if (need_comma) try w.writeAll(", ");3986 if (need_comma) try w.writeAll(", ");
4741 need_comma = true;3987 need_comma = true;
4742 try f.writeCValue(w, resolved_arg, .FunctionArgument);3988 try f.writeCValue(w, resolved_arg, .other);
4743 try f.freeCValue(inst, resolved_arg);
4744 }3989 }
4745 try w.writeAll(");");3990 try w.writeAll(");");
4746 switch (modifier) {3991 switch (modifier) {
4747 .always_tail => try w.writeByte('\n'),3992 .always_tail => try w.writeByte('\n'),
4748 else => try f.object.newline(),3993 else => try f.newline(),
4749 }3994 }
47503995
4751 const result = result: {3996 return result_local;
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;
4769}3997}
47703998
4771fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {3999fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4772 const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;4000 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;
4774 // TODO re-evaluate whether to emit these or not. If we naively emit4002 // TODO re-evaluate whether to emit these or not. If we naively emit
4775 // these directives, the output file will report bogus line numbers because4003 // these directives, the output file will report bogus line numbers because
4776 // every newline after the #line directive adds one to the line.4004 // every newline after the #line directive adds one to the line.
...@@ -4779,32 +4007,32 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4779,32 +4007,32 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4779 // newlines until the next dbg_stmt occurs.4007 // newlines until the next dbg_stmt occurs.
4780 // Perhaps an additional compilation option is in order?4008 // Perhaps an additional compilation option is in order?
4781 //try w.print("#line {d}", .{dbg_stmt.line + 1});4009 //try w.print("#line {d}", .{dbg_stmt.line + 1});
4782 //try f.object.newline();4010 //try f.newline();
4783 try w.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });4011 try w.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4784 try f.object.newline();4012 try f.newline();
4785 return .none;4013 return .none;
4786}4014}
47874015
4788fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {4016fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {
4789 try f.object.code.writer.writeAll("(void)0;");4017 try f.code.writer.writeAll("(void)0;");
4790 try f.object.newline();4018 try f.newline();
4791 return .none;4019 return .none;
4792}4020}
47934021
4794fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {4022fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4795 const pt = f.object.dg.pt;4023 const pt = f.dg.pt;
4796 const zcu = pt.zcu;4024 const zcu = pt.zcu;
4797 const ip = &zcu.intern_pool;4025 const ip = &zcu.intern_pool;
4798 const block = f.air.unwrapDbgBlock(inst);4026 const block = f.air.unwrapDbgBlock(inst);
4799 const owner_nav = ip.getNav(zcu.funcInfo(block.func).owner_nav);4027 const owner_nav = ip.getNav(zcu.funcInfo(block.func).owner_nav);
4800 const w = &f.object.code.writer;4028 const w = &f.code.writer;
4801 try w.print("/* inline:{f} */", .{owner_nav.fqn.fmt(&zcu.intern_pool)});4029 try w.print("/* inline:{f} */", .{owner_nav.fqn.fmt(&zcu.intern_pool)});
4802 try f.object.newline();4030 try f.newline();
4803 return lowerBlock(f, inst, block.body);4031 return lowerBlock(f, inst, block.body);
4804}4032}
48054033
4806fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {4034fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4807 const pt = f.object.dg.pt;4035 const pt = f.dg.pt;
4808 const zcu = pt.zcu;4036 const zcu = pt.zcu;
4809 const tag = f.air.instructions.items(.tag)[@intFromEnum(inst)];4037 const tag = f.air.instructions.items(.tag)[@intFromEnum(inst)];
4810 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4038 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 {...@@ -4813,9 +4041,9 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4813 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4041 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
48144042
4815 try reap(f, inst, &.{pl_op.operand});4043 try reap(f, inst, &.{pl_op.operand});
4816 const w = &f.object.code.writer;4044 const w = &f.code.writer;
4817 try w.print("/* {s}:{s} */", .{ @tagName(tag), name.toSlice(f.air) });4045 try w.print("/* {s}:{s} */", .{ @tagName(tag), name.toSlice(f.air) });
4818 try f.object.newline();4046 try f.newline();
4819 return .none;4047 return .none;
4820}4048}
48214049
...@@ -4825,21 +4053,21 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4825,21 +4053,21 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4825}4053}
48264054
4827fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue {4055fn 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;
4829 const zcu = pt.zcu;4057 const zcu = pt.zcu;
4830 const liveness_block = f.liveness.getBlock(inst);4058 const liveness_block = f.liveness.getBlock(inst);
48314059
4832 const block_id = f.next_block_index;4060 const block_id = f.next_block_index;
4833 f.next_block_index += 1;4061 f.next_block_index += 1;
4834 const w = &f.object.code.writer;4062 const w = &f.code.writer;
48354063
4836 const inst_ty = f.typeOfIndex(inst);4064 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))
4838 try f.allocLocal(inst, inst_ty)4066 try f.allocLocal(inst, inst_ty)
4839 else4067 else
4840 .none;4068 .none;
48414069
4842 try f.blocks.putNoClobber(f.object.dg.gpa, inst, .{4070 try f.blocks.putNoClobber(f.dg.gpa, inst, .{
4843 .block_id = block_id,4071 .block_id = block_id,
4844 .result = result,4072 .result = result,
4845 });4073 });
...@@ -4854,23 +4082,23 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -4854,23 +4082,23 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
4854 }4082 }
48554083
4856 // noreturn blocks have no `br` instructions reaching them, so we don't want a label4084 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
4857 if (f.object.dg.is_naked_fn) {4085 if (f.dg.is_naked_fn) {
4858 if (f.object.dg.expected_block) |expected_block| {4086 if (f.dg.expected_block) |expected_block| {
4859 if (block_id != expected_block)4087 if (block_id != expected_block)
4860 return f.fail("runtime code not allowed in naked function", .{});4088 return f.fail("runtime code not allowed in naked function", .{});
4861 f.object.dg.expected_block = null;4089 f.dg.expected_block = null;
4862 }4090 }
4863 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {4091 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {
4864 // label must be followed by an expression, include an empty one.4092 // label must be followed by an expression, include an empty one.
4865 try w.print("\nzig_block_{d}:;", .{block_id});4093 try w.print("\nzig_block_{d}:;", .{block_id});
4866 try f.object.newline();4094 try f.newline();
4867 }4095 }
48684096
4869 return result;4097 return result;
4870}4098}
48714099
4872fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {4100fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
4873 const pt = f.object.dg.pt;4101 const pt = f.dg.pt;
4874 const unwrapped_try = f.air.unwrapTry(inst);4102 const unwrapped_try = f.air.unwrapTry(inst);
4875 const body = unwrapped_try.else_body;4103 const body = unwrapped_try.else_body;
4876 const err_union_ty = f.air.typeOf(unwrapped_try.error_union, &pt.zcu.intern_pool);4104 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 {...@@ -4878,7 +4106,7 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
4878}4106}
48794107
4880fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {4108fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4881 const pt = f.object.dg.pt;4109 const pt = f.dg.pt;
4882 const unwrapped_try = f.air.unwrapTryPtr(inst);4110 const unwrapped_try = f.air.unwrapTryPtr(inst);
4883 const body = unwrapped_try.else_body;4111 const body = unwrapped_try.else_body;
4884 const err_union_ty = f.air.typeOf(unwrapped_try.error_union_ptr, &pt.zcu.intern_pool).childType(pt.zcu);4112 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(...@@ -4893,46 +4121,38 @@ fn lowerTry(
4893 err_union_ty: Type,4121 err_union_ty: Type,
4894 is_ptr: bool,4122 is_ptr: bool,
4895) !CValue {4123) !CValue {
4896 const pt = f.object.dg.pt;4124 const pt = f.dg.pt;
4897 const zcu = pt.zcu;4125 const zcu = pt.zcu;
4898 const err_union = try f.resolveInst(operand);4126 const err_union = try f.resolveInst(operand);
4899 const inst_ty = f.typeOfIndex(inst);4127 const inst_ty = f.typeOfIndex(inst);
4900 const liveness_condbr = f.liveness.getCondBr(inst);4128 const liveness_condbr = f.liveness.getCondBr(inst);
4901 const w = &f.object.code.writer;4129 const w = &f.code.writer;
4902 const payload_ty = err_union_ty.errorUnionPayload(zcu);4130 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)) {4132 try w.writeAll("if (");
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(") ");
49234133
4924 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);4134 // Reap the operand so that it can be reused inside genBody.
4925 try f.object.newline();4135 // Remember we must avoid calling reap() twice for the same operand
4926 if (f.object.dg.expected_block) |_|4136 // in this function.
4927 return f.fail("runtime code not allowed in naked function", .{});4137 try reap(f, inst, &.{operand});
4928 }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
4930 // Now we have the "then branch" (in terms of the liveness data); process any deaths.4150 // Now we have the "then branch" (in terms of the liveness data); process any deaths.
4931 for (liveness_condbr.then_deaths) |death| {4151 for (liveness_condbr.then_deaths) |death| {
4932 try die(f, inst, death.toRef());4152 try die(f, inst, death.toRef());
4933 }4153 }
49344154
4935 if (!payload_has_bits) {4155 if (!payload_ty.hasRuntimeBits(zcu)) {
4936 if (!is_ptr) {4156 if (!is_ptr) {
4937 return .none;4157 return .none;
4938 } else {4158 } else {
...@@ -4945,14 +4165,14 @@ fn lowerTry(...@@ -4945,14 +4165,14 @@ fn lowerTry(
4945 if (f.liveness.isUnused(inst)) return .none;4165 if (f.liveness.isUnused(inst)) return .none;
49464166
4947 const local = try f.allocLocal(inst, inst_ty);4167 const local = try f.allocLocal(inst, inst_ty);
4948 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));4168 try f.writeCValue(w, local, .other);
4949 try f.writeCValue(w, local, .Other);4169 try w.writeAll(" = ");
4950 try a.assign(f, w);
4951 if (is_ptr) {4170 if (is_ptr) {
4952 try w.writeByte('&');4171 try w.writeByte('&');
4953 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "payload" });4172 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "payload" });
4954 } else try f.writeCValueMember(w, err_union, .{ .identifier = "payload" });4173 } else try f.writeCValueMember(w, err_union, .{ .identifier = "payload" });
4955 try a.end(f, w);4174 try w.writeByte(';');
4175 try f.newline();
4956 return local;4176 return local;
4957}4177}
49584178
...@@ -4960,25 +4180,24 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -4960,25 +4180,24 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
4960 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;4180 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
4961 const block = f.blocks.get(branch.block_inst).?;4181 const block = f.blocks.get(branch.block_inst).?;
4962 const result = block.result;4182 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) {
4966 if (result != .none) return f.fail("runtime code not allowed in naked function", .{});4186 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;
4968 return;4188 return;
4969 }4189 }
49704190
4971 // If result is .none then the value of the block is unused.4191 // If result is .none then the value of the block is unused.
4972 if (result != .none) {4192 if (result != .none) {
4973 const operand_ty = f.typeOf(branch.operand);
4974 const operand = try f.resolveInst(branch.operand);4193 const operand = try f.resolveInst(branch.operand);
4975 try reap(f, inst, &.{branch.operand});4194 try reap(f, inst, &.{branch.operand});
49764195
4977 const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));4196 try f.writeCValue(w, result, .other);
4978 try f.writeCValue(w, result, .Other);4197 try w.writeAll(" = ");
4979 try a.assign(f, w);4198 try f.writeCValue(w, operand, .other);
4980 try f.writeCValue(w, operand, .Other);4199 try w.writeByte(';');
4981 try a.end(f, w);4200 try f.newline();
4982 }4201 }
49834202
4984 try w.print("goto zig_block_{d};\n", .{block.block_id});4203 try w.print("goto zig_block_{d};\n", .{block.block_id});
...@@ -4986,14 +4205,14 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -4986,14 +4205,14 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
49864205
4987fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {4206fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {
4988 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;4207 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)});
4990}4209}
49914210
4992fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {4211fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
4993 const pt = f.object.dg.pt;4212 const pt = f.dg.pt;
4994 const zcu = pt.zcu;4213 const zcu = pt.zcu;
4995 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;4214 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
4996 const w = &f.object.code.writer;4215 const w = &f.code.writer;
49974216
4998 if (try f.air.value(br.operand, pt)) |cond_val| {4217 if (try f.air.value(br.operand, pt)) |cond_val| {
4999 // Comptime-known dispatch. Iterate the cases to find the correct4218 // Comptime-known dispatch. Iterate the cases to find the correct
...@@ -5022,11 +4241,11 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {...@@ -5022,11 +4241,11 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
5022 // Runtime-known dispatch. Set the switch condition, and branch back.4241 // Runtime-known dispatch. Set the switch condition, and branch back.
5023 const cond = try f.resolveInst(br.operand);4242 const cond = try f.resolveInst(br.operand);
5024 const cond_local = f.loop_switch_conds.get(br.block_inst).?;4243 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);
5026 try w.writeAll(" = ");4245 try w.writeAll(" = ");
5027 try f.writeCValue(w, cond, .Other);4246 try f.writeCValue(w, cond, .other);
5028 try w.writeByte(';');4247 try w.writeByte(';');
5029 try f.object.newline();4248 try f.newline();
5030 try w.print("goto zig_switch_{d}_loop;\n", .{@intFromEnum(br.block_inst)});4249 try w.print("goto zig_switch_{d}_loop;\n", .{@intFromEnum(br.block_inst)});
5031}4250}
50324251
...@@ -5043,11 +4262,10 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5043,11 +4262,10 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
5043}4262}
50444263
5045fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue {4264fn 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;
5047 const zcu = pt.zcu;4266 const zcu = pt.zcu;
5048 const target = &f.object.dg.mod.resolved_target.result;4267 const target = &f.dg.mod.resolved_target.result;
5049 const ctype_pool = &f.object.dg.ctype_pool;4268 const w = &f.code.writer;
5050 const w = &f.object.code.writer;
50514269
5052 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {4270 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {
5053 const src_info = dest_ty.intInfo(zcu);4271 const src_info = dest_ty.intInfo(zcu);
...@@ -5058,26 +4276,16 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5058,26 +4276,16 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
50584276
5059 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {4277 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {
5060 const local = try f.allocLocal(null, dest_ty);4278 const local = try f.allocLocal(null, dest_ty);
5061 try f.writeCValue(w, local, .Other);4279 try f.writeCValue(w, local, .other);
5062 try w.writeAll(" = (");4280 try w.writeAll(" = (");
5063 try f.renderType(w, dest_ty);4281 try f.renderType(w, dest_ty);
5064 try w.writeByte(')');4282 try w.writeByte(')');
5065 try f.writeCValue(w, operand, .Other);4283 try f.writeCValue(w, operand, .other);
5066 try w.writeByte(';');4284 try w.writeByte(';');
5067 try f.object.newline();4285 try f.newline();
5068 return local;4286 return local;
5069 }4287 }
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
5081 const local = try f.allocLocal(null, dest_ty);4289 const local = try f.allocLocal(null, dest_ty);
5082 // On big-endian targets, copying ABI integers with padding bits is awkward, because the padding bits are at the low bytes of the value.4290 // On big-endian targets, copying ABI integers with padding bits is awkward, because the padding bits are at the low bytes of the value.
5083 // We need to offset the source or destination pointer appropriately and copy the right number of bytes.4291 // 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...@@ -5085,141 +4293,134 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5085 // e.g. [10]u8 -> u80. We need to offset the destination so that we copy to the least significant bits of the integer.4293 // e.g. [10]u8 -> u80. We need to offset the destination so that we copy to the least significant bits of the integer.
5086 const offset = dest_ty.abiSize(zcu) - operand_ty.abiSize(zcu);4294 const offset = dest_ty.abiSize(zcu) - operand_ty.abiSize(zcu);
5087 try w.writeAll("memcpy((char *)&");4295 try w.writeAll("memcpy((char *)&");
5088 try f.writeCValue(w, local, .Other);4296 try f.writeCValue(w, local, .other);
5089 try w.print(" + {d}, &", .{offset});4297 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 }
5091 try w.print(", {d});", .{operand_ty.abiSize(zcu)});4302 try w.print(", {d});", .{operand_ty.abiSize(zcu)});
5092 } else if (target.cpu.arch.endian() == .big and operand_ty.isAbiInt(zcu) and !dest_ty.isAbiInt(zcu)) {4303 } else if (target.cpu.arch.endian() == .big and operand_ty.isAbiInt(zcu) and !dest_ty.isAbiInt(zcu)) {
5093 // e.g. u80 -> [10]u8. We need to offset the source so that we copy from the least significant bits of the integer.4304 // e.g. u80 -> [10]u8. We need to offset the source so that we copy from the least significant bits of the integer.
5094 const offset = operand_ty.abiSize(zcu) - dest_ty.abiSize(zcu);4305 const offset = operand_ty.abiSize(zcu) - dest_ty.abiSize(zcu);
5095 try w.writeAll("memcpy(&");4306 try w.writeAll("memcpy(&");
5096 try f.writeCValue(w, local, .Other);4307 try f.writeCValue(w, local, .other);
5097 try w.writeAll(", (const char *)&");4308 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 }
5099 try w.print(" + {d}, {d});", .{ offset, dest_ty.abiSize(zcu) });4313 try w.print(" + {d}, {d});", .{ offset, dest_ty.abiSize(zcu) });
5100 } else {4314 } else {
5101 try w.writeAll("memcpy(&");4315 try w.writeAll("memcpy(&");
5102 try f.writeCValue(w, local, .Other);4316 try f.writeCValue(w, local, .other);
5103 try w.writeAll(", &");4317 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 }
5105 try w.print(", {d});", .{@min(dest_ty.abiSize(zcu), operand_ty.abiSize(zcu))});4322 try w.print(", {d});", .{@min(dest_ty.abiSize(zcu), operand_ty.abiSize(zcu))});
5106 }4323 }
51074324
5108 try f.object.newline();4325 try f.newline();
51094326
5110 // Ensure padding bits have the expected value.4327 // Ensure padding bits have the expected value.
5111 if (dest_ty.isAbiInt(zcu)) {4328 if (dest_ty.isAbiInt(zcu)) {
5112 const dest_ctype = try f.ctypeFromType(dest_ty, .complete);4329 switch (CType.classifyInt(dest_ty, zcu)) {
5113 const dest_info = dest_ty.intInfo(zcu);4330 .void => unreachable, // opv
5114 var bits: u16 = dest_info.bits;4331 .small => {
5115 var wrap_ctype: ?CType = null;4332 try f.writeCValue(w, local, .other);
5116 var need_bitcasts = false;4333 try w.writeAll(" = zig_wrap_");
51174334 try f.dg.renderTypeForBuiltinFnName(w, dest_ty);
5118 try f.writeCValue(w, local, .Other);4335 try w.writeByte('(');
5119 switch (dest_ctype.info(ctype_pool)) {4336 try f.writeCValue(w, local, .other);
5120 else => {},4337 try f.dg.renderBuiltinInfo(w, dest_ty, .bits);
5121 .array => |array_info| {4338 try w.writeAll(");");
5122 try w.print("[{d}]", .{switch (target.cpu.arch.endian()) {4339 try f.newline();
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;
5131 },4340 },
5132 }4341 .big => |big| {
5133 try w.writeAll(" = ");4342 const dest_info = dest_ty.intInfo(zcu);
5134 if (need_bitcasts) {4343 const padding_index: u16 = switch (target.cpu.arch.endian()) {
5135 try w.writeAll("zig_bitCast_");4344 .little => big.limbs_len - 1,
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,
5157 .big => 0,4345 .big => 0,
5158 },4346 };
5159 }),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 },
5160 }4367 }
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();
5166 }4368 }
51674369
5168 try f.freeCValue(null, operand_lval);
5169 return local;4370 return local;
5170}4371}
51714372
5172fn airTrap(f: *Function, w: *Writer) !void {4373fn airTrap(f: *Function) !void {
5173 // Not even allowed to call trap in a naked function.4374 // Not even allowed to call trap in a naked function.
5174 if (f.object.dg.is_naked_fn) return;4375 if (f.dg.is_naked_fn) return;
5175 try w.writeAll("zig_trap();\n");4376 try f.code.writer.writeAll("zig_trap();\n");
5176}4377}
51774378
5178fn airBreakpoint(f: *Function) !CValue {4379fn airBreakpoint(f: *Function) !CValue {
5179 const w = &f.object.code.writer;4380 const w = &f.code.writer;
5180 try w.writeAll("zig_breakpoint();");4381 try w.writeAll("zig_breakpoint();");
5181 try f.object.newline();4382 try f.newline();
5182 return .none;4383 return .none;
5183}4384}
51844385
5185fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {4386fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
5186 const w = &f.object.code.writer;4387 const w = &f.code.writer;
5187 const local = try f.allocLocal(inst, .usize);4388 const local = try f.allocLocal(inst, .usize);
5188 try f.writeCValue(w, local, .Other);4389 try f.writeCValue(w, local, .other);
5189 try w.writeAll(" = (");4390 try w.writeAll(" = (");
5190 try f.renderType(w, .usize);4391 try f.renderType(w, .usize);
5191 try w.writeAll(")zig_return_address();");4392 try w.writeAll(")zig_return_address();");
5192 try f.object.newline();4393 try f.newline();
5193 return local;4394 return local;
5194}4395}
51954396
5196fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {4397fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
5197 const w = &f.object.code.writer;4398 const w = &f.code.writer;
5198 const local = try f.allocLocal(inst, .usize);4399 const local = try f.allocLocal(inst, .usize);
5199 try f.writeCValue(w, local, .Other);4400 try f.writeCValue(w, local, .other);
5200 try w.writeAll(" = (");4401 try w.writeAll(" = (");
5201 try f.renderType(w, .usize);4402 try f.renderType(w, .usize);
5202 try w.writeAll(")zig_frame_address();");4403 try w.writeAll(")zig_frame_address();");
5203 try f.object.newline();4404 try f.newline();
5204 return local;4405 return local;
5205}4406}
52064407
5207fn airUnreach(o: *Object) !void {4408fn airUnreach(f: *Function) !void {
5208 // Not even allowed to call unreachable in a naked function.4409 // Not even allowed to call unreachable in a naked function.
5209 if (o.dg.is_naked_fn) return;4410 if (f.dg.is_naked_fn) return;
5210 try o.code.writer.writeAll("zig_unreachable();\n");4411 try f.code.writer.writeAll("zig_unreachable();\n");
5211}4412}
52124413
5213fn airLoop(f: *Function, inst: Air.Inst.Index) !void {4414fn airLoop(f: *Function, inst: Air.Inst.Index) !void {
5214 const block = f.air.unwrapBlock(inst);4415 const block = f.air.unwrapBlock(inst);
5215 const w = &f.object.code.writer;4416 const w = &f.code.writer;
52164417
5217 // `repeat` instructions matching this loop will branch to4418 // `repeat` instructions matching this loop will branch to
5218 // this label. Since we need a label for arbitrary `repeat`4419 // this label. Since we need a label for arbitrary `repeat`
5219 // anyway, there's actually no need to use a "real" looping4420 // anyway, there's actually no need to use a "real" looping
5220 // construct at all!4421 // construct at all!
5221 try w.print("zig_loop_{d}:", .{@intFromEnum(inst)});4422 try w.print("zig_loop_{d}:", .{@intFromEnum(inst)});
5222 try f.object.newline();4423 try f.newline();
5223 try genBodyInner(f, block.body); // no need to restore state, we're noreturn4424 try genBodyInner(f, block.body); // no need to restore state, we're noreturn
5224}4425}
52254426
...@@ -5230,15 +4431,15 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -5230,15 +4431,15 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
5230 const then_body = cond_br.then_body;4431 const then_body = cond_br.then_body;
5231 const else_body = cond_br.else_body;4432 const else_body = cond_br.else_body;
5232 const liveness_condbr = f.liveness.getCondBr(inst);4433 const liveness_condbr = f.liveness.getCondBr(inst);
5233 const w = &f.object.code.writer;4434 const w = &f.code.writer;
52344435
5235 try w.writeAll("if (");4436 try w.writeAll("if (");
5236 try f.writeCValue(w, cond, .Other);4437 try f.writeCValue(w, cond, .other);
5237 try w.writeAll(") ");4438 try w.writeAll(") ");
52384439
5239 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);4440 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
5240 try f.object.newline();4441 try f.newline();
5241 if (else_body.len > 0) if (f.object.dg.expected_block) |_|4442 if (else_body.len > 0) if (f.dg.expected_block) |_|
5242 return f.fail("runtime code not allowed in naked function", .{});4443 return f.fail("runtime code not allowed in naked function", .{});
52434444
5244 // We don't need to use `genBodyResolveState` for the else block, because this instruction is4445 // 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 {...@@ -5256,23 +4457,23 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
5256}4457}
52574458
5258fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void {4459fn 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;
5260 const zcu = pt.zcu;4461 const zcu = pt.zcu;
5261 const gpa = f.object.dg.gpa;4462 const gpa = f.dg.gpa;
5262 const switch_br = f.air.unwrapSwitch(inst);4463 const switch_br = f.air.unwrapSwitch(inst);
5263 const init_condition = try f.resolveInst(switch_br.operand);4464 const init_condition = try f.resolveInst(switch_br.operand);
5264 try reap(f, inst, &.{switch_br.operand});4465 try reap(f, inst, &.{switch_br.operand});
5265 const condition_ty = f.typeOf(switch_br.operand);4466 const condition_ty = f.typeOf(switch_br.operand);
5266 const w = &f.object.code.writer;4467 const w = &f.code.writer;
52674468
5268 // For dispatches, we will create a local alloc to contain the condition value.4469 // For dispatches, we will create a local alloc to contain the condition value.
5269 // This may not result in optimal codegen for switch loops, but it minimizes the4470 // This may not result in optimal codegen for switch loops, but it minimizes the
5270 // amount of C code we generate, which is probably more desirable here (and is simpler).4471 // amount of C code we generate, which is probably more desirable here (and is simpler).
5271 const condition = if (is_dispatch_loop) cond: {4472 const condition = if (is_dispatch_loop) cond: {
5272 const new_local = try f.allocLocal(inst, condition_ty);4473 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);
5274 try w.print("zig_switch_{d}_loop:", .{@intFromEnum(inst)});4475 try w.print("zig_switch_{d}_loop:", .{@intFromEnum(inst)});
5275 try f.object.newline();4476 try f.newline();
5276 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);4477 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);
5277 break :cond new_local;4478 break :cond new_local;
5278 } else init_condition;4479 } else init_condition;
...@@ -5294,9 +4495,9 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5294,9 +4495,9 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5294 try f.renderType(w, lowered_condition_ty);4495 try f.renderType(w, lowered_condition_ty);
5295 try w.writeByte(')');4496 try w.writeByte(')');
5296 }4497 }
5297 try f.writeCValue(w, condition, .Other);4498 try f.writeCValue(w, condition, .other);
5298 try w.writeAll(") {");4499 try w.writeAll(") {");
5299 f.object.indent();4500 f.indent();
53004501
5301 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);4502 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);
5302 defer gpa.free(liveness.deaths);4503 defer gpa.free(liveness.deaths);
...@@ -5309,7 +4510,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5309,7 +4510,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5309 continue;4510 continue;
5310 }4511 }
5311 for (case.items) |item| {4512 for (case.items) |item| {
5312 try f.object.newline();4513 try f.newline();
5313 try w.writeAll("case ");4514 try w.writeAll("case ");
5314 const item_value = try f.air.value(item, pt);4515 const item_value = try f.air.value(item, pt);
5315 // If `item_value` is a pointer with a known integer address, print the address4516 // 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...@@ -5326,28 +4527,28 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5326 try f.renderType(w, .usize);4527 try f.renderType(w, .usize);
5327 try w.writeByte(')');4528 try w.writeByte(')');
5328 }4529 }
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);
5330 }4531 }
5331 try w.writeByte(':');4532 try w.writeByte(':');
5332 }4533 }
5333 try w.writeAll(" {");4534 try w.writeAll(" {");
5334 f.object.indent();4535 f.indent();
5335 try f.object.newline();4536 try f.newline();
5336 if (is_dispatch_loop) {4537 if (is_dispatch_loop) {
5337 try w.print("zig_switch_{d}_dispatch_{d}:;", .{ @intFromEnum(inst), case.idx });4538 try w.print("zig_switch_{d}_dispatch_{d}:;", .{ @intFromEnum(inst), case.idx });
5338 try f.object.newline();4539 try f.newline();
5339 }4540 }
5340 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);4541 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5341 try f.object.outdent();4542 try f.outdent();
5342 try w.writeByte('}');4543 try w.writeByte('}');
5343 if (f.object.dg.expected_block) |_|4544 if (f.dg.expected_block) |_|
5344 return f.fail("runtime code not allowed in naked function", .{});4545 return f.fail("runtime code not allowed in naked function", .{});
53454546
5346 // The case body must be noreturn so we don't need to insert a break.4547 // The case body must be noreturn so we don't need to insert a break.
5347 }4548 }
53484549
5349 const else_body = it.elseBody();4550 const else_body = it.elseBody();
5350 try f.object.newline();4551 try f.newline();
53514552
5352 try w.writeAll("default: ");4553 try w.writeAll("default: ");
5353 if (any_range_cases) {4554 if (any_range_cases) {
...@@ -5360,33 +4561,33 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5360,33 +4561,33 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5360 try w.writeAll("if (");4561 try w.writeAll("if (");
5361 for (case.items, 0..) |item, item_i| {4562 for (case.items, 0..) |item, item_i| {
5362 if (item_i != 0) try w.writeAll(" || ");4563 if (item_i != 0) try w.writeAll(" || ");
5363 try f.writeCValue(w, condition, .Other);4564 try f.writeCValue(w, condition, .other);
5364 try w.writeAll(" == ");4565 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);
5366 }4567 }
5367 for (case.ranges, 0..) |range, range_i| {4568 for (case.ranges, 0..) |range, range_i| {
5368 if (case.items.len != 0 or range_i != 0) try w.writeAll(" || ");4569 if (case.items.len != 0 or range_i != 0) try w.writeAll(" || ");
5369 // "(x >= lower && x <= upper)"4570 // "(x >= lower && x <= upper)"
5370 try w.writeByte('(');4571 try w.writeByte('(');
5371 try f.writeCValue(w, condition, .Other);4572 try f.writeCValue(w, condition, .other);
5372 try w.writeAll(" >= ");4573 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);
5374 try w.writeAll(" && ");4575 try w.writeAll(" && ");
5375 try f.writeCValue(w, condition, .Other);4576 try f.writeCValue(w, condition, .other);
5376 try w.writeAll(" <= ");4577 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);
5378 try w.writeByte(')');4579 try w.writeByte(')');
5379 }4580 }
5380 try w.writeAll(") {");4581 try w.writeAll(") {");
5381 f.object.indent();4582 f.indent();
5382 try f.object.newline();4583 try f.newline();
5383 if (is_dispatch_loop) {4584 if (is_dispatch_loop) {
5384 try w.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });4585 try w.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
5385 }4586 }
5386 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);4587 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5387 try f.object.outdent();4588 try f.outdent();
5388 try w.writeByte('}');4589 try w.writeByte('}');
5389 if (f.object.dg.expected_block) |_|4590 if (f.dg.expected_block) |_|
5390 return f.fail("runtime code not allowed in naked function", .{});4591 return f.fail("runtime code not allowed in naked function", .{});
5391 }4592 }
5392 }4593 }
...@@ -5400,16 +4601,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5400,16 +4601,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5400 try die(f, inst, death.toRef());4601 try die(f, inst, death.toRef());
5401 }4602 }
5402 try genBody(f, else_body);4603 try genBody(f, else_body);
5403 if (f.object.dg.expected_block) |_|4604 if (f.dg.expected_block) |_|
5404 return f.fail("runtime code not allowed in naked function", .{});4605 return f.fail("runtime code not allowed in naked function", .{});
5405 } else try airUnreach(&f.object);4606 } else try airUnreach(f);
5406 try f.object.newline();4607 try f.newline();
5407 try f.object.outdent();4608 try f.outdent();
5408 try w.writeAll("}\n");4609 try w.writeAll("}\n");
5409}4610}
54104611
5411fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {4612fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
5412 const dg = f.object.dg;4613 const dg = f.dg;
5413 const target = &dg.mod.resolved_target.result;4614 const target = &dg.mod.resolved_target.result;
5414 return switch (constraint[0]) {4615 return switch (constraint[0]) {
5415 '{' => true,4616 '{' => true,
...@@ -5429,28 +4630,28 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool...@@ -5429,28 +4630,28 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
5429}4630}
54304631
5431fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {4632fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5432 const pt = f.object.dg.pt;4633 const pt = f.dg.pt;
5433 const zcu = pt.zcu;4634 const zcu = pt.zcu;
5434 const unwrapped_asm = f.air.unwrapAsm(inst);4635 const unwrapped_asm = f.air.unwrapAsm(inst);
5435 const is_volatile = unwrapped_asm.is_volatile;4636 const is_volatile = unwrapped_asm.is_volatile;
5436 const gpa = f.object.dg.gpa;4637 const gpa = f.dg.gpa;
5437 const outputs = unwrapped_asm.outputs;4638 const outputs = unwrapped_asm.outputs;
5438 const inputs = unwrapped_asm.inputs;4639 const inputs = unwrapped_asm.inputs;
54394640
5440 const result = result: {4641 const result = result: {
5441 const w = &f.object.code.writer;4642 const w = &f.code.writer;
5442 const inst_ty = f.typeOfIndex(inst);4643 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: {
5444 const inst_local = try f.allocLocalValue(.{4645 const inst_local = try f.allocLocalValue(.{
5445 .ctype = try f.ctypeFromType(inst_ty, .complete),4646 .type = inst_ty,
5446 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),4647 .alignment = .none,
5447 });4648 });
5448 if (f.wantSafety()) {4649 if (f.wantSafety()) {
5449 try f.writeCValue(w, inst_local, .Other);4650 try f.writeCValue(w, inst_local, .other);
5450 try w.writeAll(" = ");4651 try w.writeAll(" = ");
5451 try f.writeCValue(w, .{ .undef = inst_ty }, .Other);4652 try f.writeCValue(w, .{ .undef = inst_ty }, .other);
5452 try w.writeByte(';');4653 try w.writeByte(';');
5453 try f.object.newline();4654 try f.newline();
5454 }4655 }
5455 break :local inst_local;4656 break :local inst_local;
5456 } else .none;4657 } else .none;
...@@ -5471,20 +4672,20 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5471,20 +4672,20 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5471 const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu);4672 const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu);
5472 try w.writeAll("register ");4673 try w.writeAll("register ");
5473 const output_local = try f.allocLocalValue(.{4674 const output_local = try f.allocLocalValue(.{
5474 .ctype = try f.ctypeFromType(output_ty, .complete),4675 .type = output_ty,
5475 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),4676 .alignment = .none,
5476 });4677 });
5477 try f.allocs.put(gpa, output_local.new_local, false);4678 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);
5479 try w.writeAll(" __asm(\"");4680 try w.writeAll(" __asm(\"");
5480 try w.writeAll(constraint["={".len .. constraint.len - "}".len]);4681 try w.writeAll(constraint["={".len .. constraint.len - "}".len]);
5481 try w.writeAll("\")");4682 try w.writeAll("\")");
5482 if (f.wantSafety()) {4683 if (f.wantSafety()) {
5483 try w.writeAll(" = ");4684 try w.writeAll(" = ");
5484 try f.writeCValue(w, .{ .undef = output_ty }, .Other);4685 try f.writeCValue(w, .{ .undef = output_ty }, .other);
5485 }4686 }
5486 try w.writeByte(';');4687 try w.writeByte(';');
5487 try f.object.newline();4688 try f.newline();
5488 }4689 }
5489 }4690 }
54904691
...@@ -5504,29 +4705,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5504,29 +4705,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5504 const input_ty = f.typeOf(input.operand);4705 const input_ty = f.typeOf(input.operand);
5505 if (is_reg) try w.writeAll("register ");4706 if (is_reg) try w.writeAll("register ");
5506 const input_local = try f.allocLocalValue(.{4707 const input_local = try f.allocLocalValue(.{
5507 .ctype = try f.ctypeFromType(input_ty, .complete),4708 .type = input_ty,
5508 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),4709 .alignment = .none,
5509 });4710 });
5510 try f.allocs.put(gpa, input_local.new_local, false);4711 try f.allocs.put(gpa, input_local.new_local, false);
5511 // Do not render the declaration as `const` qualified if we're generating an4712 // Do not render the declaration as `const` qualified if we're generating an
5512 // explicit `register` local, as GCC will ignore the constraint completely.4713 // 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);
5514 if (is_reg) {4715 if (is_reg) {
5515 try w.writeAll(" __asm(\"");4716 try w.writeAll(" __asm(\"");
5516 try w.writeAll(constraint["{".len .. constraint.len - "}".len]);4717 try w.writeAll(constraint["{".len .. constraint.len - "}".len]);
5517 try w.writeAll("\")");4718 try w.writeAll("\")");
5518 }4719 }
5519 try w.writeAll(" = ");4720 try w.writeAll(" = ");
5520 try f.writeCValue(w, input_val, .Other);4721 try f.writeCValue(w, input_val, .other);
5521 try w.writeByte(';');4722 try w.writeByte(';');
5522 try f.object.newline();4723 try f.newline();
5523 }4724 }
5524 }4725 }
55254726
5526 {4727 {
5527 const asm_source = unwrapped_asm.source;4728 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);
5530 const allocator = stack.get();4731 const allocator = stack.get();
5531 const fixed_asm_source = try allocator.alloc(u8, asm_source.len);4732 const fixed_asm_source = try allocator.alloc(u8, asm_source.len);
5532 defer allocator.free(fixed_asm_source);4733 defer allocator.free(fixed_asm_source);
...@@ -5592,10 +4793,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5592,10 +4793,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5592 const is_reg = constraint[1] == '{';4793 const is_reg = constraint[1] == '{';
5593 try w.print("{f}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});4794 try w.print("{f}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});
5594 if (is_reg) {4795 if (is_reg) {
5595 try f.writeCValue(w, .{ .local = locals_index }, .Other);4796 try f.writeCValue(w, .{ .local = locals_index }, .other);
5596 locals_index += 1;4797 locals_index += 1;
5597 } else if (output.operand == .none) {4798 } else if (output.operand == .none) {
5598 try f.writeCValue(w, inst_local, .FunctionArgument);4799 try f.writeCValue(w, inst_local, .other);
5599 } else {4800 } else {
5600 try f.writeCValueDeref(w, try f.resolveInst(output.operand));4801 try f.writeCValueDeref(w, try f.resolveInst(output.operand));
5601 }4802 }
...@@ -5619,57 +4820,54 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5619,57 +4820,54 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5619 const input_local_idx = locals_index;4820 const input_local_idx = locals_index;
5620 locals_index += 1;4821 locals_index += 1;
5621 break :local .{ .local = input_local_idx };4822 break :local .{ .local = input_local_idx };
5622 } else input_val, .Other);4823 } else input_val, .other);
5623 try w.writeByte(')');4824 try w.writeByte(')');
5624 }4825 }
5625 try w.writeByte(':');4826 try w.writeByte(':');
5626 const ip = &zcu.intern_pool;4827 const ip = &zcu.intern_pool;
5627 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;4828 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
5628 const struct_type: Type = .fromInterned(aggregate.ty);4829 const clobbers_ty = clobbers_val.typeOf(zcu);
5629 switch (aggregate.storage) {4830 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
5630 .elems => |elems| for (elems, 0..) |elem, i| switch (elem) {4831 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
5631 .bool_true => {4832 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
5632 const field_name = struct_type.structFieldName(i, zcu).toSlice(ip).?;4833 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
5633 assert(field_name.len != 0);4834 const limb_bits = @bitSizeOf(std.math.big.Limb);
56344835 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
5635 const target = &f.object.dg.mod.resolved_target.result;4836 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
5636 var c_name_buf: [16]u8 = undefined;4837 0 => continue, // field is false
5637 const name =4838 1 => {}, // field is true
5638 if ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'r') name: {4839 }
5639 // Convert "rN" to "$N"4840 const field_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
5640 const c_name = (&c_name_buf)[0..field_name.len];4841 assert(field_name.len != 0);
5641 @memcpy(c_name, field_name);4842
5642 c_name_buf[0] = '$';4843 const target = &f.dg.mod.resolved_target.result;
5643 break :name c_name;4844 var c_name_buf: [16]u8 = undefined;
5644 } else if ((target.cpu.arch.isMIPS() and (mem.startsWith(u8, field_name, "fcc") or field_name[0] == 'w')) or4845 const name =
5645 ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'f') or4846 if ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'r') name: {
5646 (target.cpu.arch == .kvx and !mem.eql(u8, field_name, "memory"))) name: {4847 // Convert "rN" to "$N"
5647 // "$" prefix for these registers4848 const c_name = (&c_name_buf)[0..field_name.len];
5648 c_name_buf[0] = '$';4849 @memcpy(c_name, field_name);
5649 @memcpy((&c_name_buf)[1..][0..field_name.len], field_name);4850 c_name_buf[0] = '$';
5650 break :name (&c_name_buf)[0 .. 1 + field_name.len];4851 break :name c_name;
5651 } else if (target.cpu.arch.isSPARC() and4852 } else if ((target.cpu.arch.isMIPS() and (mem.startsWith(u8, field_name, "fcc") or field_name[0] == 'w')) or
5652 (mem.eql(u8, field_name, "ccr") or mem.eql(u8, field_name, "icc") or mem.eql(u8, field_name, "xcc"))) name: {4853 ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'f') or
5653 // C compilers just use `icc` to encompass all of these.4854 (target.cpu.arch == .kvx and !mem.eql(u8, field_name, "memory"))) name: {
5654 break :name "icc";4855 // "$" prefix for these registers
5655 } else field_name;4856 c_name_buf[0] = '$';
56564857 @memcpy((&c_name_buf)[1..][0..field_name.len], field_name);
5657 try w.print(" {f}", .{fmtStringLiteral(name, null)});4858 break :name (&c_name_buf)[0 .. 1 + field_name.len];
5658 (try w.writableArray(1))[0] = ',';4859 } else if (target.cpu.arch.isSPARC() and
5659 },4860 (mem.eql(u8, field_name, "ccr") or mem.eql(u8, field_name, "icc") or mem.eql(u8, field_name, "xcc"))) name: {
5660 .bool_false => continue,4861 // C compilers just use `icc` to encompass all of these.
5661 else => unreachable,4862 break :name "icc";
5662 },4863 } else field_name;
5663 .repeated_elem => |elem| switch (elem) {4864
5664 .bool_true => @panic("TODO"),4865 try w.print(" {f}", .{fmtStringLiteral(name, null)});
5665 .bool_false => {},4866 (try w.writableArray(1))[0] = ',';
5666 else => unreachable,
5667 },
5668 .bytes => @panic("TODO"),
5669 }4867 }
5670 w.undo(1); // erase the last comma4868 w.undo(1); // erase the last comma
5671 try w.writeAll(");");4869 try w.writeAll(");");
5672 try f.object.newline();4870 try f.newline();
56734871
5674 locals_index = locals_begin;4872 locals_index = locals_begin;
5675 it = unwrapped_asm.iterateOutputs();4873 it = unwrapped_asm.iterateOutputs();
...@@ -5683,10 +4881,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5683,10 +4881,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5683 else4881 else
5684 try f.resolveInst(output.operand));4882 try f.resolveInst(output.operand));
5685 try w.writeAll(" = ");4883 try w.writeAll(" = ");
5686 try f.writeCValue(w, .{ .local = locals_index }, .Other);4884 try f.writeCValue(w, .{ .local = locals_index }, .other);
5687 locals_index += 1;4885 locals_index += 1;
5688 try w.writeByte(';');4886 try w.writeByte(';');
5689 try f.object.newline();4887 try f.newline();
5690 }4888 }
5691 }4889 }
56924890
...@@ -5708,147 +4906,145 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5708,147 +4906,145 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5708fn airIsNull(4906fn airIsNull(
5709 f: *Function,4907 f: *Function,
5710 inst: Air.Inst.Index,4908 inst: Air.Inst.Index,
5711 operator: std.math.CompareOperator,4909 operator: enum { eq, neq },
5712 is_ptr: bool,4910 is_ptr: bool,
5713) !CValue {4911) !CValue {
5714 const pt = f.object.dg.pt;4912 const pt = f.dg.pt;
5715 const zcu = pt.zcu;4913 const zcu = pt.zcu;
5716 const ctype_pool = &f.object.dg.ctype_pool;
5717 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4914 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;
5720 const operand = try f.resolveInst(un_op);4917 const operand = try f.resolveInst(un_op);
5721 try reap(f, inst, &.{un_op});4918 try reap(f, inst, &.{un_op});
57224919
5723 const local = try f.allocLocal(inst, .bool);4920 const local = try f.allocLocal(inst, .bool);
5724 const a = try Assignment.start(f, w, .bool);4921 try f.writeCValue(w, local, .other);
5725 try f.writeCValue(w, local, .Other);4922 try w.writeAll(" = ");
5726 try a.assign(f, w);
57274923
5728 const operand_ty = f.typeOf(un_op);4924 const operand_ty = f.typeOf(un_op);
5729 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;4925 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
5730 const opt_ctype = try f.ctypeFromType(optional_ty, .complete);4926
5731 const rhs = switch (opt_ctype.info(ctype_pool)) {4927 const pre: []const u8, const maybe_field: ?[]const u8, const post: []const u8 = switch (operator) {
5732 .basic, .pointer => rhs: {4928 // zig fmt: off
5733 if (is_ptr)4929 .eq => switch (CType.classifyOptional(optional_ty, zcu)) {
5734 try f.writeCValueDeref(w, operand)4930 .npv_payload => unreachable, // opv optional
5735 else4931 .error_set => .{ "", null, " == 0" },
5736 try f.writeCValue(w, operand, .Other);4932 .ptr_like => .{ "", null, " == NULL" },
5737 break :rhs if (opt_ctype.isBool())4933 .slice_like => .{ "", "ptr", " == NULL" },
5738 "true"4934 .opv_payload => .{ "", "is_null", "" },
5739 else if (opt_ctype.isInteger())4935 .@"struct" => .{ "", "is_null", "" },
5740 "0"
5741 else
5742 "NULL";
5743 },4936 },
5744 .aligned, .array, .vector, .fwd_decl, .function => unreachable,4937 .neq => switch (CType.classifyOptional(optional_ty, zcu)) {
5745 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {4938 .npv_payload => unreachable, // opv optional
5746 .is_null, .payload => rhs: {4939 .error_set => .{ "", null, " != 0" },
5747 if (is_ptr)4940 .ptr_like => .{ "", null, " != NULL" },
5748 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" })4941 .slice_like => .{ "", "ptr", " != NULL" },
5749 else4942 .opv_payload => .{ "!", "is_null", "" },
5750 try f.writeCValueMember(w, operand, .{ .identifier = "is_null" });4943 .@"struct" => .{ "!", "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,
5761 },4944 },
4945 // zig fmt: on
5762 };4946 };
5763 try w.writeAll(compareOperatorC(operator));4947
5764 try w.writeAll(rhs);4948 try w.writeAll(pre);
5765 try a.end(f, w);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();
5766 return local;4966 return local;
5767}4967}
57684968
5769fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {4969fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
5770 const pt = f.object.dg.pt;4970 const pt = f.dg.pt;
5771 const zcu = pt.zcu;4971 const zcu = pt.zcu;
5772 const ctype_pool = &f.object.dg.ctype_pool;
5773 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4972 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57744973
5775 const inst_ty = f.typeOfIndex(inst);4974 const inst_ty = f.typeOfIndex(inst);
5776 const operand_ty = f.typeOf(ty_op.operand);4975 const operand_ty = f.typeOf(ty_op.operand);
5777 const opt_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;4976 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
5781 const operand = try f.resolveInst(ty_op.operand);4978 const operand = try f.resolveInst(ty_op.operand);
5782 switch (opt_ctype.info(ctype_pool)) {4979
5783 .basic, .pointer => return f.moveCValue(inst, inst_ty, operand),4980 switch (CType.classifyOptional(opt_ty, zcu)) {
5784 .aligned, .array, .vector, .fwd_decl, .function => unreachable,4981 .npv_payload => unreachable, // opv optional
5785 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {4982
5786 .is_null, .payload => {4983 .opv_payload => return if (is_ptr) .{ .undef = inst_ty } else .none,
5787 const w = &f.object.code.writer;4984
5788 const local = try f.allocLocal(inst, inst_ty);4985 .error_set,
5789 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));4986 .ptr_like,
5790 try f.writeCValue(w, local, .Other);4987 .slice_like,
5791 try a.assign(f, w);4988 => return f.moveCValue(inst, inst_ty, operand),
5792 if (is_ptr) {4989
5793 try w.writeByte('&');4990 .@"struct" => {
5794 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });4991 const w = &f.code.writer;
5795 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });4992 const local = try f.allocLocal(inst, inst_ty);
5796 try a.end(f, w);4993 try f.writeCValue(w, local, .other);
5797 return local;4994 try w.writeAll(" = ");
5798 },4995 if (is_ptr) {
5799 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),4996 try w.writeByte('&');
5800 else => unreachable,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;
5801 },5002 },
5802 }5003 }
5803}5004}
58045005
5805fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {5006fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5806 const pt = f.object.dg.pt;5007 const pt = f.dg.pt;
5807 const zcu = pt.zcu;5008 const zcu = pt.zcu;
5808 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5009 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;
5810 const operand = try f.resolveInst(ty_op.operand);5011 const operand = try f.resolveInst(ty_op.operand);
5811 try reap(f, inst, &.{ty_op.operand});5012 try reap(f, inst, &.{ty_op.operand});
5812 const operand_ty = f.typeOf(ty_op.operand);5013 const operand_ty = f.typeOf(ty_op.operand);
5014 const opt_ty = operand_ty.childType(zcu);
58135015
5814 const inst_ty = f.typeOfIndex(inst);5016 const inst_ty = f.typeOfIndex(inst);
5815 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);5017
5816 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {5018 switch (CType.classifyOptional(opt_ty, zcu)) {
5817 .basic => {5019 .npv_payload => unreachable, // opv optional
5818 const a = try Assignment.start(f, w, opt_ctype);5020
5819 try f.writeCValueDeref(w, operand);5021 .opv_payload => {
5820 try a.assign(f, w);5022 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });
5821 try f.object.dg.renderValue(w, Value.false, .Other);5023 try w.writeAll(" = ");
5822 try a.end(f, w);5024 try f.dg.renderValue(w, .false, .other);
5823 return .none;5025 try w.writeByte(';');
5824 },5026 try f.newline();
5825 .pointer => {5027 return .{ .undef = inst_ty };
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;
5834 },5028 },
5835 .aligned, .array, .vector, .fwd_decl, .function => unreachable,5029
5836 .aggregate => {5030 .error_set,
5837 {5031 .ptr_like,
5838 const a = try Assignment.start(f, w, opt_ctype);5032 .slice_like,
5839 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });5033 => return f.moveCValue(inst, inst_ty, operand),
5840 try a.assign(f, w);5034
5841 try f.object.dg.renderValue(w, Value.false, .Other);5035 .@"struct" => {
5842 try a.end(f, w);5036 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });
5843 }5037 try w.writeAll(" = ");
5038 try f.dg.renderValue(w, .false, .other);
5039 try w.writeByte(';');
5040 try f.newline();
5844 if (f.liveness.isUnused(inst)) return .none;5041 if (f.liveness.isUnused(inst)) return .none;
5845 const local = try f.allocLocal(inst, inst_ty);5042 const local = try f.allocLocal(inst, inst_ty);
5846 const a = try Assignment.start(f, w, opt_ctype);5043 try f.writeCValue(w, local, .other);
5847 try f.writeCValue(w, local, .Other);5044 try w.writeAll(" = &");
5848 try a.assign(f, w);
5849 try w.writeByte('&');
5850 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });5045 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
5851 try a.end(f, w);5046 try w.writeByte(';');
5047 try f.newline();
5852 return local;5048 return local;
5853 },5049 },
5854 }5050 }
...@@ -5870,12 +5066,12 @@ fn fieldLocation(...@@ -5870,12 +5066,12 @@ fn fieldLocation(
5870 .struct_type => {5066 .struct_type => {
5871 const loaded_struct = ip.loadStructType(container_ty.toIntern());5067 const loaded_struct = ip.loadStructType(container_ty.toIntern());
5872 return switch (loaded_struct.layout) {5068 return switch (loaded_struct.layout) {
5873 .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))5069 .auto, .@"extern" => if (!container_ty.hasRuntimeBits(zcu))
5874 .begin5070 .begin
5875 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))5071 else if (!field_ptr_ty.childType(zcu).hasRuntimeBits(zcu))
5876 .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] }5072 .{ .byte_offset = loaded_struct.field_offsets.get(ip)[field_index] }
5877 else5073 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) } },
5879 .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)5075 .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)
5880 .{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(loaded_struct, field_index) +5076 .{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(loaded_struct, field_index) +
5881 container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }5077 container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }
...@@ -5883,27 +5079,29 @@ fn fieldLocation(...@@ -5883,27 +5079,29 @@ fn fieldLocation(
5883 .begin,5079 .begin,
5884 };5080 };
5885 },5081 },
5886 .tuple_type => return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))5082 .tuple_type => return if (!container_ty.hasRuntimeBits(zcu))
5887 .begin5083 .begin
5888 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))5084 else if (!field_ptr_ty.childType(zcu).hasRuntimeBits(zcu))
5889 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }5085 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }
5890 else5086 else
5891 .{ .field = .{ .field = field_index } },5087 .{ .field = .{ .field = field_index } },
5892 .union_type => {5088 .union_type => {
5893 const loaded_union = ip.loadUnionType(container_ty.toIntern());5089 const loaded_union = ip.loadUnionType(container_ty.toIntern());
5894 switch (loaded_union.flagsUnordered(ip).layout) {5090 switch (loaded_union.layout) {
5895 .auto, .@"extern" => {5091 .auto => {
5896 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);5092 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
5897 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu))5093 if (!field_ty.hasRuntimeBits(zcu)) {
5898 return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(zcu))5094 if (container_ty.unionHasAllZeroBitFieldTypes(zcu)) return .begin;
5899 .{ .field = .{ .identifier = "payload" } }5095 return .{ .field = .{ .identifier = "payload" } };
5900 else5096 }
5901 .begin;5097 const field_name = ip.loadEnumType(loaded_union.enum_tag_type).field_names.get(ip)[field_index];
5902 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];5098 return .{ .field = .{ .payload_identifier = field_name.toSlice(ip) } };
5903 return .{ .field = if (loaded_union.hasTag(ip))5099 },
5904 .{ .payload_identifier = field_name.toSlice(ip) }5100 .@"extern" => {
5905 else5101 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
5906 .{ .identifier = field_name.toSlice(ip) } };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) } };
5907 },5105 },
5908 .@"packed" => return .begin,5106 .@"packed" => return .begin,
5909 }5107 }
...@@ -5940,7 +5138,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue...@@ -5940,7 +5138,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
5940}5138}
59415139
5942fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {5140fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5943 const pt = f.object.dg.pt;5141 const pt = f.dg.pt;
5944 const zcu = pt.zcu;5142 const zcu = pt.zcu;
5945 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5143 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5946 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5144 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
...@@ -5952,26 +5150,26 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5952,26 +5150,26 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5952 const field_ptr_val = try f.resolveInst(extra.field_ptr);5150 const field_ptr_val = try f.resolveInst(extra.field_ptr);
5953 try reap(f, inst, &.{extra.field_ptr});5151 try reap(f, inst, &.{extra.field_ptr});
59545152
5955 const w = &f.object.code.writer;5153 const w = &f.code.writer;
5956 const local = try f.allocLocal(inst, container_ptr_ty);5154 const local = try f.allocLocal(inst, container_ptr_ty);
5957 try f.writeCValue(w, local, .Other);5155 try f.writeCValue(w, local, .other);
5958 try w.writeAll(" = (");5156 try w.writeAll(" = (");
5959 try f.renderType(w, container_ptr_ty);5157 try f.renderType(w, container_ptr_ty);
5960 try w.writeByte(')');5158 try w.writeByte(')');
59615159
5962 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, zcu)) {5160 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),
5964 .field => |field| {5162 .field => |field| {
5965 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);5163 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
59665164
5967 try w.writeAll("((");5165 try w.writeAll("((");
5968 try f.renderType(w, u8_ptr_ty);5166 try f.renderType(w, u8_ptr_ty);
5969 try w.writeByte(')');5167 try w.writeByte(')');
5970 try f.writeCValue(w, field_ptr_val, .Other);5168 try f.writeCValue(w, field_ptr_val, .other);
5971 try w.writeAll(" - offsetof(");5169 try w.writeAll(" - offsetof(");
5972 try f.renderType(w, container_ty);5170 try f.renderType(w, container_ty);
5973 try w.writeAll(", ");5171 try w.writeAll(", ");
5974 try f.writeCValue(w, field, .Other);5172 try f.writeCValue(w, field, .other);
5975 try w.writeAll("))");5173 try w.writeAll("))");
5976 },5174 },
5977 .byte_offset => |byte_offset| {5175 .byte_offset => |byte_offset| {
...@@ -5980,7 +5178,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5980,7 +5178,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5980 try w.writeAll("((");5178 try w.writeAll("((");
5981 try f.renderType(w, u8_ptr_ty);5179 try f.renderType(w, u8_ptr_ty);
5982 try w.writeByte(')');5180 try w.writeByte(')');
5983 try f.writeCValue(w, field_ptr_val, .Other);5181 try f.writeCValue(w, field_ptr_val, .other);
5984 try w.print(" - {f})", .{5182 try w.print(" - {f})", .{
5985 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),5183 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),
5986 });5184 });
...@@ -5988,7 +5186,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5988,7 +5186,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5988 }5186 }
59895187
5990 try w.writeByte(';');5188 try w.writeByte(';');
5991 try f.object.newline();5189 try f.newline();
5992 return local;5190 return local;
5993}5191}
59945192
...@@ -5999,23 +5197,19 @@ fn fieldPtr(...@@ -5999,23 +5197,19 @@ fn fieldPtr(
5999 container_ptr_val: CValue,5197 container_ptr_val: CValue,
6000 field_index: u32,5198 field_index: u32,
6001) !CValue {5199) !CValue {
6002 const pt = f.object.dg.pt;5200 const pt = f.dg.pt;
6003 const zcu = pt.zcu;5201 const zcu = pt.zcu;
6004 const container_ty = container_ptr_ty.childType(zcu);
6005 const field_ptr_ty = f.typeOfIndex(inst);5202 const field_ptr_ty = f.typeOfIndex(inst);
60065203
6007 // Ensure complete type definition is visible before accessing fields.5204 const w = &f.code.writer;
6008 _ = try f.ctypeFromType(container_ty, .complete);
6009
6010 const w = &f.object.code.writer;
6011 const local = try f.allocLocal(inst, field_ptr_ty);5205 const local = try f.allocLocal(inst, field_ptr_ty);
6012 try f.writeCValue(w, local, .Other);5206 try f.writeCValue(w, local, .other);
6013 try w.writeAll(" = (");5207 try w.writeAll(" = (");
6014 try f.renderType(w, field_ptr_ty);5208 try f.renderType(w, field_ptr_ty);
6015 try w.writeByte(')');5209 try w.writeByte(')');
60165210
6017 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, zcu)) {5211 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),
6019 .field => |field| {5213 .field => |field| {
6020 try w.writeByte('&');5214 try w.writeByte('&');
6021 try f.writeCValueDerefMember(w, container_ptr_val, field);5215 try f.writeCValueDerefMember(w, container_ptr_val, field);
...@@ -6026,7 +5220,7 @@ fn fieldPtr(...@@ -6026,7 +5220,7 @@ fn fieldPtr(
6026 try w.writeAll("((");5220 try w.writeAll("((");
6027 try f.renderType(w, u8_ptr_ty);5221 try f.renderType(w, u8_ptr_ty);
6028 try w.writeByte(')');5222 try w.writeByte(')');
6029 try f.writeCValue(w, container_ptr_val, .Other);5223 try f.writeCValue(w, container_ptr_val, .other);
6030 try w.print(" + {f})", .{5224 try w.print(" + {f})", .{
6031 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),5225 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),
6032 });5226 });
...@@ -6034,61 +5228,51 @@ fn fieldPtr(...@@ -6034,61 +5228,51 @@ fn fieldPtr(
6034 }5228 }
60355229
6036 try w.writeByte(';');5230 try w.writeByte(';');
6037 try f.object.newline();5231 try f.newline();
6038 return local;5232 return local;
6039}5233}
60405234
6041fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {5235fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6042 const pt = f.object.dg.pt;5236 const pt = f.dg.pt;
6043 const zcu = pt.zcu;5237 const zcu = pt.zcu;
6044 const ip = &zcu.intern_pool;5238 const ip = &zcu.intern_pool;
6045 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5239 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6046 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;5240 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
60475241
6048 const inst_ty = f.typeOfIndex(inst);5242 const inst_ty = f.typeOfIndex(inst);
6049 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5243 assert(inst_ty.hasRuntimeBits(zcu));
6050 try reap(f, inst, &.{extra.struct_operand});
6051 return .none;
6052 }
60535244
6054 const struct_byval = try f.resolveInst(extra.struct_operand);5245 const struct_byval = try f.resolveInst(extra.struct_operand);
6055 try reap(f, inst, &.{extra.struct_operand});5246 try reap(f, inst, &.{extra.struct_operand});
6056 const struct_ty = f.typeOf(extra.struct_operand);5247 const struct_ty = f.typeOf(extra.struct_operand);
6057 const w = &f.object.code.writer;5248 const w = &f.code.writer;
6058
6059 // Ensure complete type definition is visible before accessing fields.
6060 _ = try f.ctypeFromType(struct_ty, .complete);
60615249
6062 assert(struct_ty.containerLayout(zcu) != .@"packed"); // `Air.Legalize.Feature.expand_packed_struct_field_val` handles this case5250 assert(struct_ty.containerLayout(zcu) != .@"packed"); // `Air.Legalize.Feature.expand_packed_struct_field_val` handles this case
6063 const field_name: CValue = switch (ip.indexToKey(struct_ty.toIntern())) {5251 const field_name: CValue = switch (ip.indexToKey(struct_ty.toIntern())) {
6064 .struct_type => .{ .identifier = struct_ty.structFieldName(extra.field_index, zcu).unwrap().?.toSlice(ip) },5252 .struct_type => .{ .identifier = struct_ty.structFieldName(extra.field_index, zcu).unwrap().?.toSlice(ip) },
6065 .union_type => name: {5253 .union_type => name: {
6066 const union_type = ip.loadUnionType(struct_ty.toIntern());5254 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);
6068 const field_name_str = enum_tag_ty.enumFieldName(extra.field_index, zcu).toSlice(ip);5256 const field_name_str = enum_tag_ty.enumFieldName(extra.field_index, zcu).toSlice(ip);
6069 if (union_type.hasTag(ip)) {5257 break :name .{ .payload_identifier = field_name_str };
6070 break :name .{ .payload_identifier = field_name_str };
6071 } else {
6072 break :name .{ .identifier = field_name_str };
6073 }
6074 },5258 },
6075 .tuple_type => .{ .field = extra.field_index },5259 .tuple_type => .{ .field = extra.field_index },
6076 else => unreachable,5260 else => unreachable,
6077 };5261 };
60785262
6079 const local = try f.allocLocal(inst, inst_ty);5263 const local = try f.allocLocal(inst, inst_ty);
6080 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));5264 try f.writeCValue(w, local, .other);
6081 try f.writeCValue(w, local, .Other);5265 try w.writeAll(" = ");
6082 try a.assign(f, w);
6083 try f.writeCValueMember(w, struct_byval, field_name);5266 try f.writeCValueMember(w, struct_byval, field_name);
6084 try a.end(f, w);5267 try w.writeByte(';');
5268 try f.newline();
6085 return local;5269 return local;
6086}5270}
60875271
6088/// *(E!T) -> E5272/// *(E!T) -> E
6089/// Note that the result is never a pointer.5273/// Note that the result is never a pointer.
6090fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5274fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6091 const pt = f.object.dg.pt;5275 const pt = f.dg.pt;
6092 const zcu = pt.zcu;5276 const zcu = pt.zcu;
6093 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5277 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 {...@@ -6098,37 +5282,23 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6098 try reap(f, inst, &.{ty_op.operand});5282 try reap(f, inst, &.{ty_op.operand});
60995283
6100 const operand_is_ptr = operand_ty.zigTypeTag(zcu) == .pointer;5284 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);
6104 const local = try f.allocLocal(inst, inst_ty);5285 const local = try f.allocLocal(inst, inst_ty);
61055286
6106 if (!payload_ty.hasRuntimeBits(zcu) and operand == .local and operand.local == local.new_local) {5287 const w = &f.code.writer;
6107 // The store will be 'x = x'; elide it.5288 try f.writeCValue(w, local, .other);
6108 return local;
6109 }
6110
6111 const w = &f.object.code.writer;
6112 try f.writeCValue(w, local, .Other);
6113 try w.writeAll(" = ");5289 try w.writeAll(" = ");
61145290
6115 if (!payload_ty.hasRuntimeBits(zcu))5291 if (operand_is_ptr)
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)
6122 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })5292 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
6123 else5293 else
6124 try f.writeCValueMember(w, operand, .{ .identifier = "error" });5294 try f.writeCValueMember(w, operand, .{ .identifier = "error" });
6125 try w.writeByte(';');5295 try w.writeByte(';');
6126 try f.object.newline();5296 try f.newline();
6127 return local;5297 return local;
6128}5298}
61295299
6130fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {5300fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
6131 const pt = f.object.dg.pt;5301 const pt = f.dg.pt;
6132 const zcu = pt.zcu;5302 const zcu = pt.zcu;
6133 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5303 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...@@ -6138,154 +5308,124 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
6138 const operand_ty = f.typeOf(ty_op.operand);5308 const operand_ty = f.typeOf(ty_op.operand);
6139 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;5309 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;
6142 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {5312 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
6143 if (!is_ptr) return .none;5313 assert(is_ptr); // opv bug in sema
6144
6145 const local = try f.allocLocal(inst, inst_ty);5314 const local = try f.allocLocal(inst, inst_ty);
6146 try f.writeCValue(w, local, .Other);5315 try f.writeCValue(w, local, .other);
6147 try w.writeAll(" = (");5316 try w.writeAll(" = (");
6148 try f.renderType(w, inst_ty);5317 try f.renderType(w, inst_ty);
6149 try w.writeByte(')');5318 try w.writeByte(')');
6150 try f.writeCValue(w, operand, .Other);5319 try f.writeCValue(w, operand, .other);
6151 try w.writeByte(';');5320 try w.writeByte(';');
6152 try f.object.newline();5321 try f.newline();
6153 return local;5322 return local;
6154 }5323 }
61555324
6156 const local = try f.allocLocal(inst, inst_ty);5325 const local = try f.allocLocal(inst, inst_ty);
6157 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));5326 try f.writeCValue(w, local, .other);
6158 try f.writeCValue(w, local, .Other);5327 try w.writeAll(" = ");
6159 try a.assign(f, w);
6160 if (is_ptr) {5328 if (is_ptr) {
6161 try w.writeByte('&');5329 try w.writeByte('&');
6162 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });5330 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
6163 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });5331 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });
6164 try a.end(f, w);5332 try w.writeByte(';');
5333 try f.newline();
6165 return local;5334 return local;
6166}5335}
61675336
6168fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {5337fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
6169 const ctype_pool = &f.object.dg.ctype_pool;5338 const zcu = f.dg.pt.zcu;
6170 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5339 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
61715340
6172 const inst_ty = f.typeOfIndex(inst);5341 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
6176 const operand = try f.resolveInst(ty_op.operand);5343 const operand = try f.resolveInst(ty_op.operand);
6177 switch (inst_ctype.info(ctype_pool)) {5344
6178 .basic, .pointer => return f.moveCValue(inst, inst_ty, operand),5345 switch (CType.classifyOptional(inst_ty, zcu)) {
6179 .aligned, .array, .vector, .fwd_decl, .function => unreachable,5346 .npv_payload => unreachable, // opv optional
6180 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {5347
6181 .is_null, .payload => {5348 .opv_payload => unreachable, // opv bug in Sema
6182 const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);5349
6183 const w = &f.object.code.writer;5350 .error_set,
6184 const local = try f.allocLocal(inst, inst_ty);5351 .ptr_like,
6185 {5352 .slice_like,
6186 const a = try Assignment.start(f, w, .bool);5353 => return f.moveCValue(inst, inst_ty, operand),
6187 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });5354
6188 try a.assign(f, w);5355 .@"struct" => {
6189 try w.writeAll("false");5356 const w = &f.code.writer;
6190 try a.end(f, w);5357 const local = try f.allocLocal(inst, inst_ty);
6191 }5358
6192 {5359 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
6193 const a = try Assignment.start(f, w, operand_ctype);5360 try w.writeAll(" = false;");
6194 try f.writeCValueMember(w, local, .{ .identifier = "payload" });5361 try f.newline();
6195 try a.assign(f, w);5362
6196 try f.writeCValue(w, operand, .Other);5363 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6197 try a.end(f, w);5364 try w.writeAll(" = ");
6198 }5365 try f.writeCValue(w, operand, .other);
6199 return local;5366 try w.writeByte(';');
6200 },5367 try f.newline();
6201 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),5368
6202 else => unreachable,5369 return local;
6203 },5370 },
6204 }5371 }
6205}5372}
62065373
6207fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5374fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6208 const pt = f.object.dg.pt;5375 const pt = f.dg.pt;
6209 const zcu = pt.zcu;5376 const zcu = pt.zcu;
6210 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5377 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62115378
6212 const inst_ty = f.typeOfIndex(inst);5379 const inst_ty = f.typeOfIndex(inst);
6213 const payload_ty = inst_ty.errorUnionPayload(zcu);5380 const payload_ty = inst_ty.errorUnionPayload(zcu);
6214 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
6215 const err_ty = inst_ty.errorUnionSet(zcu);
6216 const err = try f.resolveInst(ty_op.operand);5381 const err = try f.resolveInst(ty_op.operand);
6217 try reap(f, inst, &.{ty_op.operand});5382 try reap(f, inst, &.{ty_op.operand});
62185383
6219 const w = &f.object.code.writer;5384 const w = &f.code.writer;
6220 const local = try f.allocLocal(inst, inst_ty);5385 const local = try f.allocLocal(inst, inst_ty);
62215386
6222 if (repr_is_err and err == .local and err.local == local.new_local) {5387 if (payload_ty.hasRuntimeBits(zcu)) {
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));
6229 try f.writeCValueMember(w, local, .{ .identifier = "payload" });5388 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6230 try a.assign(f, w);5389 try w.writeAll(" = ");
6231 try f.object.dg.renderUndefValue(w, payload_ty, .Other);5390 try f.dg.renderUndefValue(w, payload_ty, .other);
6232 try a.end(f, w);5391 try w.writeByte(';');
6233 }5392 try f.newline();
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);
6243 }5393 }
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
6244 return local;5401 return local;
6245}5402}
62465403
6247fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {5404fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
6248 const pt = f.object.dg.pt;5405 const pt = f.dg.pt;
6249 const zcu = pt.zcu;5406 const w = &f.code.writer;
6250 const w = &f.object.code.writer;
6251 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5407 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6252 const inst_ty = f.typeOfIndex(inst);5408 const inst_ty = f.typeOfIndex(inst);
6253 const operand = try f.resolveInst(ty_op.operand);5409 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);
6258 const err_int_ty = try pt.errorIntType();5411 const err_int_ty = try pt.errorIntType();
6259 const no_err = try pt.intValue(err_int_ty, 0);5412 const no_err = try pt.intValue(err_int_ty, 0);
6260 try reap(f, inst, &.{ty_op.operand});5413 try reap(f, inst, &.{ty_op.operand});
62615414
6262 // First, set the non-error value.5415 // First, set the non-error value.
6263 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5416 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" });
6264 const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));5417 try w.print(" = {f};", .{try f.fmtIntLiteralDec(no_err)});
6265 try f.writeCValueDeref(w, operand);5418 try f.newline();
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 }
62785419
6279 // Then return the payload pointer (only if it is used)5420 // Then return the payload pointer (only if it is used)
6280 if (f.liveness.isUnused(inst)) return .none;5421 if (f.liveness.isUnused(inst)) return .none;
62815422
6282 const local = try f.allocLocal(inst, inst_ty);5423 const local = try f.allocLocal(inst, inst_ty);
6283 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));5424 try f.writeCValue(w, local, .other);
6284 try f.writeCValue(w, local, .Other);5425 try w.writeAll(" = &");
6285 try a.assign(f, w);
6286 try w.writeByte('&');
6287 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });5426 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
6288 try a.end(f, w);5427 try w.writeByte(';');
5428 try f.newline();
6289 return local;5429 return local;
6290}5430}
62915431
...@@ -6305,131 +5445,96 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6305,131 +5445,96 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
6305}5445}
63065446
6307fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {5447fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
6308 const pt = f.object.dg.pt;5448 const pt = f.dg.pt;
6309 const zcu = pt.zcu;5449 const zcu = pt.zcu;
6310 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5450 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63115451
6312 const inst_ty = f.typeOfIndex(inst);5452 const inst_ty = f.typeOfIndex(inst);
6313 const payload_ty = inst_ty.errorUnionPayload(zcu);5453 const payload_ty = inst_ty.errorUnionPayload(zcu);
6314 const payload = try f.resolveInst(ty_op.operand);5454 const payload = try f.resolveInst(ty_op.operand);
6315 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);5455 assert(payload_ty.hasRuntimeBits(zcu));
6316 const err_ty = inst_ty.errorUnionSet(zcu);
6317 try reap(f, inst, &.{ty_op.operand});5456 try reap(f, inst, &.{ty_op.operand});
63185457
6319 const w = &f.object.code.writer;5458 const w = &f.code.writer;
6320 const local = try f.allocLocal(inst, inst_ty);5459 const local = try f.allocLocal(inst, inst_ty);
6321 if (!repr_is_err) {5460
6322 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));5461 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6323 try f.writeCValueMember(w, local, .{ .identifier = "payload" });5462 try w.writeAll(" = ");
6324 try a.assign(f, w);5463 try f.writeCValue(w, payload, .other);
6325 try f.writeCValue(w, payload, .Other);5464 try w.writeByte(';');
6326 try a.end(f, w);5465 try f.newline();
6327 }5466
6328 {5467 try f.writeCValueMember(w, local, .{ .identifier = "error" });
6329 const a = try Assignment.start(f, w, try f.ctypeFromType(err_ty, .complete));5468 try w.writeAll(" = ");
6330 if (repr_is_err)5469 try f.dg.renderValue(w, try pt.intValue(try pt.errorIntType(), 0), .other);
6331 try f.writeCValue(w, local, .Other)5470 try w.writeByte(';');
6332 else5471 try f.newline();
6333 try f.writeCValueMember(w, local, .{ .identifier = "error" });5472
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 }
6338 return local;5473 return local;
6339}5474}
63405475
6341fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {5476fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
6342 const pt = f.object.dg.pt;5477 const pt = f.dg.pt;
6343 const zcu = pt.zcu;
6344 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5478 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;
6347 const operand = try f.resolveInst(un_op);5481 const operand = try f.resolveInst(un_op);
6348 try reap(f, inst, &.{un_op});5482 try reap(f, inst, &.{un_op});
6349 const operand_ty = f.typeOf(un_op);
6350 const local = try f.allocLocal(inst, .bool);5483 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);5485 try f.writeCValue(w, local, .other);
6356 try f.writeCValue(w, local, .Other);5486 try w.writeAll(" = ");
6357 try a.assign(f, w);
6358 const err_int_ty = try pt.errorIntType();5487 const err_int_ty = try pt.errorIntType();
6359 if (!error_ty.errorSetIsEmpty(zcu))5488 if (is_ptr)
6360 if (payload_ty.hasRuntimeBits(zcu))5489 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
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)
6367 else5490 else
6368 try f.object.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .Other);5491 try f.writeCValueMember(w, operand, .{ .identifier = "error" });
6369 try w.writeByte(' ');5492 try w.print(" {s} ", .{operator});
6370 try w.writeAll(operator);5493 try f.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .other);
6371 try w.writeByte(' ');5494 try w.writeByte(';');
6372 try f.object.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .Other);5495 try f.newline();
6373 try a.end(f, w);
6374 return local;5496 return local;
6375}5497}
63765498
6377fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {5499fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6378 const pt = f.object.dg.pt;5500 const pt = f.dg.pt;
6379 const zcu = pt.zcu;5501 const zcu = pt.zcu;
6380 const ctype_pool = &f.object.dg.ctype_pool;
6381 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5502 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63825503
6383 const operand = try f.resolveInst(ty_op.operand);5504 const operand = try f.resolveInst(ty_op.operand);
6384 try reap(f, inst, &.{ty_op.operand});5505 try reap(f, inst, &.{ty_op.operand});
6385 const inst_ty = f.typeOfIndex(inst);5506 const inst_ty = f.typeOfIndex(inst);
6386 const ptr_ty = inst_ty.slicePtrFieldType(zcu);5507 const w = &f.code.writer;
6387 const w = &f.object.code.writer;
6388 const local = try f.allocLocal(inst, inst_ty);5508 const local = try f.allocLocal(inst, inst_ty);
6389 const operand_ty = f.typeOf(ty_op.operand);5509 const operand_ty = f.typeOf(ty_op.operand);
6390 const array_ty = operand_ty.childType(zcu);5510 const array_ty = operand_ty.childType(zcu);
63915511
6392 {5512 // We have a `*[n]T`, which was turned into to a pointer to `struct { T array[n]; }`.
6393 const a = try Assignment.start(f, w, try f.ctypeFromType(ptr_ty, .complete));5513 // Ideally we would want to use 'operand->array' to convert to a `T *` (we get a `T []`
6394 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });5514 // which decays to a pointer), but if the element type is zero-bit or the array length is
6395 try a.assign(f, w);5515 // zero, there will not be an `array` member (the array type lowers to `void`). We cannot
6396 if (operand == .undef) {5516 // check the type layout here because it may not be resolved, so in this instance, we must
6397 try f.writeCValue(w, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Other);5517 // use a pointer cast.
6398 } else {5518 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
6399 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);5519 try w.writeAll(" = (");
6400 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;5520 try f.dg.renderType(w, inst_ty.slicePtrFieldType(zcu));
6401 const elem_ty = array_ty.childType(zcu);5521 try w.writeByte(')');
6402 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);5522 try f.writeCValue(w, operand, .other);
6403 if (!ptr_child_ctype.eql(elem_ctype)) {5523 try w.writeByte(';');
6404 try w.writeByte('(');5524 try f.newline();
6405 try f.renderCType(w, ptr_ctype);5525
6406 try w.writeByte(')');5526 try f.writeCValueMember(w, local, .{ .identifier = "len" });
6407 }5527 try w.print(" = {f}", .{
6408 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);5528 try f.fmtIntLiteralDec(try pt.intValue(.usize, array_ty.arrayLen(zcu))),
6409 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;5529 });
6410 if (operand_child_ctype.info(ctype_pool) == .array) {5530 try w.writeByte(';');
6411 try w.writeByte('&');5531 try f.newline();
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 }
64275532
6428 return local;5533 return local;
6429}5534}
64305535
6431fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {5536fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6432 const pt = f.object.dg.pt;5537 const pt = f.dg.pt;
6433 const zcu = pt.zcu;5538 const zcu = pt.zcu;
6434 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5539 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 {...@@ -6439,7 +5544,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6439 try reap(f, inst, &.{ty_op.operand});5544 try reap(f, inst, &.{ty_op.operand});
6440 const operand_ty = f.typeOf(ty_op.operand);5545 const operand_ty = f.typeOf(ty_op.operand);
6441 const scalar_ty = operand_ty.scalarType(zcu);5546 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;
6443 const operation = if (inst_scalar_ty.isRuntimeFloat() and scalar_ty.isRuntimeFloat())5548 const operation = if (inst_scalar_ty.isRuntimeFloat() and scalar_ty.isRuntimeFloat())
6444 if (inst_scalar_ty.floatBits(target) < scalar_ty.floatBits(target)) "trunc" else "extend"5549 if (inst_scalar_ty.floatBits(target) < scalar_ty.floatBits(target)) "trunc" else "extend"
6445 else if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat())5550 else if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat())
...@@ -6449,16 +5554,15 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6449,16 +5554,15 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6449 else5554 else
6450 unreachable;5555 unreachable;
64515556
6452 const w = &f.object.code.writer;5557 const w = &f.code.writer;
6453 const local = try f.allocLocal(inst, inst_ty);5558 const local = try f.allocLocal(inst, inst_ty);
6454 const v = try Vectorize.start(f, inst, w, operand_ty);5559 const v = try Vectorize.start(f, inst, w, operand_ty);
6455 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));5560 try f.writeCValue(w, local, .other);
6456 try f.writeCValue(w, local, .Other);
6457 try v.elem(f, w);5561 try v.elem(f, w);
6458 try a.assign(f, w);5562 try w.writeAll(" = ");
6459 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {5563 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6460 try w.writeAll("zig_wrap_");5564 try w.writeAll("zig_wrap_");
6461 try f.object.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);5565 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
6462 try w.writeByte('(');5566 try w.writeByte('(');
6463 }5567 }
6464 try w.writeAll("zig_");5568 try w.writeAll("zig_");
...@@ -6466,14 +5570,15 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6466,14 +5570,15 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6466 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));5570 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
6467 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));5571 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
6468 try w.writeByte('(');5572 try w.writeByte('(');
6469 try f.writeCValue(w, operand, .FunctionArgument);5573 try f.writeCValue(w, operand, .other);
6470 try v.elem(f, w);5574 try v.elem(f, w);
6471 try w.writeByte(')');5575 try w.writeByte(')');
6472 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {5576 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);
6474 try w.writeByte(')');5578 try w.writeByte(')');
6475 }5579 }
6476 try a.end(f, w);5580 try w.writeByte(';');
5581 try f.newline();
6477 try v.end(f, inst, w);5582 try v.end(f, inst, w);
64785583
6479 return local;5584 return local;
...@@ -6486,7 +5591,7 @@ fn airUnBuiltinCall(...@@ -6486,7 +5591,7 @@ fn airUnBuiltinCall(
6486 operation: []const u8,5591 operation: []const u8,
6487 info: BuiltinInfo,5592 info: BuiltinInfo,
6488) !CValue {5593) !CValue {
6489 const pt = f.object.dg.pt;5594 const pt = f.dg.pt;
6490 const zcu = pt.zcu;5595 const zcu = pt.zcu;
64915596
6492 const operand = try f.resolveInst(operand_ref);5597 const operand = try f.resolveInst(operand_ref);
...@@ -6496,30 +5601,32 @@ fn airUnBuiltinCall(...@@ -6496,30 +5601,32 @@ fn airUnBuiltinCall(
6496 const operand_ty = f.typeOf(operand_ref);5601 const operand_ty = f.typeOf(operand_ref);
6497 const scalar_ty = operand_ty.scalarType(zcu);5602 const scalar_ty = operand_ty.scalarType(zcu);
64985603
6499 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);5604 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
6500 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;5605 const ref_arg = lowersToBigInt(scalar_ty, zcu);
65015606
6502 const w = &f.object.code.writer;5607 const w = &f.code.writer;
6503 const local = try f.allocLocal(inst, inst_ty);5608 const local = try f.allocLocal(inst, inst_ty);
6504 const v = try Vectorize.start(f, inst, w, operand_ty);5609 const v = try Vectorize.start(f, inst, w, operand_ty);
6505 if (!ref_ret) {5610 if (!ref_ret) {
6506 try f.writeCValue(w, local, .Other);5611 try f.writeCValue(w, local, .other);
6507 try v.elem(f, w);5612 try v.elem(f, w);
6508 try w.writeAll(" = ");5613 try w.writeAll(" = ");
6509 }5614 }
6510 try w.print("zig_{s}_", .{operation});5615 try w.print("zig_{s}_", .{operation});
6511 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);5616 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6512 try w.writeByte('(');5617 try w.writeByte('(');
6513 if (ref_ret) {5618 if (ref_ret) {
6514 try f.writeCValue(w, local, .FunctionArgument);5619 try w.writeByte('&');
5620 try f.writeCValue(w, local, .other);
6515 try v.elem(f, w);5621 try v.elem(f, w);
6516 try w.writeAll(", ");5622 try w.writeAll(", ");
6517 }5623 }
6518 try f.writeCValue(w, operand, .FunctionArgument);5624 if (ref_arg) try w.writeByte('&');
5625 try f.writeCValue(w, operand, .other);
6519 try v.elem(f, w);5626 try v.elem(f, w);
6520 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);5627 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
6521 try w.writeAll(");");5628 try w.writeAll(");");
6522 try f.object.newline();5629 try f.newline();
6523 try v.end(f, inst, w);5630 try v.end(f, inst, w);
65245631
6525 return local;5632 return local;
...@@ -6531,13 +5638,12 @@ fn airBinBuiltinCall(...@@ -6531,13 +5638,12 @@ fn airBinBuiltinCall(
6531 operation: []const u8,5638 operation: []const u8,
6532 info: BuiltinInfo,5639 info: BuiltinInfo,
6533) !CValue {5640) !CValue {
6534 const pt = f.object.dg.pt;5641 const pt = f.dg.pt;
6535 const zcu = pt.zcu;5642 const zcu = pt.zcu;
6536 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5643 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
65375644
6538 const operand_ty = f.typeOf(bin_op.lhs);5645 const operand_ty = f.typeOf(bin_op.lhs);
6539 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);5646 const is_big = lowersToBigInt(operand_ty, zcu);
6540 const is_big = operand_ctype.info(&f.object.dg.ctype_pool) == .array;
65415647
6542 const lhs = try f.resolveInst(bin_op.lhs);5648 const lhs = try f.resolveInst(bin_op.lhs);
6543 const rhs = try f.resolveInst(bin_op.rhs);5649 const rhs = try f.resolveInst(bin_op.rhs);
...@@ -6547,32 +5653,35 @@ fn airBinBuiltinCall(...@@ -6547,32 +5653,35 @@ fn airBinBuiltinCall(
6547 const inst_scalar_ty = inst_ty.scalarType(zcu);5653 const inst_scalar_ty = inst_ty.scalarType(zcu);
6548 const scalar_ty = operand_ty.scalarType(zcu);5654 const scalar_ty = operand_ty.scalarType(zcu);
65495655
6550 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);5656 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
6551 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;5657 const ref_arg = lowersToBigInt(scalar_ty, zcu);
65525658
6553 const w = &f.object.code.writer;5659 const w = &f.code.writer;
6554 const local = try f.allocLocal(inst, inst_ty);5660 const local = try f.allocLocal(inst, inst_ty);
6555 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });5661 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6556 const v = try Vectorize.start(f, inst, w, operand_ty);5662 const v = try Vectorize.start(f, inst, w, operand_ty);
6557 if (!ref_ret) {5663 if (!ref_ret) {
6558 try f.writeCValue(w, local, .Other);5664 try f.writeCValue(w, local, .other);
6559 try v.elem(f, w);5665 try v.elem(f, w);
6560 try w.writeAll(" = ");5666 try w.writeAll(" = ");
6561 }5667 }
6562 try w.print("zig_{s}_", .{operation});5668 try w.print("zig_{s}_", .{operation});
6563 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);5669 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6564 try w.writeByte('(');5670 try w.writeByte('(');
6565 if (ref_ret) {5671 if (ref_ret) {
6566 try f.writeCValue(w, local, .FunctionArgument);5672 try w.writeByte('&');
5673 try f.writeCValue(w, local, .other);
6567 try v.elem(f, w);5674 try v.elem(f, w);
6568 try w.writeAll(", ");5675 try w.writeAll(", ");
6569 }5676 }
6570 try f.writeCValue(w, lhs, .FunctionArgument);5677 if (ref_arg) try w.writeByte('&');
5678 try f.writeCValue(w, lhs, .other);
6571 try v.elem(f, w);5679 try v.elem(f, w);
6572 try w.writeAll(", ");5680 try w.writeAll(", ");
6573 try f.writeCValue(w, rhs, .FunctionArgument);5681 if (ref_arg) try w.writeByte('&');
5682 try f.writeCValue(w, rhs, .other);
6574 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);5683 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);
6576 try w.writeAll(");\n");5685 try w.writeAll(");\n");
6577 try v.end(f, inst, w);5686 try v.end(f, inst, w);
65785687
...@@ -6587,7 +5696,7 @@ fn airCmpBuiltinCall(...@@ -6587,7 +5696,7 @@ fn airCmpBuiltinCall(
6587 operation: enum { cmp, operator },5696 operation: enum { cmp, operator },
6588 info: BuiltinInfo,5697 info: BuiltinInfo,
6589) !CValue {5698) !CValue {
6590 const pt = f.object.dg.pt;5699 const pt = f.dg.pt;
6591 const zcu = pt.zcu;5700 const zcu = pt.zcu;
6592 const lhs = try f.resolveInst(data.lhs);5701 const lhs = try f.resolveInst(data.lhs);
6593 const rhs = try f.resolveInst(data.rhs);5702 const rhs = try f.resolveInst(data.rhs);
...@@ -6598,14 +5707,14 @@ fn airCmpBuiltinCall(...@@ -6598,14 +5707,14 @@ fn airCmpBuiltinCall(
6598 const operand_ty = f.typeOf(data.lhs);5707 const operand_ty = f.typeOf(data.lhs);
6599 const scalar_ty = operand_ty.scalarType(zcu);5708 const scalar_ty = operand_ty.scalarType(zcu);
66005709
6601 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);5710 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
6602 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;5711 const ref_arg = lowersToBigInt(scalar_ty, zcu);
66035712
6604 const w = &f.object.code.writer;5713 const w = &f.code.writer;
6605 const local = try f.allocLocal(inst, inst_ty);5714 const local = try f.allocLocal(inst, inst_ty);
6606 const v = try Vectorize.start(f, inst, w, operand_ty);5715 const v = try Vectorize.start(f, inst, w, operand_ty);
6607 if (!ref_ret) {5716 if (!ref_ret) {
6608 try f.writeCValue(w, local, .Other);5717 try f.writeCValue(w, local, .other);
6609 try v.elem(f, w);5718 try v.elem(f, w);
6610 try w.writeAll(" = ");5719 try w.writeAll(" = ");
6611 }5720 }
...@@ -6613,33 +5722,36 @@ fn airCmpBuiltinCall(...@@ -6613,33 +5722,36 @@ fn airCmpBuiltinCall(
6613 else => @tagName(operation),5722 else => @tagName(operation),
6614 .operator => compareOperatorAbbrev(operator),5723 .operator => compareOperatorAbbrev(operator),
6615 }});5724 }});
6616 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);5725 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6617 try w.writeByte('(');5726 try w.writeByte('(');
6618 if (ref_ret) {5727 if (ref_ret) {
6619 try f.writeCValue(w, local, .FunctionArgument);5728 try w.writeByte('&');
5729 try f.writeCValue(w, local, .other);
6620 try v.elem(f, w);5730 try v.elem(f, w);
6621 try w.writeAll(", ");5731 try w.writeAll(", ");
6622 }5732 }
6623 try f.writeCValue(w, lhs, .FunctionArgument);5733 if (ref_arg) try w.writeByte('&');
5734 try f.writeCValue(w, lhs, .other);
6624 try v.elem(f, w);5735 try v.elem(f, w);
6625 try w.writeAll(", ");5736 try w.writeAll(", ");
6626 try f.writeCValue(w, rhs, .FunctionArgument);5737 if (ref_arg) try w.writeByte('&');
5738 try f.writeCValue(w, rhs, .other);
6627 try v.elem(f, w);5739 try v.elem(f, w);
6628 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);5740 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
6629 try w.writeByte(')');5741 try w.writeByte(')');
6630 if (!ref_ret) try w.print("{s}{f}", .{5742 if (!ref_ret) try w.print("{s}{f}", .{
6631 compareOperatorC(operator),5743 compareOperatorC(operator),
6632 try f.fmtIntLiteralDec(try pt.intValue(.i32, 0)),5744 try f.fmtIntLiteralDec(try pt.intValue(.i32, 0)),
6633 });5745 });
6634 try w.writeByte(';');5746 try w.writeByte(';');
6635 try f.object.newline();5747 try f.newline();
6636 try v.end(f, inst, w);5748 try v.end(f, inst, w);
66375749
6638 return local;5750 return local;
6639}5751}
66405752
6641fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {5753fn 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;
6643 const zcu = pt.zcu;5755 const zcu = pt.zcu;
6644 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5756 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6645 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;5757 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...@@ -6649,9 +5761,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6649 const new_value = try f.resolveInst(extra.new_value);5761 const new_value = try f.resolveInst(extra.new_value);
6650 const ptr_ty = f.typeOf(extra.ptr);5762 const ptr_ty = f.typeOf(extra.ptr);
6651 const ty = ptr_ty.childType(zcu);5763 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;
6655 const new_value_mat = try Materialize.start(f, inst, ty, new_value);5766 const new_value_mat = try Materialize.start(f, inst, ty, new_value);
6656 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });5767 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...@@ -6662,13 +5773,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
66625773
6663 const local = try f.allocLocal(inst, inst_ty);5774 const local = try f.allocLocal(inst, inst_ty);
6664 if (inst_ty.isPtrLikeOptional(zcu)) {5775 if (inst_ty.isPtrLikeOptional(zcu)) {
6665 {5776 try f.writeCValue(w, local, .other);
6666 const a = try Assignment.start(f, w, ctype);5777 try w.writeAll(" = ");
6667 try f.writeCValue(w, local, .Other);5778 try f.writeCValue(w, expected_value, .other);
6668 try a.assign(f, w);5779 try w.writeByte(';');
6669 try f.writeCValue(w, expected_value, .Other);5780 try f.newline();
6670 try a.end(f, w);
6671 }
66725781
6673 try w.writeAll("if (");5782 try w.writeAll("if (");
6674 try w.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});5783 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...@@ -6676,9 +5785,9 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6676 try w.writeByte(')');5785 try w.writeByte(')');
6677 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");5786 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6678 try w.writeAll(" *)");5787 try w.writeAll(" *)");
6679 try f.writeCValue(w, ptr, .Other);5788 try f.writeCValue(w, ptr, .other);
6680 try w.writeAll(", ");5789 try w.writeAll(", ");
6681 try f.writeCValue(w, local, .FunctionArgument);5790 try f.writeCValue(w, local, .other);
6682 try w.writeAll(", ");5791 try w.writeAll(", ");
6683 try new_value_mat.mat(f, w);5792 try new_value_mat.mat(f, w);
6684 try w.writeAll(", ");5793 try w.writeAll(", ");
...@@ -6686,56 +5795,49 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6686,56 +5795,49 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6686 try w.writeAll(", ");5795 try w.writeAll(", ");
6687 try writeMemoryOrder(w, extra.failureOrder());5796 try writeMemoryOrder(w, extra.failureOrder());
6688 try w.writeAll(", ");5797 try w.writeAll(", ");
6689 try f.object.dg.renderTypeForBuiltinFnName(w, ty);5798 try f.dg.renderTypeForBuiltinFnName(w, ty);
6690 try w.writeAll(", ");5799 try w.writeAll(", ");
6691 try f.renderType(w, repr_ty);5800 try f.renderType(w, repr_ty);
6692 try w.writeByte(')');5801 try w.writeByte(')');
6693 try w.writeAll(") {");5802 try w.writeAll(") {");
6694 f.object.indent();5803 f.indent();
6695 try f.object.newline();5804 try f.newline();
6696 {5805
6697 const a = try Assignment.start(f, w, ctype);5806 try f.writeCValue(w, local, .other);
6698 try f.writeCValue(w, local, .Other);5807 try w.writeAll(" = NULL;");
6699 try a.assign(f, w);5808 try f.newline();
6700 try w.writeAll("NULL");5809
6701 try a.end(f, w);5810 try f.outdent();
6702 }
6703 try f.object.outdent();
6704 try w.writeByte('}');5811 try w.writeByte('}');
6705 try f.object.newline();5812 try f.newline();
6706 } else {5813 } else {
6707 {5814 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6708 const a = try Assignment.start(f, w, ctype);5815 try w.writeAll(" = ");
6709 try f.writeCValueMember(w, local, .{ .identifier = "payload" });5816 try f.writeCValue(w, expected_value, .other);
6710 try a.assign(f, w);5817 try w.writeByte(';');
6711 try f.writeCValue(w, expected_value, .Other);5818 try f.newline();
6712 try a.end(f, w);5819
6713 }5820 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
6714 {5821 try w.print(" = zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6715 const a = try Assignment.start(f, w, .bool);5822 try f.renderType(w, ty);
6716 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });5823 try w.writeByte(')');
6717 try a.assign(f, w);5824 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6718 try w.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});5825 try w.writeAll(" *)");
6719 try f.renderType(w, ty);5826 try f.writeCValue(w, ptr, .other);
6720 try w.writeByte(')');5827 try w.writeAll(", ");
6721 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");5828 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6722 try w.writeAll(" *)");5829 try w.writeAll(", ");
6723 try f.writeCValue(w, ptr, .Other);5830 try new_value_mat.mat(f, w);
6724 try w.writeAll(", ");5831 try w.writeAll(", ");
6725 try f.writeCValueMember(w, local, .{ .identifier = "payload" });5832 try writeMemoryOrder(w, extra.successOrder());
6726 try w.writeAll(", ");5833 try w.writeAll(", ");
6727 try new_value_mat.mat(f, w);5834 try writeMemoryOrder(w, extra.failureOrder());
6728 try w.writeAll(", ");5835 try w.writeAll(", ");
6729 try writeMemoryOrder(w, extra.successOrder());5836 try f.dg.renderTypeForBuiltinFnName(w, ty);
6730 try w.writeAll(", ");5837 try w.writeAll(", ");
6731 try writeMemoryOrder(w, extra.failureOrder());5838 try f.renderType(w, repr_ty);
6732 try w.writeAll(", ");5839 try w.writeAll(");");
6733 try f.object.dg.renderTypeForBuiltinFnName(w, ty);5840 try f.newline();
6734 try w.writeAll(", ");
6735 try f.renderType(w, repr_ty);
6736 try w.writeByte(')');
6737 try a.end(f, w);
6738 }
6739 }5841 }
6740 try new_value_mat.end(f, inst);5842 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...@@ -6748,7 +5850,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6748}5850}
67495851
6750fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {5852fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6751 const pt = f.object.dg.pt;5853 const pt = f.dg.pt;
6752 const zcu = pt.zcu;5854 const zcu = pt.zcu;
6753 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5855 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6754 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;5856 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
...@@ -6758,7 +5860,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6758,7 +5860,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6758 const ptr = try f.resolveInst(pl_op.operand);5860 const ptr = try f.resolveInst(pl_op.operand);
6759 const operand = try f.resolveInst(extra.operand);5861 const operand = try f.resolveInst(extra.operand);
67605862
6761 const w = &f.object.code.writer;5863 const w = &f.code.writer;
6762 const operand_mat = try Materialize.start(f, inst, ty, operand);5864 const operand_mat = try Materialize.start(f, inst, ty, operand);
6763 try reap(f, inst, &.{ pl_op.operand, extra.operand });5865 try reap(f, inst, &.{ pl_op.operand, extra.operand });
67645866
...@@ -6771,7 +5873,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6771,7 +5873,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6771 try w.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});5873 try w.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
6772 if (is_float) try w.writeAll("_float") else if (is_128) try w.writeAll("_int128");5874 if (is_float) try w.writeAll("_float") else if (is_128) try w.writeAll("_int128");
6773 try w.writeByte('(');5875 try w.writeByte('(');
6774 try f.writeCValue(w, local, .Other);5876 try f.writeCValue(w, local, .other);
6775 try w.writeAll(", (");5877 try w.writeAll(", (");
6776 const use_atomic = switch (extra.op()) {5878 const use_atomic = switch (extra.op()) {
6777 else => true,5879 else => true,
...@@ -6783,17 +5885,17 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6783,17 +5885,17 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6783 if (use_atomic) try w.writeByte(')');5885 if (use_atomic) try w.writeByte(')');
6784 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");5886 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6785 try w.writeAll(" *)");5887 try w.writeAll(" *)");
6786 try f.writeCValue(w, ptr, .Other);5888 try f.writeCValue(w, ptr, .other);
6787 try w.writeAll(", ");5889 try w.writeAll(", ");
6788 try operand_mat.mat(f, w);5890 try operand_mat.mat(f, w);
6789 try w.writeAll(", ");5891 try w.writeAll(", ");
6790 try writeMemoryOrder(w, extra.ordering());5892 try writeMemoryOrder(w, extra.ordering());
6791 try w.writeAll(", ");5893 try w.writeAll(", ");
6792 try f.object.dg.renderTypeForBuiltinFnName(w, ty);5894 try f.dg.renderTypeForBuiltinFnName(w, ty);
6793 try w.writeAll(", ");5895 try w.writeAll(", ");
6794 try f.renderType(w, repr_ty);5896 try f.renderType(w, repr_ty);
6795 try w.writeAll(");");5897 try w.writeAll(");");
6796 try f.object.newline();5898 try f.newline();
6797 try operand_mat.end(f, inst);5899 try operand_mat.end(f, inst);
67985900
6799 if (f.liveness.isUnused(inst)) {5901 if (f.liveness.isUnused(inst)) {
...@@ -6805,7 +5907,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6805,7 +5907,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6805}5907}
68065908
6807fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {5909fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6808 const pt = f.object.dg.pt;5910 const pt = f.dg.pt;
6809 const zcu = pt.zcu;5911 const zcu = pt.zcu;
6810 const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;5912 const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
6811 const ptr = try f.resolveInst(atomic_load.ptr);5913 const ptr = try f.resolveInst(atomic_load.ptr);
...@@ -6819,31 +5921,31 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6819,31 +5921,31 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6819 ty;5921 ty;
68205922
6821 const inst_ty = f.typeOfIndex(inst);5923 const inst_ty = f.typeOfIndex(inst);
6822 const w = &f.object.code.writer;5924 const w = &f.code.writer;
6823 const local = try f.allocLocal(inst, inst_ty);5925 const local = try f.allocLocal(inst, inst_ty);
68245926
6825 try w.writeAll("zig_atomic_load(");5927 try w.writeAll("zig_atomic_load(");
6826 try f.writeCValue(w, local, .Other);5928 try f.writeCValue(w, local, .other);
6827 try w.writeAll(", (zig_atomic(");5929 try w.writeAll(", (zig_atomic(");
6828 try f.renderType(w, ty);5930 try f.renderType(w, ty);
6829 try w.writeByte(')');5931 try w.writeByte(')');
6830 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");5932 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6831 try w.writeAll(" *)");5933 try w.writeAll(" *)");
6832 try f.writeCValue(w, ptr, .Other);5934 try f.writeCValue(w, ptr, .other);
6833 try w.writeAll(", ");5935 try w.writeAll(", ");
6834 try writeMemoryOrder(w, atomic_load.order);5936 try writeMemoryOrder(w, atomic_load.order);
6835 try w.writeAll(", ");5937 try w.writeAll(", ");
6836 try f.object.dg.renderTypeForBuiltinFnName(w, ty);5938 try f.dg.renderTypeForBuiltinFnName(w, ty);
6837 try w.writeAll(", ");5939 try w.writeAll(", ");
6838 try f.renderType(w, repr_ty);5940 try f.renderType(w, repr_ty);
6839 try w.writeAll(");");5941 try w.writeAll(");");
6840 try f.object.newline();5942 try f.newline();
68415943
6842 return local;5944 return local;
6843}5945}
68445946
6845fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {5947fn 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;
6847 const zcu = pt.zcu;5949 const zcu = pt.zcu;
6848 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5950 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6849 const ptr_ty = f.typeOf(bin_op.lhs);5951 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...@@ -6851,7 +5953,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6851 const ptr = try f.resolveInst(bin_op.lhs);5953 const ptr = try f.resolveInst(bin_op.lhs);
6852 const element = try f.resolveInst(bin_op.rhs);5954 const element = try f.resolveInst(bin_op.rhs);
68535955
6854 const w = &f.object.code.writer;5956 const w = &f.code.writer;
6855 const element_mat = try Materialize.start(f, inst, ty, element);5957 const element_mat = try Materialize.start(f, inst, ty, element);
6856 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });5958 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...@@ -6865,32 +5967,22 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6865 try w.writeByte(')');5967 try w.writeByte(')');
6866 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");5968 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6867 try w.writeAll(" *)");5969 try w.writeAll(" *)");
6868 try f.writeCValue(w, ptr, .Other);5970 try f.writeCValue(w, ptr, .other);
6869 try w.writeAll(", ");5971 try w.writeAll(", ");
6870 try element_mat.mat(f, w);5972 try element_mat.mat(f, w);
6871 try w.print(", {s}, ", .{order});5973 try w.print(", {s}, ", .{order});
6872 try f.object.dg.renderTypeForBuiltinFnName(w, ty);5974 try f.dg.renderTypeForBuiltinFnName(w, ty);
6873 try w.writeAll(", ");5975 try w.writeAll(", ");
6874 try f.renderType(w, repr_ty);5976 try f.renderType(w, repr_ty);
6875 try w.writeAll(");");5977 try w.writeAll(");");
6876 try f.object.newline();5978 try f.newline();
6877 try element_mat.end(f, inst);5979 try element_mat.end(f, inst);
68785980
6879 return .none;5981 return .none;
6880}5982}
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
6892fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {5984fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6893 const pt = f.object.dg.pt;5985 const pt = f.dg.pt;
6894 const zcu = pt.zcu;5986 const zcu = pt.zcu;
6895 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5987 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6896 const dest_ty = f.typeOf(bin_op.lhs);5988 const dest_ty = f.typeOf(bin_op.lhs);
...@@ -6899,7 +5991,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6899,7 +5991,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6899 const elem_ty = f.typeOf(bin_op.rhs);5991 const elem_ty = f.typeOf(bin_op.rhs);
6900 const elem_abi_size = elem_ty.abiSize(zcu);5992 const elem_abi_size = elem_ty.abiSize(zcu);
6901 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndef(zcu) else false;5993 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
6904 if (val_is_undef) {5996 if (val_is_undef) {
6905 if (!safety) {5997 if (!safety) {
...@@ -6913,153 +6005,128 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6913,153 +6005,128 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6913 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });6005 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });
6914 try w.writeAll(", 0xaa, ");6006 try w.writeAll(", 0xaa, ");
6915 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });6007 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();
6921 },6008 },
6922 .one => {6009 .one => {
6923 const array_ty = dest_ty.childType(zcu);6010 try f.writeCValue(w, dest_slice, .other);
6924 const len = array_ty.arrayLen(zcu) * elem_abi_size;6011 try w.print(", 0xaa, {d}", .{dest_ty.childType(zcu).arrayLen(zcu)});
6925
6926 try f.writeCValue(w, dest_slice, .FunctionArgument);
6927 try w.print(", 0xaa, {d});", .{len});
6928 try f.object.newline();
6929 },6012 },
6930 .many, .c => unreachable,6013 .many, .c => unreachable,
6931 }6014 }
6015 if (elem_abi_size > 0) try w.print(" * {d}", .{elem_abi_size});
6016 try w.writeAll(");");
6017 try f.newline();
6932 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6018 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6933 return .none;6019 return .none;
6934 }6020 }
69356021
6936 if (elem_abi_size > 1 or dest_ty.isVolatilePtr(zcu)) {6022 if (elem_abi_size == 1 and !dest_ty.isVolatilePtr(zcu)) {
6937 // For the assignment in this loop, the array pointer needs to get6023 const bitcasted = try bitcast(f, .u8, value, elem_ty);
6938 // casted to a regular pointer, otherwise an error like this occurs:6024 try w.writeAll("memset(");
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(" != ");
6956 switch (dest_ty.ptrSize(zcu)) {6025 switch (dest_ty.ptrSize(zcu)) {
6957 .slice => {6026 .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(", ");
6958 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });6031 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
6959 },6032 },
6960 .one => {6033 .one => {
6961 const array_ty = dest_ty.childType(zcu);6034 try f.writeCValue(w, dest_slice, .other);
6962 try w.print("{d}", .{array_ty.arrayLen(zcu)});6035 try w.writeAll(", ");
6036 try f.writeCValue(w, bitcasted, .other);
6037 try w.print(", {d}", .{dest_ty.childType(zcu).arrayLen(zcu)});
6963 },6038 },
6964 .many, .c => unreachable,6039 .many, .c => unreachable,
6965 }6040 }
6966 try w.writeAll("; ++");6041 try w.writeAll(");");
6967 try f.writeCValue(w, index, .Other);6042 try f.newline();
6968 try w.writeAll(") ");6043 try f.freeCValue(inst, bitcasted);
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
6982 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6044 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6983 try freeLocal(f, inst, index.new_local, null);
6984
6985 return .none;6045 return .none;
6986 }6046 }
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(" != ");
6991 switch (dest_ty.ptrSize(zcu)) {6059 switch (dest_ty.ptrSize(zcu)) {
6992 .slice => {6060 .slice => try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" }),
6993 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });6061 .one => try w.print("{d}", .{dest_ty.childType(zcu).arrayLen(zcu)}),
6994 try w.writeAll(", ");6062 .many, .c => unreachable,
6995 try f.writeCValue(w, bitcasted, .FunctionArgument);6063 }
6996 try w.writeAll(", ");6064 try w.writeAll("; ++");
6997 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });6065 try f.writeCValue(w, index, .other);
6998 try w.writeAll(");");6066 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;
70046067
7005 try f.writeCValue(w, dest_slice, .FunctionArgument);6068 switch (dest_ty.ptrSize(zcu)) {
7006 try w.writeAll(", ");6069 .slice => try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" }),
7007 try f.writeCValue(w, bitcasted, .FunctionArgument);6070 .one => try f.writeCValueDerefMember(w, dest_slice, .{ .identifier = "array" }),
7008 try w.print(", {d});", .{len});
7009 try f.object.newline();
7010 },
7011 .many, .c => unreachable,6071 .many, .c => unreachable,
7012 }6072 }
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
7014 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6080 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6081 try freeLocal(f, inst, index.new_local, null);
6082
7015 return .none;6083 return .none;
7016}6084}
70176085
7018fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CValue {6086fn 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;
7020 const zcu = pt.zcu;6088 const zcu = pt.zcu;
7021 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6089 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7022 const dest_ptr = try f.resolveInst(bin_op.lhs);6090 const dest_ptr = try f.resolveInst(bin_op.lhs);
7023 const src_ptr = try f.resolveInst(bin_op.rhs);6091 const src_ptr = try f.resolveInst(bin_op.rhs);
7024 const dest_ty = f.typeOf(bin_op.lhs);6092 const dest_ty = f.typeOf(bin_op.lhs);
7025 const src_ty = f.typeOf(bin_op.rhs);6093 const src_ty = f.typeOf(bin_op.rhs);
7026 const w = &f.object.code.writer;6094 const w = &f.code.writer;
70276095
7028 if (dest_ty.ptrSize(zcu) != .one) {6096 if (dest_ty.ptrSize(zcu) != .one) {
7029 try w.writeAll("if (");6097 try w.writeAll("if (");
7030 try writeArrayLen(f, dest_ptr, dest_ty);6098 try f.writeCValueMember(w, dest_ptr, .{ .identifier = "len" });
7031 try w.writeAll(" != 0) ");6099 try w.writeAll(" != 0) ");
7032 }6100 }
7033 try w.writeAll(function_paren);6101 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 }
7035 try w.writeAll(", ");6107 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 }
7037 try w.writeAll(", ");6113 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 }
7039 try w.writeAll(" * sizeof(");6119 try w.writeAll(" * sizeof(");
7040 try f.renderType(w, dest_ty.elemType2(zcu));6120 try f.renderType(w, dest_ty.indexableElem(zcu));
7041 try w.writeAll("));");6121 try w.writeAll("));");
7042 try f.object.newline();6122 try f.newline();
70436123
7044 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6124 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
7045 return .none;6125 return .none;
7046}6126}
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
7061fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {6128fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7062 const pt = f.object.dg.pt;6129 const pt = f.dg.pt;
7063 const zcu = pt.zcu;6130 const zcu = pt.zcu;
7064 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6131 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7065 const union_ptr = try f.resolveInst(bin_op.lhs);6132 const union_ptr = try f.resolveInst(bin_op.lhs);
...@@ -7069,19 +6136,18 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7069,19 +6136,18 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7069 const union_ty = f.typeOf(bin_op.lhs).childType(zcu);6136 const union_ty = f.typeOf(bin_op.lhs).childType(zcu);
7070 const layout = union_ty.unionGetLayout(zcu);6137 const layout = union_ty.unionGetLayout(zcu);
7071 if (layout.tag_size == 0) return .none;6138 if (layout.tag_size == 0) return .none;
7072 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
70736139
7074 const w = &f.object.code.writer;6140 const w = &f.code.writer;
7075 const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));
7076 try f.writeCValueDerefMember(w, union_ptr, .{ .identifier = "tag" });6141 try f.writeCValueDerefMember(w, union_ptr, .{ .identifier = "tag" });
7077 try a.assign(f, w);6142 try w.writeAll(" = ");
7078 try f.writeCValue(w, new_tag, .Other);6143 try f.writeCValue(w, new_tag, .other);
7079 try a.end(f, w);6144 try w.writeByte(';');
6145 try f.newline();
7080 return .none;6146 return .none;
7081}6147}
70826148
7083fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {6149fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7084 const pt = f.object.dg.pt;6150 const pt = f.dg.pt;
7085 const zcu = pt.zcu;6151 const zcu = pt.zcu;
7086 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6152 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 {...@@ -7093,17 +6159,20 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7093 if (layout.tag_size == 0) return .none;6159 if (layout.tag_size == 0) return .none;
70946160
7095 const inst_ty = f.typeOfIndex(inst);6161 const inst_ty = f.typeOfIndex(inst);
7096 const w = &f.object.code.writer;6162 const w = &f.code.writer;
7097 const local = try f.allocLocal(inst, inst_ty);6163 const local = try f.allocLocal(inst, inst_ty);
7098 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));6164 try f.writeCValue(w, local, .other);
7099 try f.writeCValue(w, local, .Other);6165 try w.writeAll(" = ");
7100 try a.assign(f, w);
7101 try f.writeCValueMember(w, operand, .{ .identifier = "tag" });6166 try f.writeCValueMember(w, operand, .{ .identifier = "tag" });
7102 try a.end(f, w);6167 try w.writeByte(';');
6168 try f.newline();
7103 return local;6169 return local;
7104}6170}
71056171
7106fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {6172fn 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;
7107 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6176 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
71086177
7109 const inst_ty = f.typeOfIndex(inst);6178 const inst_ty = f.typeOfIndex(inst);
...@@ -7111,15 +6180,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7111,15 +6180,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
7111 const operand = try f.resolveInst(un_op);6180 const operand = try f.resolveInst(un_op);
7112 try reap(f, inst, &.{un_op});6181 try reap(f, inst, &.{un_op});
71136182
7114 const w = &f.object.code.writer;6183 const w = &f.code.writer;
7115 const local = try f.allocLocal(inst, inst_ty);6184 const local = try f.allocLocal(inst, inst_ty);
7116 try f.writeCValue(w, local, .Other);6185 try f.writeCValue(w, local, .other);
7117 try w.print(" = {s}(", .{6186 try f.need_tag_name_funcs.put(gpa, enum_ty.toIntern(), {});
7118 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),6187 try w.print(" = zig_tagName_{f}__{d}(", .{
6188 fmtIdentUnsolo(enum_ty.containerTypeName(ip).toSlice(ip)),
6189 @intFromEnum(enum_ty.toIntern()),
7119 });6190 });
7120 try f.writeCValue(w, operand, .Other);6191 try f.writeCValue(w, operand, .other);
7121 try w.writeAll(");");6192 try w.writeAll(");");
7122 try f.object.newline();6193 try f.newline();
71236194
7124 return local;6195 return local;
7125}6196}
...@@ -7127,40 +6198,37 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7127,40 +6198,37 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
7127fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {6198fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
7128 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6199 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;
7131 const inst_ty = f.typeOfIndex(inst);6202 const inst_ty = f.typeOfIndex(inst);
7132 const operand = try f.resolveInst(un_op);6203 const operand = try f.resolveInst(un_op);
7133 try reap(f, inst, &.{un_op});6204 try reap(f, inst, &.{un_op});
7134 const local = try f.allocLocal(inst, inst_ty);6205 const local = try f.allocLocal(inst, inst_ty);
7135 try f.writeCValue(w, local, .Other);6206 try f.writeCValue(w, local, .other);
71366207
7137 try w.writeAll(" = zig_errorName[");6208 try w.writeAll(" = zig_errorName[");
7138 try f.writeCValue(w, operand, .Other);6209 try f.writeCValue(w, operand, .other);
7139 try w.writeAll(" - 1];");6210 try w.writeAll(" - 1];");
7140 try f.object.newline();6211 try f.newline();
7141 return local;6212 return local;
7142}6213}
71436214
7144fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {6215fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
7145 const pt = f.object.dg.pt;
7146 const zcu = pt.zcu;
7147 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6216 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
71486217
7149 const operand = try f.resolveInst(ty_op.operand);6218 const operand = try f.resolveInst(ty_op.operand);
7150 try reap(f, inst, &.{ty_op.operand});6219 try reap(f, inst, &.{ty_op.operand});
71516220
7152 const inst_ty = f.typeOfIndex(inst);6221 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;
7156 const local = try f.allocLocal(inst, inst_ty);6224 const local = try f.allocLocal(inst, inst_ty);
7157 const v = try Vectorize.start(f, inst, w, inst_ty);6225 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));6226 try f.writeCValue(w, local, .other);
7159 try f.writeCValue(w, local, .Other);
7160 try v.elem(f, w);6227 try v.elem(f, w);
7161 try a.assign(f, w);6228 try w.writeAll(" = ");
7162 try f.writeCValue(w, operand, .Other);6229 try f.writeCValue(w, operand, .other);
7163 try a.end(f, w);6230 try w.writeByte(';');
6231 try f.newline();
7164 try v.end(f, inst, w);6232 try v.end(f, inst, w);
71656233
7166 return local;6234 return local;
...@@ -7177,29 +6245,29 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7177,29 +6245,29 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
71776245
7178 const inst_ty = f.typeOfIndex(inst);6246 const inst_ty = f.typeOfIndex(inst);
71796247
7180 const w = &f.object.code.writer;6248 const w = &f.code.writer;
7181 const local = try f.allocLocal(inst, inst_ty);6249 const local = try f.allocLocal(inst, inst_ty);
7182 const v = try Vectorize.start(f, inst, w, inst_ty);6250 const v = try Vectorize.start(f, inst, w, inst_ty);
7183 try f.writeCValue(w, local, .Other);6251 try f.writeCValue(w, local, .other);
7184 try v.elem(f, w);6252 try v.elem(f, w);
7185 try w.writeAll(" = ");6253 try w.writeAll(" = ");
7186 try f.writeCValue(w, pred, .Other);6254 try f.writeCValue(w, pred, .other);
7187 try v.elem(f, w);6255 try v.elem(f, w);
7188 try w.writeAll(" ? ");6256 try w.writeAll(" ? ");
7189 try f.writeCValue(w, lhs, .Other);6257 try f.writeCValue(w, lhs, .other);
7190 try v.elem(f, w);6258 try v.elem(f, w);
7191 try w.writeAll(" : ");6259 try w.writeAll(" : ");
7192 try f.writeCValue(w, rhs, .Other);6260 try f.writeCValue(w, rhs, .other);
7193 try v.elem(f, w);6261 try v.elem(f, w);
7194 try w.writeByte(';');6262 try w.writeByte(';');
7195 try f.object.newline();6263 try f.newline();
7196 try v.end(f, inst, w);6264 try v.end(f, inst, w);
71976265
7198 return local;6266 return local;
7199}6267}
72006268
7201fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {6269fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
7202 const pt = f.object.dg.pt;6270 const pt = f.dg.pt;
7203 const zcu = pt.zcu;6271 const zcu = pt.zcu;
72046272
7205 const unwrapped = f.air.unwrapShuffleOne(zcu, inst);6273 const unwrapped = f.air.unwrapShuffleOne(zcu, inst);
...@@ -7207,22 +6275,22 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7207,22 +6275,22 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
7207 const operand = try f.resolveInst(unwrapped.operand);6275 const operand = try f.resolveInst(unwrapped.operand);
7208 const inst_ty = unwrapped.result_ty;6276 const inst_ty = unwrapped.result_ty;
72096277
7210 const w = &f.object.code.writer;6278 const w = &f.code.writer;
7211 const local = try f.allocLocal(inst, inst_ty);6279 const local = try f.allocLocal(inst, inst_ty);
7212 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand6280 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand
7213 for (mask, 0..) |mask_elem, out_idx| {6281 for (mask, 0..) |mask_elem, out_idx| {
7214 try f.writeCValue(w, local, .Other);6282 try f.writeCValueMember(w, local, .{ .identifier = "array" });
7215 try w.writeByte('[');6283 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);
7217 try w.writeAll("] = ");6285 try w.writeAll("] = ");
7218 switch (mask_elem.unwrap()) {6286 switch (mask_elem.unwrap()) {
7219 .elem => |src_idx| {6287 .elem => |src_idx| {
7220 try f.writeCValue(w, operand, .Other);6288 try f.writeCValueMember(w, operand, .{ .identifier = "array" });
7221 try w.writeByte('[');6289 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);
7223 try w.writeByte(']');6291 try w.writeByte(']');
7224 },6292 },
7225 .value => |val| try f.object.dg.renderValue(w, .fromInterned(val), .Other),6293 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),
7226 }6294 }
7227 try w.writeAll(";\n");6295 try w.writeAll(";\n");
7228 }6296 }
...@@ -7231,7 +6299,7 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7231,7 +6299,7 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
7231}6299}
72326300
7233fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {6301fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
7234 const pt = f.object.dg.pt;6302 const pt = f.dg.pt;
7235 const zcu = pt.zcu;6303 const zcu = pt.zcu;
72366304
7237 const unwrapped = f.air.unwrapShuffleTwo(zcu, inst);6305 const unwrapped = f.air.unwrapShuffleTwo(zcu, inst);
...@@ -7241,38 +6309,38 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7241,38 +6309,38 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
7241 const inst_ty = unwrapped.result_ty;6309 const inst_ty = unwrapped.result_ty;
7242 const elem_ty = inst_ty.childType(zcu);6310 const elem_ty = inst_ty.childType(zcu);
72436311
7244 const w = &f.object.code.writer;6312 const w = &f.code.writer;
7245 const local = try f.allocLocal(inst, inst_ty);6313 const local = try f.allocLocal(inst, inst_ty);
7246 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands6314 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands
7247 for (mask, 0..) |mask_elem, out_idx| {6315 for (mask, 0..) |mask_elem, out_idx| {
7248 try f.writeCValue(w, local, .Other);6316 try f.writeCValueMember(w, local, .{ .identifier = "array" });
7249 try w.writeByte('[');6317 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);
7251 try w.writeAll("] = ");6319 try w.writeAll("] = ");
7252 switch (mask_elem.unwrap()) {6320 switch (mask_elem.unwrap()) {
7253 .a_elem => |src_idx| {6321 .a_elem => |src_idx| {
7254 try f.writeCValue(w, operand_a, .Other);6322 try f.writeCValueMember(w, operand_a, .{ .identifier = "array" });
7255 try w.writeByte('[');6323 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);
7257 try w.writeByte(']');6325 try w.writeByte(']');
7258 },6326 },
7259 .b_elem => |src_idx| {6327 .b_elem => |src_idx| {
7260 try f.writeCValue(w, operand_b, .Other);6328 try f.writeCValueMember(w, operand_b, .{ .identifier = "array" });
7261 try w.writeByte('[');6329 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);
7263 try w.writeByte(']');6331 try w.writeByte(']');
7264 },6332 },
7265 .undef => try f.object.dg.renderUndefValue(w, elem_ty, .Other),6333 .undef => try f.dg.renderUndefValue(w, elem_ty, .other),
7266 }6334 }
7267 try w.writeByte(';');6335 try w.writeByte(';');
7268 try f.object.newline();6336 try f.newline();
7269 }6337 }
72706338
7271 return local;6339 return local;
7272}6340}
72736341
7274fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {6342fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7275 const pt = f.object.dg.pt;6343 const pt = f.dg.pt;
7276 const zcu = pt.zcu;6344 const zcu = pt.zcu;
7277 const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;6345 const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
72786346
...@@ -7280,7 +6348,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7280,7 +6348,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7280 const operand = try f.resolveInst(reduce.operand);6348 const operand = try f.resolveInst(reduce.operand);
7281 try reap(f, inst, &.{reduce.operand});6349 try reap(f, inst, &.{reduce.operand});
7282 const operand_ty = f.typeOf(reduce.operand);6350 const operand_ty = f.typeOf(reduce.operand);
7283 const w = &f.object.code.writer;6351 const w = &f.code.writer;
72846352
7285 const use_operator = scalar_ty.bitSize(zcu) <= 64;6353 const use_operator = scalar_ty.bitSize(zcu) <= 64;
7286 const op: union(enum) {6354 const op: union(enum) {
...@@ -7327,10 +6395,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7327,10 +6395,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7327 // }6395 // }
73286396
7329 const accum = try f.allocLocal(inst, scalar_ty);6397 const accum = try f.allocLocal(inst, scalar_ty);
7330 try f.writeCValue(w, accum, .Other);6398 try f.writeCValue(w, accum, .other);
7331 try w.writeAll(" = ");6399 try w.writeAll(" = ");
73326400
7333 try f.object.dg.renderValue(w, switch (reduce.operation) {6401 try f.dg.renderValue(w, switch (reduce.operation) {
7334 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {6402 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
7335 .bool => Value.false,6403 .bool => Value.false,
7336 .int => try pt.intValue(scalar_ty, 0),6404 .int => try pt.intValue(scalar_ty, 0),
...@@ -7366,58 +6434,58 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7366,58 +6434,58 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7366 .float => try pt.floatValue(scalar_ty, std.math.nan(f128)),6434 .float => try pt.floatValue(scalar_ty, std.math.nan(f128)),
7367 else => unreachable,6435 else => unreachable,
7368 },6436 },
7369 }, .Other);6437 }, .other);
7370 try w.writeByte(';');6438 try w.writeByte(';');
7371 try f.object.newline();6439 try f.newline();
73726440
7373 const v = try Vectorize.start(f, inst, w, operand_ty);6441 const v = try Vectorize.start(f, inst, w, operand_ty);
7374 try f.writeCValue(w, accum, .Other);6442 try f.writeCValue(w, accum, .other);
7375 switch (op) {6443 switch (op) {
7376 .builtin => |func| {6444 .builtin => |func| {
7377 try w.print(" = zig_{s}_", .{func.operation});6445 try w.print(" = zig_{s}_", .{func.operation});
7378 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);6446 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
7379 try w.writeByte('(');6447 try w.writeByte('(');
7380 try f.writeCValue(w, accum, .FunctionArgument);6448 try f.writeCValue(w, accum, .other);
7381 try w.writeAll(", ");6449 try w.writeAll(", ");
7382 try f.writeCValue(w, operand, .Other);6450 try f.writeCValue(w, operand, .other);
7383 try v.elem(f, w);6451 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);
7385 try w.writeByte(')');6453 try w.writeByte(')');
7386 },6454 },
7387 .infix => |ass| {6455 .infix => |ass| {
7388 try w.writeAll(ass);6456 try w.writeAll(ass);
7389 try f.writeCValue(w, operand, .Other);6457 try f.writeCValue(w, operand, .other);
7390 try v.elem(f, w);6458 try v.elem(f, w);
7391 },6459 },
7392 .ternary => |cmp| {6460 .ternary => |cmp| {
7393 try w.writeAll(" = ");6461 try w.writeAll(" = ");
7394 try f.writeCValue(w, accum, .Other);6462 try f.writeCValue(w, accum, .other);
7395 try w.writeAll(cmp);6463 try w.writeAll(cmp);
7396 try f.writeCValue(w, operand, .Other);6464 try f.writeCValue(w, operand, .other);
7397 try v.elem(f, w);6465 try v.elem(f, w);
7398 try w.writeAll(" ? ");6466 try w.writeAll(" ? ");
7399 try f.writeCValue(w, accum, .Other);6467 try f.writeCValue(w, accum, .other);
7400 try w.writeAll(" : ");6468 try w.writeAll(" : ");
7401 try f.writeCValue(w, operand, .Other);6469 try f.writeCValue(w, operand, .other);
7402 try v.elem(f, w);6470 try v.elem(f, w);
7403 },6471 },
7404 }6472 }
7405 try w.writeByte(';');6473 try w.writeByte(';');
7406 try f.object.newline();6474 try f.newline();
7407 try v.end(f, inst, w);6475 try v.end(f, inst, w);
74086476
7409 return accum;6477 return accum;
7410}6478}
74116479
7412fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {6480fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7413 const pt = f.object.dg.pt;6481 const pt = f.dg.pt;
7414 const zcu = pt.zcu;6482 const zcu = pt.zcu;
7415 const ip = &zcu.intern_pool;6483 const ip = &zcu.intern_pool;
7416 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6484 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7417 const inst_ty = f.typeOfIndex(inst);6485 const inst_ty = f.typeOfIndex(inst);
7418 const len: usize = @intCast(inst_ty.arrayLen(zcu));6486 const len: usize = @intCast(inst_ty.arrayLen(zcu));
7419 const elements: []const Air.Inst.Ref = @ptrCast(f.air.extra.items[ty_pl.payload..][0..len]);6487 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;
7421 const resolved_elements = try gpa.alloc(CValue, elements.len);6489 const resolved_elements = try gpa.alloc(CValue, elements.len);
7422 defer gpa.free(resolved_elements);6490 defer gpa.free(resolved_elements);
7423 for (resolved_elements, elements) |*resolved_element, element| {6491 for (resolved_elements, elements) |*resolved_element, element| {
...@@ -7430,28 +6498,23 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7430,28 +6498,23 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7430 }6498 }
7431 }6499 }
74326500
7433 const w = &f.object.code.writer;6501 const w = &f.code.writer;
7434 const local = try f.allocLocal(inst, inst_ty);6502 const local = try f.allocLocal(inst, inst_ty);
7435 switch (ip.indexToKey(inst_ty.toIntern())) {6503 switch (ip.indexToKey(inst_ty.toIntern())) {
7436 inline .array_type, .vector_type => |info, tag| {6504 inline .array_type, .vector_type => |info, tag| {
7437 const a: Assignment = .{
7438 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),
7439 };
7440 for (resolved_elements, 0..) |element, i| {6505 for (resolved_elements, 0..) |element, i| {
7441 try a.restart(f, w);6506 try f.writeCValueMember(w, local, .{ .identifier = "array" });
7442 try f.writeCValue(w, local, .Other);6507 try w.print("[{d}] = ", .{i});
7443 try w.print("[{d}]", .{i});6508 try f.writeCValue(w, element, .other);
7444 try a.assign(f, w);6509 try w.writeByte(';');
7445 try f.writeCValue(w, element, .Other);6510 try f.newline();
7446 try a.end(f, w);
7447 }6511 }
7448 if (tag == .array_type and info.sentinel != .none) {6512 if (tag == .array_type and info.sentinel != .none) {
7449 try a.restart(f, w);6513 try f.writeCValueMember(w, local, .{ .identifier = "array" });
7450 try f.writeCValue(w, local, .Other);6514 try w.print("[{d}] = ", .{info.len});
7451 try w.print("[{d}]", .{info.len});6515 try f.dg.renderValue(w, Value.fromInterned(info.sentinel), .other);
7452 try a.assign(f, w);6516 try w.writeByte(';');
7453 try f.object.dg.renderValue(w, Value.fromInterned(info.sentinel), .Other);6517 try f.newline();
7454 try a.end(f, w);
7455 }6518 }
7456 },6519 },
7457 .struct_type => {6520 .struct_type => {
...@@ -7461,13 +6524,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7461,13 +6524,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7461 var field_it = loaded_struct.iterateRuntimeOrder(ip);6524 var field_it = loaded_struct.iterateRuntimeOrder(ip);
7462 while (field_it.next()) |field_index| {6525 while (field_it.next()) |field_index| {
7463 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);6526 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));6529 try f.writeCValueMember(w, local, .{ .identifier = loaded_struct.field_names.get(ip)[field_index].toSlice(ip) });
7467 try f.writeCValueMember(w, local, .{ .identifier = loaded_struct.fieldName(ip, field_index).toSlice(ip) });6530 try w.writeAll(" = ");
7468 try a.assign(f, w);6531 try f.writeCValue(w, resolved_elements[field_index], .other);
7469 try f.writeCValue(w, resolved_elements[field_index], .Other);6532 try w.writeByte(';');
7470 try a.end(f, w);6533 try f.newline();
7471 }6534 }
7472 },6535 },
7473 .@"packed" => unreachable, // `Air.Legalize.Feature.expand_packed_struct_init` handles this case6536 .@"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 {...@@ -7476,13 +6539,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7476 .tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {6539 .tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {
7477 if (tuple_info.values.get(ip)[field_index] != .none) continue;6540 if (tuple_info.values.get(ip)[field_index] != .none) continue;
7478 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);6541 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));
7482 try f.writeCValueMember(w, local, .{ .field = field_index });6544 try f.writeCValueMember(w, local, .{ .field = field_index });
7483 try a.assign(f, w);6545 try w.writeAll(" = ");
7484 try f.writeCValue(w, resolved_elements[field_index], .Other);6546 try f.writeCValue(w, resolved_elements[field_index], .other);
7485 try a.end(f, w);6547 try w.writeByte(';');
6548 try f.newline();
7486 },6549 },
7487 else => unreachable,6550 else => unreachable,
7488 }6551 }
...@@ -7491,49 +6554,52 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7491,49 +6554,52 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7491}6554}
74926555
7493fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {6556fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7494 const pt = f.object.dg.pt;6557 const pt = f.dg.pt;
7495 const zcu = pt.zcu;6558 const zcu = pt.zcu;
7496 const ip = &zcu.intern_pool;6559 const ip = &zcu.intern_pool;
7497 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6560 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7498 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;6561 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
6562 const field_index = extra.field_index;
74996563
7500 const union_ty = f.typeOfIndex(inst);6564 const union_ty = f.typeOfIndex(inst);
7501 const loaded_union = ip.loadUnionType(union_ty.toIntern());6565 const loaded_union = ip.loadUnionType(union_ty.toIntern());
7502 const field_name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index];6566 const loaded_enum = ip.loadEnumType(loaded_union.enum_tag_type);
7503 const payload_ty = f.typeOf(extra.init);6567
7504 const payload = try f.resolveInst(extra.init);6568 const payload = try f.resolveInst(extra.init);
7505 try reap(f, inst, &.{extra.init});6569 try reap(f, inst, &.{extra.init});
75066570
7507 const w = &f.object.code.writer;6571 const w = &f.code.writer;
7508 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);6572 if (loaded_union.layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
75096573
7510 const local = try f.allocLocal(inst, union_ty);6574 const local = try f.allocLocal(inst, union_ty);
75116575
7512 const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {6576 if (loaded_union.has_runtime_tag) {
7513 const layout = union_ty.unionGetLayout(zcu);6577 try f.writeCValueMember(w, local, .{ .identifier = "tag" });
7514 if (layout.tag_size != 0) {6578 if (loaded_enum.field_values.len == 0) {
7515 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;6579 // auto-numbered
7516 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);6580 try w.print(" = {d};", .{field_index});
75176581 } else {
7518 const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));6582 const tag_int_val: Value = .fromInterned(loaded_enum.field_values.get(ip)[field_index]);
7519 try f.writeCValueMember(w, local, .{ .identifier = "tag" });6583 try w.print(" = {f};", .{try f.fmtIntLiteralDec(tag_int_val)});
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);
7523 }6584 }
7524 break :field .{ .payload_identifier = field_name.toSlice(ip) };6585 try f.newline();
7525 } else .{ .identifier = field_name.toSlice(ip) };6586 }
75266587
7527 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));6588 const field_name_slice = loaded_enum.field_names.get(ip)[field_index].toSlice(ip);
7528 try f.writeCValueMember(w, local, field);6589 switch (loaded_union.layout) {
7529 try a.assign(f, w);6590 .auto => try f.writeCValueMember(w, local, .{ .payload_identifier = field_name_slice }),
7530 try f.writeCValue(w, payload, .Other);6591 .@"extern" => try f.writeCValueMember(w, local, .{ .identifier = field_name_slice }),
7531 try a.end(f, w);6592 .@"packed" => unreachable,
6593 }
6594 try w.writeAll(" = ");
6595 try f.writeCValue(w, payload, .other);
6596 try w.writeByte(';');
6597 try f.newline();
7532 return local;6598 return local;
7533}6599}
75346600
7535fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {6601fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7536 const pt = f.object.dg.pt;6602 const pt = f.dg.pt;
7537 const zcu = pt.zcu;6603 const zcu = pt.zcu;
7538 const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;6604 const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
75396605
...@@ -7541,16 +6607,16 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7541,16 +6607,16 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7541 const ptr = try f.resolveInst(prefetch.ptr);6607 const ptr = try f.resolveInst(prefetch.ptr);
7542 try reap(f, inst, &.{prefetch.ptr});6608 try reap(f, inst, &.{prefetch.ptr});
75436609
7544 const w = &f.object.code.writer;6610 const w = &f.code.writer;
7545 switch (prefetch.cache) {6611 switch (prefetch.cache) {
7546 .data => {6612 .data => {
7547 try w.writeAll("zig_prefetch(");6613 try w.writeAll("zig_prefetch(");
7548 if (ptr_ty.isSlice(zcu))6614 if (ptr_ty.isSlice(zcu))
7549 try f.writeCValueMember(w, ptr, .{ .identifier = "ptr" })6615 try f.writeCValueMember(w, ptr, .{ .identifier = "ptr" })
7550 else6616 else
7551 try f.writeCValue(w, ptr, .FunctionArgument);6617 try f.writeCValue(w, ptr, .other);
7552 try w.print(", {d}, {d});", .{ @intFromEnum(prefetch.rw), prefetch.locality });6618 try w.print(", {d}, {d});", .{ @intFromEnum(prefetch.rw), prefetch.locality });
7553 try f.object.newline();6619 try f.newline();
7554 },6620 },
7555 // The available prefetch intrinsics do not accept a cache argument; only6621 // The available prefetch intrinsics do not accept a cache argument; only
7556 // address, rw, and locality.6622 // address, rw, and locality.
...@@ -7563,14 +6629,14 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7563,14 +6629,14 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7563fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {6629fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
7564 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6630 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;
7567 const inst_ty = f.typeOfIndex(inst);6633 const inst_ty = f.typeOfIndex(inst);
7568 const local = try f.allocLocal(inst, inst_ty);6634 const local = try f.allocLocal(inst, inst_ty);
7569 try f.writeCValue(w, local, .Other);6635 try f.writeCValue(w, local, .other);
75706636
7571 try w.writeAll(" = ");6637 try w.writeAll(" = ");
7572 try w.print("zig_wasm_memory_size({d});", .{pl_op.payload});6638 try w.print("zig_wasm_memory_size({d});", .{pl_op.payload});
7573 try f.object.newline();6639 try f.newline();
75746640
7575 return local;6641 return local;
7576}6642}
...@@ -7578,23 +6644,23 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7578,23 +6644,23 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
7578fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {6644fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
7579 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6645 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;
7582 const inst_ty = f.typeOfIndex(inst);6648 const inst_ty = f.typeOfIndex(inst);
7583 const operand = try f.resolveInst(pl_op.operand);6649 const operand = try f.resolveInst(pl_op.operand);
7584 try reap(f, inst, &.{pl_op.operand});6650 try reap(f, inst, &.{pl_op.operand});
7585 const local = try f.allocLocal(inst, inst_ty);6651 const local = try f.allocLocal(inst, inst_ty);
7586 try f.writeCValue(w, local, .Other);6652 try f.writeCValue(w, local, .other);
75876653
7588 try w.writeAll(" = ");6654 try w.writeAll(" = ");
7589 try w.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});6655 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);
7591 try w.writeAll(");");6657 try w.writeAll(");");
7592 try f.object.newline();6658 try f.newline();
7593 return local;6659 return local;
7594}6660}
75956661
7596fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {6662fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7597 const pt = f.object.dg.pt;6663 const pt = f.dg.pt;
7598 const zcu = pt.zcu;6664 const zcu = pt.zcu;
7599 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6665 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
7600 const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;6666 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 {...@@ -7607,24 +6673,24 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7607 const inst_ty = f.typeOfIndex(inst);6673 const inst_ty = f.typeOfIndex(inst);
7608 const inst_scalar_ty = inst_ty.scalarType(zcu);6674 const inst_scalar_ty = inst_ty.scalarType(zcu);
76096675
7610 const w = &f.object.code.writer;6676 const w = &f.code.writer;
7611 const local = try f.allocLocal(inst, inst_ty);6677 const local = try f.allocLocal(inst, inst_ty);
7612 const v = try Vectorize.start(f, inst, w, inst_ty);6678 const v = try Vectorize.start(f, inst, w, inst_ty);
7613 try f.writeCValue(w, local, .Other);6679 try f.writeCValue(w, local, .other);
7614 try v.elem(f, w);6680 try v.elem(f, w);
7615 try w.writeAll(" = zig_fma_");6681 try w.writeAll(" = zig_fma_");
7616 try f.object.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);6682 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
7617 try w.writeByte('(');6683 try w.writeByte('(');
7618 try f.writeCValue(w, mulend1, .FunctionArgument);6684 try f.writeCValue(w, mulend1, .other);
7619 try v.elem(f, w);6685 try v.elem(f, w);
7620 try w.writeAll(", ");6686 try w.writeAll(", ");
7621 try f.writeCValue(w, mulend2, .FunctionArgument);6687 try f.writeCValue(w, mulend2, .other);
7622 try v.elem(f, w);6688 try v.elem(f, w);
7623 try w.writeAll(", ");6689 try w.writeAll(", ");
7624 try f.writeCValue(w, addend, .FunctionArgument);6690 try f.writeCValue(w, addend, .other);
7625 try v.elem(f, w);6691 try v.elem(f, w);
7626 try w.writeAll(");");6692 try w.writeAll(");");
7627 try f.object.newline();6693 try f.newline();
7628 try v.end(f, inst, w);6694 try v.end(f, inst, w);
76296695
7630 return local;6696 return local;
...@@ -7632,34 +6698,33 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7632,34 +6698,33 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
76326698
7633fn airRuntimeNavPtr(f: *Function, inst: Air.Inst.Index) !CValue {6699fn airRuntimeNavPtr(f: *Function, inst: Air.Inst.Index) !CValue {
7634 const ty_nav = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;6700 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;
7636 const local = try f.allocLocal(inst, .fromInterned(ty_nav.ty));6702 const local = try f.allocLocal(inst, .fromInterned(ty_nav.ty));
7637 try f.writeCValue(w, local, .Other);6703 try f.writeCValue(w, local, .other);
7638 try w.writeAll(" = ");6704 try w.writeAll(" = ");
7639 try f.object.dg.renderNav(w, ty_nav.nav, .Other);6705 try f.dg.renderNav(w, ty_nav.nav, .other);
7640 try w.writeByte(';');6706 try w.writeByte(';');
7641 try f.object.newline();6707 try f.newline();
7642 return local;6708 return local;
7643}6709}
76446710
7645fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {6711fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7646 const pt = f.object.dg.pt;6712 const pt = f.dg.pt;
7647 const zcu = pt.zcu;6713 const zcu = pt.zcu;
7648 const inst_ty = f.typeOfIndex(inst);6714 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;
7654 const local = try f.allocLocal(inst, inst_ty);6719 const local = try f.allocLocal(inst, inst_ty);
7655 try w.writeAll("va_start(*(va_list *)&");6720 try w.writeAll("va_start(*(va_list *)&");
7656 try f.writeCValue(w, local, .Other);6721 try f.writeCValue(w, local, .other);
7657 if (function_info.param_ctypes.len > 0) {6722 if (f.next_arg_index > 0) {
7658 try w.writeAll(", ");6723 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);
7660 }6725 }
7661 try w.writeAll(");");6726 try w.writeAll(");");
7662 try f.object.newline();6727 try f.newline();
7663 return local;6728 return local;
7664}6729}
76656730
...@@ -7670,15 +6735,15 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7670,15 +6735,15 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
7670 const va_list = try f.resolveInst(ty_op.operand);6735 const va_list = try f.resolveInst(ty_op.operand);
7671 try reap(f, inst, &.{ty_op.operand});6736 try reap(f, inst, &.{ty_op.operand});
76726737
7673 const w = &f.object.code.writer;6738 const w = &f.code.writer;
7674 const local = try f.allocLocal(inst, inst_ty);6739 const local = try f.allocLocal(inst, inst_ty);
7675 try f.writeCValue(w, local, .Other);6740 try f.writeCValue(w, local, .other);
7676 try w.writeAll(" = va_arg(*(va_list *)");6741 try w.writeAll(" = va_arg(*(va_list *)");
7677 try f.writeCValue(w, va_list, .Other);6742 try f.writeCValue(w, va_list, .other);
7678 try w.writeAll(", ");6743 try w.writeAll(", ");
7679 try f.renderType(w, ty_op.ty.toType());6744 try f.renderType(w, ty_op.ty.toType());
7680 try w.writeAll(");");6745 try w.writeAll(");");
7681 try f.object.newline();6746 try f.newline();
7682 return local;6747 return local;
7683}6748}
76846749
...@@ -7688,11 +6753,11 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7688,11 +6753,11 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
7688 const va_list = try f.resolveInst(un_op);6753 const va_list = try f.resolveInst(un_op);
7689 try reap(f, inst, &.{un_op});6754 try reap(f, inst, &.{un_op});
76906755
7691 const w = &f.object.code.writer;6756 const w = &f.code.writer;
7692 try w.writeAll("va_end(*(va_list *)");6757 try w.writeAll("va_end(*(va_list *)");
7693 try f.writeCValue(w, va_list, .Other);6758 try f.writeCValue(w, va_list, .other);
7694 try w.writeAll(");");6759 try w.writeAll(");");
7695 try f.object.newline();6760 try f.newline();
7696 return .none;6761 return .none;
7697}6762}
76986763
...@@ -7703,14 +6768,14 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7703,14 +6768,14 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
7703 const va_list = try f.resolveInst(ty_op.operand);6768 const va_list = try f.resolveInst(ty_op.operand);
7704 try reap(f, inst, &.{ty_op.operand});6769 try reap(f, inst, &.{ty_op.operand});
77056770
7706 const w = &f.object.code.writer;6771 const w = &f.code.writer;
7707 const local = try f.allocLocal(inst, inst_ty);6772 const local = try f.allocLocal(inst, inst_ty);
7708 try w.writeAll("va_copy(*(va_list *)&");6773 try w.writeAll("va_copy(*(va_list *)&");
7709 try f.writeCValue(w, local, .Other);6774 try f.writeCValue(w, local, .other);
7710 try w.writeAll(", *(va_list *)");6775 try w.writeAll(", *(va_list *)");
7711 try f.writeCValue(w, va_list, .Other);6776 try f.writeCValue(w, va_list, .other);
7712 try w.writeAll(");");6777 try w.writeAll(");");
7713 try f.object.newline();6778 try f.newline();
7714 return local;6779 return local;
7715}6780}
77166781
...@@ -8027,103 +7092,193 @@ fn undefPattern(comptime IntType: type) IntType {...@@ -8027,103 +7092,193 @@ fn undefPattern(comptime IntType: type) IntType {
80277092
8028const FormatIntLiteralContext = struct {7093const FormatIntLiteralContext = struct {
8029 dg: *DeclGen,7094 dg: *DeclGen,
8030 int_info: InternPool.Key.IntType,7095 loc: ValueRenderLocation,
8031 kind: CType.Kind,
8032 ctype: CType,
8033 val: Value,7096 val: Value,
7097 cty: CType,
8034 base: u8,7098 base: u8,
8035 case: std.fmt.Case,7099 case: std.fmt.Case,
8036};7100};
8037fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void {7101fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void {
8038 const pt = data.dg.pt;7102 const dg = data.dg;
8039 const zcu = pt.zcu;7103 const zcu = dg.pt.zcu;
8040 const target = &data.dg.mod.resolved_target.result;7104 const target = &dg.mod.resolved_target.result;
8041 const ctype_pool = &data.dg.ctype_pool;7105
80427106 const val = data.val;
8043 const ExpectedContents = struct {7107 const ty = val.typeOf(zcu);
8044 const base = 10;7108
8045 const bits = 128;7109 assert(!val.isUndef(zcu));
8046 const limbs_count = BigInt.calcTwosCompLimbCount(bits);7110
80477111 var space: Value.BigIntSpace = undefined;
8048 undef_limbs: [limbs_count]BigIntLimb,7112 const val_bigint = val.toBigInt(&space, zcu);
8049 wrap_limbs: [limbs_count]BigIntLimb,7113
8050 to_string_buf: [bits]u8,7114 switch (CType.classifyInt(ty, zcu)) {
8051 to_string_limbs: [BigInt.calcToStringLimbsBufferLen(limbs_count, base)]BigIntLimb,7115 .void => unreachable, // opv
8052 };7116 .small => |int_cty| return FormatInt128.format(.{
8053 var stack align(@alignOf(ExpectedContents)) =7117 .target = zcu.getTarget(),
8054 std.heap.stackFallback(@sizeOf(ExpectedContents), data.dg.gpa);7118 .int_cty = int_cty,
8055 const allocator = stack.get();7119 .val = val_bigint,
80567120 .is_global = data.loc == .static_initializer,
8057 var undef_limbs: []BigIntLimb = &.{};7121 .base = data.base,
8058 defer allocator.free(undef_limbs);7122 .case = data.case,
80597123 }, w),
8060 var int_buf: Value.BigIntSpace = undefined;7124 .big => |big| {
8061 const int = if (data.val.isUndef(zcu)) blk: {7125 if (!data.loc.isInitializer()) {
8062 undef_limbs = allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits)) catch return error.WriteFailed;7126 // Use `CType.fmtTypeName` directly to avoid the possibility of `error.OutOfMemory`.
8063 @memset(undef_limbs, undefPattern(BigIntLimb));7127 try w.print("({f})", .{data.cty.fmtTypeName(zcu)});
80647128 }
8065 var undef_int = BigInt.Mutable{7129
8066 .limbs = undef_limbs,7130 try w.writeAll("{{");
8067 .len = undef_limbs.len,7131
8068 .positive = true,7132 var limb_buf: [std.math.big.int.calcTwosCompLimbCount(65535)]std.math.big.Limb = undefined;
8069 };7133 for (0..big.limbs_len) |limb_index| {
8070 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);7134 if (limb_index != 0) try w.writeAll(", ");
8071 break :blk undef_int.toConst();7135 const limb_bit_offset: u16 = switch (target.cpu.arch.endian()) {
8072 } else data.val.toBigInt(&int_buf, zcu);7136 .little => @intCast(limb_index * big.limb_size.bits()),
8073 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));7137 .big => @intCast((big.limbs_len - limb_index - 1) * big.limb_size.bits()),
80747138 };
8075 const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8);7139 var limb_bigint: std.math.big.int.Mutable = .{
8076 var one_limbs: [BigInt.calcLimbLen(1)]BigIntLimb = undefined;7140 .limbs = &limb_buf,
8077 const one = BigInt.Mutable.init(&one_limbs, 1).toConst();7141 .len = undefined,
80787142 .positive = undefined,
8079 var wrap = BigInt.Mutable{7143 };
8080 .limbs = allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)) catch return error.WriteFailed,7144 limb_bigint.shiftRight(val_bigint, limb_bit_offset);
8081 .len = undefined,7145 limb_bigint.truncate(limb_bigint.toConst(), .unsigned, big.limb_size.bits());
8082 .positive = undefined,7146 try FormatInt128.format(.{
8083 };7147 .target = zcu.getTarget(),
8084 defer allocator.free(wrap.limbs);7148 .int_cty = big.limb_size.unsigned(),
80857149 .val = limb_bigint.toConst(),
8086 const c_limb_info: struct {7150 .is_global = data.loc == .static_initializer,
8087 ctype: CType,7151 .base = data.base,
8088 count: usize,7152 .case = data.case,
8089 endian: std.builtin.Endian,7153 }, w);
8090 homogeneous: bool,7154 }
8091 } = switch (data.ctype.info(ctype_pool)) {7155
8092 .basic => |basic_info| switch (basic_info) {7156 try w.writeAll("}}");
8093 else => .{7157 },
8094 .ctype = .void,7158 }
8095 .count = 1,7159}
8096 .endian = .little,7160const FormatInt128 = struct {
8097 .homogeneous = true,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 });
8098 },7213 },
8099 .zig_u128, .zig_i128 => .{7214
8100 .ctype = .u64,7215 .zig_i128 => {
8101 .count = 2,7216 const raw = val.toInt(i128) catch unreachable;
8102 .endian = .big,7217 const lo: u64 = @truncate(@as(u128, @bitCast(raw)));
8103 .homogeneous = false,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 });
8104 },7225 },
8105 },7226 }
8106 .array => |array_info| .{7227 }
8107 .ctype = array_info.elem_ctype,7228};
8108 .count = @intCast(array_info.len),7229fn fmtUnsignedIntLiteralSmall(
8109 .endian = target.cpu.arch.endian(),7230 target: *const std.Target,
8110 .homogeneous = true,7231 int_cty: CType.Int,
8111 },7232 val: u64,
8112 else => unreachable,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,
8113 };7244 };
8114 if (c_limb_info.count == 1) {7245}
8115 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or7246fn fmtSignedIntLiteralSmall(
8116 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))7247 target: *const std.Target,
8117 return w.print("{s}_{s}", .{7248 int_cty: CType.Int,
8118 data.ctype.getStandardDefineAbbrev() orelse return w.print("zig_{s}Int_{c}{d}", .{7249 val: i64,
8119 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,7250 is_global: bool,
8120 }),7251 base: u8,
8121 if (int.positive) "MAX" else "MIN",7252 case: std.fmt.Case,
8122 });7253) FormatSignedIntLiteralSmall {
81237254 return .{
8124 if (!int.positive) try w.writeByte('-');7255 .target = target,
8125 try data.ctype.renderLiteralPrefix(w, data.kind, ctype_pool);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));
8127 switch (data.base) {7282 switch (data.base) {
8128 2 => try w.writeAll("0b"),7283 2 => try w.writeAll("0b"),
8129 8 => try w.writeByte('0'),7284 8 => try w.writeByte('0'),
...@@ -8131,68 +7286,131 @@ fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void...@@ -8131,68 +7286,131 @@ fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void
8131 16 => try w.writeAll("0x"),7286 16 => try w.writeAll("0x"),
8132 else => unreachable,7287 else => unreachable,
8133 }7288 }
8134 const string = int.abs().toStringAlloc(allocator, data.base, data.case) catch7289 // This `@abs` is safe thanks to the `min_int` case above.
8135 return error.WriteFailed;7290 try w.printInt(@abs(data.val), data.base, data.case, .{});
8136 defer allocator.free(string);7291 try w.writeAll(intLiteralSuffix(data.int_cty));
8137 try w.writeAll(string);7292 }
8138 } else {7293};
8139 try data.ctype.renderLiteralPrefix(w, data.kind, ctype_pool);7294const FormatUnsignedIntLiteralSmall = struct {
8140 wrap.truncate(int, .unsigned, c_bits);7295 target: *const std.Target,
8141 @memset(wrap.limbs[wrap.len..], 0);7296 int_cty: CType.Int,
8142 wrap.len = wrap.limbs.len;7297 val: u64,
8143 const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count);7298 is_global: bool,
81447299 base: u8,
8145 var c_limb_int_info: std.builtin.Type.Int = .{7300 case: std.fmt.Case,
8146 .signedness = undefined,7301 pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void {
8147 .bits = @intCast(@divExact(c_bits, c_limb_info.count)),7302 const bits = data.int_cty.bits(data.target);
8148 };7303 const max_int: u64 = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits);
8149 var c_limb_ctype: CType = undefined;7304 if (data.val == max_int) {
81507305 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
8151 var limb_offset: usize = 0;7306 }
8152 const most_significant_limb_i = wrap.len - limbs_per_c_limb;7307 try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global));
8153 while (limb_offset < wrap.len) : (limb_offset += limbs_per_c_limb) {7308 switch (data.base) {
8154 const limb_i = switch (c_limb_info.endian) {7309 2 => try w.writeAll("0b"),
8155 .little => limb_offset,7310 8 => try w.writeByte('0'),
8156 .big => most_significant_limb_i - limb_offset,7311 10 => {},
8157 };7312 16 => try w.writeAll("0x"),
8158 var c_limb_mut = BigInt.Mutable{7313 else => unreachable,
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);
8193 }7314 }
7315 try w.printInt(data.val, data.base, data.case, .{});
7316 try w.writeAll(intLiteralSuffix(data.int_cty));
8194 }7317 }
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 };
8196}7414}
81977415
8198const Materialize = struct {7416const Materialize = struct {
...@@ -8207,7 +7425,7 @@ const Materialize = struct {...@@ -8207,7 +7425,7 @@ const Materialize = struct {
8207 }7425 }
82087426
8209 pub fn mat(self: Materialize, f: *Function, w: *Writer) !void {7427 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);
8211 }7429 }
82127430
8213 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {7431 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
...@@ -8215,95 +7433,52 @@ const Materialize = struct {...@@ -8215,95 +7433,52 @@ const Materialize = struct {
8215 }7433 }
8216};7434};
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
8262const Vectorize = struct {7436const Vectorize = struct {
8263 index: CValue = .none,7437 index: CValue = .none,
82647438
8265 pub fn start(f: *Function, inst: Air.Inst.Index, w: *Writer, ty: Type) !Vectorize {7439 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;
8267 const zcu = pt.zcu;7441 const zcu = pt.zcu;
8268 return if (ty.zigTypeTag(zcu) == .vector) index: {7442 switch (ty.zigTypeTag(zcu)) {
8269 const local = try f.allocLocal(inst, .usize);7443 else => return .{ .index = .none },
82707444 .vector => {
8271 try w.writeAll("for (");7445 const local = try f.allocLocal(inst, .usize);
8272 try f.writeCValue(w, local, .Other);7446 try w.writeAll("for (");
8273 try w.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)});7447 try f.writeCValue(w, local, .other);
8274 try f.writeCValue(w, local, .Other);7448 try w.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)});
8275 try w.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))});7449 try f.writeCValue(w, local, .other);
8276 try f.writeCValue(w, local, .Other);7450 try w.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))});
8277 try w.print(" += {f}) {{\n", .{try f.fmtIntLiteralDec(.one_usize)});7451 try f.writeCValue(w, local, .other);
8278 f.object.indent();7452 try w.print(" += {f}) {{", .{try f.fmtIntLiteralDec(.one_usize)});
8279 try f.object.newline();7453 f.indent();
82807454 try f.newline();
8281 break :index .{ .index = local };7455 return .{ .index = local };
8282 } else .{};7456 },
7457 }
8283 }7458 }
82847459
8285 pub fn elem(self: Vectorize, f: *Function, w: *Writer) !void {7460 pub fn elem(self: Vectorize, f: *Function, w: *Writer) !void {
8286 if (self.index != .none) {7461 if (self.index != .none) {
8287 try w.writeByte('[');7462 try w.writeAll(".array[");
8288 try f.writeCValue(w, self.index, .Other);7463 try f.writeCValue(w, self.index, .other);
8289 try w.writeByte(']');7464 try w.writeByte(']');
8290 }7465 }
8291 }7466 }
82927467
8293 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, w: *Writer) !void {7468 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, w: *Writer) !void {
8294 if (self.index != .none) {7469 if (self.index != .none) {
8295 try f.object.outdent();7470 try f.outdent();
8296 try w.writeByte('}');7471 try w.writeByte('}');
8297 try f.object.newline();7472 try f.newline();
8298 try freeLocal(f, inst, self.index.new_local, null);7473 try freeLocal(f, inst, self.index.new_local, null);
8299 }7474 }
8300 }7475 }
8301};7476};
83027477
8303fn lowersToArray(ty: Type, zcu: *Zcu) bool {7478fn lowersToBigInt(ty: Type, zcu: *const Zcu) bool {
8304 return switch (ty.zigTypeTag(zcu)) {7479 return switch (ty.zigTypeTag(zcu)) {
8305 .array, .vector => return true,7480 .int, .@"enum", .@"struct", .@"union" => CType.classifyInt(ty, zcu) == .big,
8306 else => return ty.isAbiInt(zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(zcu)))) == null,7481 else => false,
8307 };7482 };
8308}7483}
83097484
...@@ -8329,8 +7504,8 @@ fn die(f: *Function, inst: Air.Inst.Index, ref: Air.Inst.Ref) !void {...@@ -8329,8 +7504,8 @@ fn die(f: *Function, inst: Air.Inst.Index, ref: Air.Inst.Ref) !void {
8329}7504}
83307505
8331fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_inst: ?Air.Inst.Index) !void {7506fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_inst: ?Air.Inst.Index) !void {
8332 const gpa = f.object.dg.gpa;7507 const gpa = f.dg.gpa;
8333 const local = &f.locals.items[local_index];7508 const local = f.locals.items[local_index];
8334 if (inst) |i| {7509 if (inst) |i| {
8335 if (ref_inst) |operand| {7510 if (ref_inst) |operand| {
8336 log.debug("%{d}: freeing t{d} (operand %{d})", .{ @intFromEnum(i), local_index, operand });7511 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...@@ -8344,7 +7519,7 @@ fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_i
8344 log.debug("freeing t{d}", .{local_index});7519 log.debug("freeing t{d}", .{local_index});
8345 }7520 }
8346 }7521 }
8347 const gop = try f.free_locals_map.getOrPut(gpa, local.getType());7522 const gop = try f.free_locals_map.getOrPut(gpa, local);
8348 if (!gop.found_existing) gop.value_ptr.* = .{};7523 if (!gop.found_existing) gop.value_ptr.* = .{};
8349 if (std.debug.runtime_safety) {7524 if (std.debug.runtime_safety) {
8350 // If this trips, an unfreeable allocation was attempted to be freed.7525 // If this trips, an unfreeable allocation was attempted to be freed.
...@@ -8401,3 +7576,28 @@ fn deinitFreeLocalsMap(gpa: Allocator, map: *LocalsMap) void {...@@ -8401,3 +7576,28 @@ fn deinitFreeLocalsMap(gpa: Allocator, map: *LocalsMap) void {
8401 }7576 }
8402 map.deinit(gpa);7577 map.deinit(gpa);
8403}7578}
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 {...@@ -520,6 +520,21 @@ pub const Object = struct {
520 gpa: Allocator,520 gpa: Allocator,
521 builder: Builder,521 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
523 debug_compile_unit: Builder.Metadata.Optional,538 debug_compile_unit: Builder.Metadata.Optional,
524539
525 debug_enums_fwd_ref: Builder.Metadata.Optional,540 debug_enums_fwd_ref: Builder.Metadata.Optional,
...@@ -529,9 +544,13 @@ pub const Object = struct {...@@ -529,9 +544,13 @@ pub const Object = struct {
529 debug_globals: std.ArrayList(Builder.Metadata),544 debug_globals: std.ArrayList(Builder.Metadata),
530545
531 debug_file_map: std.AutoHashMapUnmanaged(Zcu.File.Index, Builder.Metadata),546 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
536 target: *const std.Target,555 target: *const std.Target,
537 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,556 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
...@@ -654,35 +673,38 @@ pub const Object = struct {...@@ -654,35 +673,38 @@ pub const Object = struct {
654 obj.* = .{673 obj.* = .{
655 .gpa = gpa,674 .gpa = gpa,
656 .builder = builder,675 .builder = builder,
676 .type_pool = .empty,
677 .lazy_abi_aligns = .empty,
657 .debug_compile_unit = debug_compile_unit,678 .debug_compile_unit = debug_compile_unit,
658 .debug_enums_fwd_ref = debug_enums_fwd_ref,679 .debug_enums_fwd_ref = debug_enums_fwd_ref,
659 .debug_globals_fwd_ref = debug_globals_fwd_ref,680 .debug_globals_fwd_ref = debug_globals_fwd_ref,
660 .debug_enums = .{},681 .debug_enums = .empty,
661 .debug_globals = .{},682 .debug_globals = .empty,
662 .debug_file_map = .{},683 .debug_file_map = .empty,
663 .debug_type_map = .{},684 .debug_types = .empty,
664 .debug_unresolved_namespace_scopes = .{},685 .debug_anyerror_fwd_ref = .none,
665 .target = target,686 .target = target,
666 .nav_map = .{},687 .nav_map = .empty,
667 .uav_map = .{},688 .uav_map = .empty,
668 .enum_tag_name_map = .{},689 .enum_tag_name_map = .empty,
669 .named_enum_map = .{},690 .named_enum_map = .empty,
670 .type_map = .{},691 .type_map = .empty,
671 .error_name_table = .none,692 .error_name_table = .none,
672 .null_opt_usize = .no_init,693 .null_opt_usize = .no_init,
673 .struct_field_map = .{},694 .struct_field_map = .empty,
674 .used = .{},695 .used = .empty,
675 };696 };
676 return obj;697 return obj;
677 }698 }
678699
679 pub fn deinit(self: *Object) void {700 pub fn deinit(self: *Object) void {
680 const gpa = self.gpa;701 const gpa = self.gpa;
702 self.type_pool.deinit(gpa);
703 self.lazy_abi_aligns.deinit(gpa);
681 self.debug_enums.deinit(gpa);704 self.debug_enums.deinit(gpa);
682 self.debug_globals.deinit(gpa);705 self.debug_globals.deinit(gpa);
683 self.debug_file_map.deinit(gpa);706 self.debug_file_map.deinit(gpa);
684 self.debug_type_map.deinit(gpa);707 self.debug_types.deinit(gpa);
685 self.debug_unresolved_namespace_scopes.deinit(gpa);
686 self.nav_map.deinit(gpa);708 self.nav_map.deinit(gpa);
687 self.uav_map.deinit(gpa);709 self.uav_map.deinit(gpa);
688 self.enum_tag_name_map.deinit(gpa);710 self.enum_tag_name_map.deinit(gpa);
...@@ -824,19 +846,13 @@ pub const Object = struct {...@@ -824,19 +846,13 @@ pub const Object = struct {
824 }846 }
825847
826 if (!o.builder.strip) {848 if (!o.builder.strip) {
827 {849 if (o.debug_anyerror_fwd_ref.unwrap()) |fwd_ref| {
828 var i: usize = 0;850 const debug_anyerror_type = try o.lowerDebugAnyerrorType(pt);
829 while (i < o.debug_unresolved_namespace_scopes.count()) : (i += 1) {851 o.builder.resolveDebugForwardReference(fwd_ref, debug_anyerror_type);
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 }
838 }852 }
839853
854 try o.flushTypePool(pt);
855
840 o.builder.resolveDebugForwardReference(856 o.builder.resolveDebugForwardReference(
841 o.debug_enums_fwd_ref.unwrap().?,857 o.debug_enums_fwd_ref.unwrap().?,
842 try o.builder.metadataTuple(o.debug_enums.items),858 try o.builder.metadataTuple(o.debug_enums.items),
...@@ -1395,10 +1411,10 @@ pub const Object = struct {...@@ -1395,10 +1411,10 @@ pub const Object = struct {
1395 if (ptr_info.flags.is_const) {1411 if (ptr_info.flags.is_const) {
1396 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);1412 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
1397 }1413 }
1398 const elem_align = (if (ptr_info.flags.alignment != .none)1414 const elem_align: Builder.Alignment.Lazy = switch (ptr_info.flags.alignment) {
1399 @as(InternPool.Alignment, ptr_info.flags.alignment)1415 else => |a| .wrap(a.toLlvm()),
1400 else1416 .none => try o.lazyAbiAlignment(pt, .fromInterned(ptr_info.child)),
1401 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();1417 };
1402 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);1418 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
1403 const ptr_param = wip.arg(llvm_arg_i);1419 const ptr_param = wip.arg(llvm_arg_i);
1404 llvm_arg_i += 1;1420 llvm_arg_i += 1;
...@@ -1472,7 +1488,7 @@ pub const Object = struct {...@@ -1472,7 +1488,7 @@ pub const Object = struct {
14721488
1473 const line_number = zcu.navSrcLine(func.owner_nav) + 1;1489 const line_number = zcu.navSrcLine(func.owner_nav) + 1;
1474 const is_internal_linkage = ip.indexToKey(nav.status.fully_resolved.val) != .@"extern";1490 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
1477 const subprogram = try o.builder.debugSubprogram(1493 const subprogram = try o.builder.debugSubprogram(
1478 file,1494 file,
...@@ -1522,7 +1538,7 @@ pub const Object = struct {...@@ -1522,7 +1538,7 @@ pub const Object = struct {
15221538
1523 break :f .{1539 break :f .{
1524 .counters_variable = counters_variable,1540 .counters_variable = counters_variable,
1525 .pcs = .{},1541 .pcs = .empty,
1526 };1542 };
1527 };1543 };
15281544
...@@ -1538,10 +1554,10 @@ pub const Object = struct {...@@ -1538,10 +1554,10 @@ pub const Object = struct {
1538 .args = args.items,1554 .args = args.items,
1539 .arg_index = 0,1555 .arg_index = 0,
1540 .arg_inline_index = 0,1556 .arg_inline_index = 0,
1541 .func_inst_table = .{},1557 .func_inst_table = .empty,
1542 .blocks = .{},1558 .blocks = .empty,
1543 .loops = .{},1559 .loops = .empty,
1544 .switch_dispatch_info = .{},1560 .switch_dispatch_info = .empty,
1545 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,1561 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
1546 .file = file,1562 .file = file,
1547 .scope = subprogram,1563 .scope = subprogram,
...@@ -1599,6 +1615,7 @@ pub const Object = struct {...@@ -1599,6 +1615,7 @@ pub const Object = struct {
1599 }1615 }
16001616
1601 try fg.wip.finish();1617 try fg.wip.finish();
1618 try o.flushTypePool(pt);
1602 }1619 }
16031620
1604 pub fn updateNav(self: *Object, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {1621 pub fn updateNav(self: *Object, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
...@@ -1615,6 +1632,11 @@ pub const Object = struct {...@@ -1615,6 +1632,11 @@ pub const Object = struct {
1615 },1632 },
1616 else => |e| return e,1633 else => |e| return e,
1617 };1634 };
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 });
1618 }1640 }
16191641
1620 pub fn updateExports(1642 pub fn updateExports(
...@@ -1810,6 +1832,84 @@ pub const Object = struct {...@@ -1810,6 +1832,84 @@ pub const Object = struct {
1810 }1832 }
1811 }1833 }
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
1813 fn getDebugFile(o: *Object, pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.Error!Builder.Metadata {1913 fn getDebugFile(o: *Object, pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.Error!Builder.Metadata {
1814 const gpa = o.gpa;1914 const gpa = o.gpa;
1815 const gop = try o.debug_file_map.getOrPut(gpa, file_index);1915 const gop = try o.debug_file_map.getOrPut(gpa, file_index);
...@@ -1826,10 +1926,19 @@ pub const Object = struct {...@@ -1826,10 +1926,19 @@ pub const Object = struct {
1826 return gop.value_ptr.*;1926 return gop.value_ptr.*;
1827 }1927 }
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(
1830 o: *Object,1938 o: *Object,
1831 pt: Zcu.PerThread,1939 pt: Zcu.PerThread,
1832 ty: Type,1940 ty: Type,
1941 ty_fwd_ref: Builder.Metadata,
1833 ) Allocator.Error!Builder.Metadata {1942 ) Allocator.Error!Builder.Metadata {
1834 assert(!o.builder.strip);1943 assert(!o.builder.strip);
18351944
...@@ -1838,312 +1947,137 @@ pub const Object = struct {...@@ -1838,312 +1947,137 @@ pub const Object = struct {
1838 const zcu = pt.zcu;1947 const zcu = pt.zcu;
1839 const ip = &zcu.intern_pool;1948 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
1843 switch (ty.zigTypeTag(zcu)) {1961 switch (ty.zigTypeTag(zcu)) {
1844 .void,1962 .void,
1845 .noreturn,1963 .noreturn,
1846 => {1964 .comptime_int,
1847 const debug_void_type = try o.builder.debugSignedType(1965 .comptime_float,
1848 try o.builder.metadataString("void"),1966 .type,
1849 0,1967 .undefined,
1850 );1968 .null,
1851 try o.debug_type_map.put(gpa, ty.toIntern(), debug_void_type);1969 .enum_literal,
1852 return debug_void_type;1970 => return o.builder.debugSignedType(name, 0),
1853 },1971
1972 .float => return o.builder.debugFloatType(name, ty.floatBits(target)),
1973
1974 .bool => return o.builder.debugBoolType(name, 8),
1975
1854 .int => {1976 .int => {
1855 const info = ty.intInfo(zcu);1977 const info = ty.intInfo(zcu);
1856 assert(info.bits != 0);1978 const bits = ty.abiSize(zcu) * 8;
1857 const name = try o.allocTypeName(pt, ty);1979 return switch (info.signedness) {
1858 defer gpa.free(name);1980 .signed => try o.builder.debugSignedType(name, bits),
1859 const builder_name = try o.builder.metadataString(name);1981 .unsigned => try o.builder.debugUnsignedType(name, bits),
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),
1864 };1982 };
1865 try o.debug_type_map.put(gpa, ty.toIntern(), debug_int_type);
1866 return debug_int_type;
1867 },1983 },
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 },
1941 .pointer => {1985 .pointer => {
1942 // Normalize everything that the debug info does not represent.1986 const ptr_size = Type.ptrAbiSize(zcu.getTarget());
1943 const ptr_info = ty.ptrInfo(zcu);1987 const ptr_align = Type.ptrAbiAlignment(zcu.getTarget());
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);
19781988
1979 if (ty.isSlice(zcu)) {1989 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
1994 const debug_ptr_type = try o.builder.debugMemberType(1990 const debug_ptr_type = try o.builder.debugMemberType(
1995 try o.builder.metadataString("ptr"),1991 try o.builder.metadataString("ptr"),
1996 null, // File1992 null, // file
1997 debug_fwd_ref,1993 ty_fwd_ref,
1998 0, // Line1994 0, // line
1999 try o.lowerDebugType(pt, ptr_ty),1995 try o.getDebugType(pt, ty.slicePtrFieldType(zcu)),
2000 ptr_size * 8,1996 ptr_size * 8,
2001 (ptr_align.toByteUnits() orelse 0) * 8,1997 ptr_align.toByteUnits().? * 8,
2002 0, // Offset1998 0, // offset
2003 );1999 );
20042000
2005 const debug_len_type = try o.builder.debugMemberType(2001 const debug_len_type = try o.builder.debugMemberType(
2006 try o.builder.metadataString("len"),2002 try o.builder.metadataString("len"),
2007 null, // File2003 null, // file
2008 debug_fwd_ref,2004 ty_fwd_ref,
2009 0, // Line2005 0, // line
2010 try o.lowerDebugType(pt, len_ty),2006 try o.getDebugType(pt, .usize),
2011 len_size * 8,2007 ptr_size * 8,
2012 (len_align.toByteUnits() orelse 0) * 8,2008 ptr_align.toByteUnits().? * 8,
2013 len_offset * 8,2009 ptr_size * 8,
2014 );2010 );
20152011
2016 const debug_slice_type = try o.builder.debugStructType(2012 return o.builder.debugStructType(
2017 try o.builder.metadataString(name),2013 name,
2018 null, // File2014 null, // file
2019 o.debug_compile_unit.unwrap().?, // Scope2015 o.debug_compile_unit.unwrap().?, // scope
2020 line,2016 0, // line
2021 null, // Underlying type2017 null, // underlying type
2022 ty.abiSize(zcu) * 8,2018 ptr_size * 2 * 8,
2023 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2019 ptr_align.toByteUnits().? * 8,
2024 try o.builder.metadataTuple(&.{2020 try o.builder.metadataTuple(&.{
2025 debug_ptr_type,2021 debug_ptr_type,
2026 debug_len_type,2022 debug_len_type,
2027 }),2023 }),
2028 );2024 );
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;
2037 }2025 }
20382026
2039 const debug_elem_ty = try o.lowerDebugType(pt, Type.fromInterned(ptr_info.child));2027 return o.builder.debugPointerType(
20402028 name,
2041 const name = try o.allocTypeName(pt, ty);2029 null, // file
2042 defer gpa.free(name);2030 o.debug_compile_unit.unwrap().?, // scope
20432031 0, // line
2044 const debug_ptr_type = try o.builder.debugPointerType(2032 try o.getDebugType(pt, ty.childType(zcu)),
2045 try o.builder.metadataString(name),2033 ptr_size * 8,
2046 null, // File2034 ptr_align.toByteUnits().? * 8,
2047 null, // Scope2035 0, // offset
2048 0, // Line
2049 debug_elem_ty,
2050 target.ptrBitWidth(),
2051 (ty.ptrAlignment(zcu).toByteUnits() orelse 0) * 8,
2052 0, // Offset
2053 );2036 );
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;
2113 },2037 },
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 ),
2114 .vector => {2053 .vector => {
2115 const elem_ty = ty.elemType2(zcu);2054 const elem_ty = ty.childType(zcu);
2116 // Vector elements cannot be padded since that would make2055 // Vector elements cannot be padded since that would make
2117 // @bitSizOf(elem) * len > @bitSizOf(vec).2056 // @bitSizeOf(elem) * len > @bitSizOf(vec).
2118 // Neither gdb nor lldb seem to be able to display non-byte sized2057 // Neither gdb nor lldb seem to be able to display non-byte sized
2119 // vectors properly.2058 // vectors properly.
2120 const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) {2059 const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) {
2121 .int => blk: {2060 .int => blk: {
2122 const info = elem_ty.intInfo(zcu);2061 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);
2127 break :blk switch (info.signedness) {2062 break :blk switch (info.signedness) {
2128 .signed => try o.builder.debugSignedType(builder_name, info.bits),2063 .signed => try o.builder.debugSignedType(name, info.bits),
2129 .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits),2064 .unsigned => try o.builder.debugUnsignedType(name, info.bits),
2130 };2065 };
2131 },2066 },
2132 .bool => try o.builder.debugBoolType(2067 .bool => try o.builder.debugBoolType(try o.builder.metadataString("bool"), 1),
2133 try o.builder.metadataString("bool"),2068 // We don't pad pointers or floats, so we can lower those normally.
2134 1,2069 .pointer, .optional, .float => try o.getDebugType(pt, elem_ty),
2135 ),2070 else => unreachable,
2136 else => try o.lowerDebugType(pt, ty.childType(zcu)),
2137 };2071 };
21382072
2139 const debug_vector_type = try o.builder.debugVectorType(2073 return o.builder.debugVectorType(
2140 null, // Name2074 name,
2141 null, // File2075 null, // file
2142 null, // Scope2076 o.debug_compile_unit.unwrap().?, // scope
2143 0, // Line2077 0, // line
2144 debug_elem_type,2078 debug_elem_type,
2145 ty.abiSize(zcu) * 8,2079 ty.abiSize(zcu) * 8,
2146 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2080 ty.abiAlignment(zcu).toByteUnits().? * 8,
2147 try o.builder.metadataTuple(&.{2081 try o.builder.metadataTuple(&.{
2148 try o.builder.debugSubrange(2082 try o.builder.debugSubrange(
2149 try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)),2083 try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)),
...@@ -2151,566 +2085,574 @@ pub const Object = struct {...@@ -2151,566 +2085,574 @@ pub const Object = struct {
2151 ),2085 ),
2152 }),2086 }),
2153 );2087 );
2154
2155 try o.debug_type_map.put(gpa, ty.toIntern(), debug_vector_type);
2156 return debug_vector_type;
2157 },2088 },
2158 .optional => {2089 .optional => {
2159 const name = try o.allocTypeName(pt, ty);2090 const payload_ty = ty.optionalChild(zcu);
2160 defer gpa.free(name);2091 if (ty.optionalReprIsPayload(zcu)) {
2161 const child_ty = ty.optionalChild(zcu);2092 return o.builder.debugTypedefType(
2162 if (!child_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2093 name,
2163 const debug_bool_type = try o.builder.debugBoolType(2094 null, // file
2164 try o.builder.metadataString(name),2095 o.debug_compile_unit.unwrap().?, // scope
2165 8,2096 0, // line
2097 try o.getDebugType(pt, payload_ty),
2098 ty.abiSize(zcu) * 8,
2099 ty.abiAlignment(zcu).toByteUnits().? * 8,
2100 0, // offset
2166 );2101 );
2167 try o.debug_type_map.put(gpa, ty.toIntern(), debug_bool_type);
2168 return debug_bool_type;
2169 }2102 }
21702103
2171 const debug_fwd_ref = try o.builder.debugForwardReference();2104 const payload_size = payload_ty.abiSize(zcu);
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 }
21872105
2188 const non_null_ty = Type.u8;2106 const non_null_ty = Type.u8;
2189 const payload_size = child_ty.abiSize(zcu);
2190 const payload_align = child_ty.abiAlignment(zcu);
2191 const non_null_size = non_null_ty.abiSize(zcu);2107 const non_null_size = non_null_ty.abiSize(zcu);
2192 const non_null_align = non_null_ty.abiAlignment(zcu);2108 const non_null_align = non_null_ty.abiAlignment(zcu);
2193 const non_null_offset = non_null_align.forward(payload_size);2109 const non_null_offset = non_null_align.forward(payload_size);
21942110
2195 const debug_data_type = try o.builder.debugMemberType(2111 const debug_payload_type = try o.builder.debugMemberType(
2196 try o.builder.metadataString("data"),2112 try o.builder.metadataString("payload"),
2197 null, // File2113 null, // file
2198 debug_fwd_ref,2114 ty_fwd_ref, // scope
2199 0, // Line2115 0, // line
2200 try o.lowerDebugType(pt, child_ty),2116 try o.getDebugType(pt, payload_ty),
2201 payload_size * 8,2117 payload_size * 8,
2202 (payload_align.toByteUnits() orelse 0) * 8,2118 payload_ty.abiAlignment(zcu).toByteUnits().? * 8,
2203 0, // Offset2119 0, // offset
2204 );2120 );
22052121
2206 const debug_some_type = try o.builder.debugMemberType(2122 const debug_some_type = try o.builder.debugMemberType(
2207 try o.builder.metadataString("some"),2123 try o.builder.metadataString("some"),
2208 null,2124 null,
2209 debug_fwd_ref,2125 ty_fwd_ref,
2210 0,2126 0,
2211 try o.lowerDebugType(pt, non_null_ty),2127 try o.getDebugType(pt, non_null_ty),
2212 non_null_size * 8,2128 non_null_size * 8,
2213 (non_null_align.toByteUnits() orelse 0) * 8,2129 non_null_align.toByteUnits().? * 8,
2214 non_null_offset * 8,2130 non_null_offset * 8,
2215 );2131 );
22162132
2217 const debug_optional_type = try o.builder.debugStructType(2133 return o.builder.debugStructType(
2218 try o.builder.metadataString(name),2134 name,
2219 null, // File2135 null, // file
2220 o.debug_compile_unit.unwrap().?, // Scope2136 o.debug_compile_unit.unwrap().?, // scope
2221 0, // Line2137 0, // line
2222 null, // Underlying type2138 null, // underlying type
2223 ty.abiSize(zcu) * 8,2139 ty.abiSize(zcu) * 8,
2224 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2140 ty.abiAlignment(zcu).toByteUnits().? * 8,
2225 try o.builder.metadataTuple(&.{2141 try o.builder.metadataTuple(&.{
2226 debug_data_type,2142 debug_payload_type,
2227 debug_some_type,2143 debug_some_type,
2228 }),2144 }),
2229 );2145 );
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;
2238 },2146 },
2239 .error_union => {2147 .error_union => {
2148 const error_ty = ty.errorUnionSet(zcu);
2240 const payload_ty = ty.errorUnionPayload(zcu);2149 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);2151 const error_size = error_ty.abiSize(zcu);
2252 const error_align = Type.anyerror.abiAlignment(zcu);2152 const error_align = error_ty.abiAlignment(zcu);
2253 const payload_size = payload_ty.abiSize(zcu);2153 const payload_size = payload_ty.abiSize(zcu);
2254 const payload_align = payload_ty.abiAlignment(zcu);2154 const payload_align = payload_ty.abiAlignment(zcu);
22552155
2256 var error_index: u32 = undefined;2156 const error_offset: u64, const payload_offset: u64 = offsets: {
2257 var payload_index: u32 = undefined;2157 if (error_align.compare(.gt, payload_align)) {
2258 var error_offset: u64 = undefined;2158 break :offsets .{ 0, payload_align.forward(error_size) };
2259 var payload_offset: u64 = undefined;2159 } else {
2260 if (error_align.compare(.gt, payload_align)) {2160 break :offsets .{ error_align.forward(payload_size), 0 };
2261 error_index = 0;2161 }
2262 payload_index = 1;2162 };
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();
22732163
2274 var fields: [2]Builder.Metadata = undefined;2164 const error_field = try o.builder.debugMemberType(
2275 fields[error_index] = try o.builder.debugMemberType(2165 try o.builder.metadataString("error"),
2276 try o.builder.metadataString("tag"),2166 null, // file
2277 null, // File2167 ty_fwd_ref,
2278 debug_fwd_ref,2168 0, // line
2279 0, // Line2169 try o.getDebugType(pt, error_ty),
2280 try o.lowerDebugType(pt, Type.anyerror),
2281 error_size * 8,2170 error_size * 8,
2282 (error_align.toByteUnits() orelse 0) * 8,2171 error_align.toByteUnits().? * 8,
2283 error_offset * 8,2172 error_offset * 8,
2284 );2173 );
2285 fields[payload_index] = try o.builder.debugMemberType(2174 const payload_field = try o.builder.debugMemberType(
2286 try o.builder.metadataString("value"),2175 try o.builder.metadataString("payload"),
2287 null, // File2176 null, // file
2288 debug_fwd_ref,2177 ty_fwd_ref, // scope
2289 0, // Line2178 0, // line
2290 try o.lowerDebugType(pt, payload_ty),2179 try o.getDebugType(pt, payload_ty),
2291 payload_size * 8,2180 payload_size * 8,
2292 (payload_align.toByteUnits() orelse 0) * 8,2181 payload_align.toByteUnits().? * 8,
2293 payload_offset * 8,2182 payload_offset * 8,
2294 );2183 );
22952184
2296 const debug_error_union_type = try o.builder.debugStructType(2185 return try o.builder.debugStructType(
2297 try o.builder.metadataString(name),2186 name,
2298 null, // File2187 null, // File
2299 o.debug_compile_unit.unwrap().?, // Sope2188 o.debug_compile_unit.unwrap().?, // Scope
2300 0, // Line2189 0, // Line
2301 null, // Underlying type2190 null, // Underlying type
2302 ty.abiSize(zcu) * 8,2191 ty.abiSize(zcu) * 8,
2303 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2192 ty.abiAlignment(zcu).toByteUnits().? * 8,
2304 try o.builder.metadataTuple(&fields),2193 try o.builder.metadataTuple(&.{ error_field, payload_field }),
2305 );2194 );
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;
2311 },2195 },
2312 .error_set => {2196 .error_set => {
2313 const debug_error_set = try o.builder.debugUnsignedType(2197 assert(ty.toIntern() != .anyerror_type); // handled specially in `updateConst`; will be populated by `emit` instead
2314 try o.builder.metadataString("anyerror"),2198 // Error sets are just named wrappers around `anyerror`.
2315 16,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
2316 );2208 );
2317 try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_set);
2318 return debug_error_set;
2319 },2209 },
2320 .@"struct" => {2210 .@"fn" => {
2321 const name = try o.allocTypeName(pt, ty);2211 if (!ty.fnHasRuntimeBits(zcu)) {
2322 defer gpa.free(name);2212 return o.builder.debugSignedType(name, 0);
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 }
2336 }2213 }
23372214
2338 switch (ip.indexToKey(ty.toIntern())) {2215 const fn_info = zcu.typeToFunc(ty).?;
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);
23442216
2345 comptime assert(struct_layout_version == 2);2217 var debug_param_types: std.ArrayList(Builder.Metadata) = try .initCapacity(gpa, 3 + fn_info.param_types.len);
2346 var offset: u64 = 0;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| {2225 if (sret) {
2351 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;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);2230 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {
2354 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);2231 // Stack trace pointer.
2355 const field_offset = field_align.forward(offset);2232 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, .ptr_usize));
2356 offset = field_offset + field_size;2233 }
23572234
2358 var name_buf: [32]u8 = undefined;2235 for (fn_info.param_types.get(ip)) |param_ty_ip| {
2359 const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{i}) catch unreachable;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(2246 return o.builder.debugSubroutineType(
2362 try o.builder.metadataString(field_name),2247 try o.builder.metadataTuple(debug_param_types.items),
2363 null, // File2248 );
2364 debug_fwd_ref,2249 },
2365 0,2250 .@"struct" => {
2366 try o.lowerDebugType(pt, Type.fromInterned(field_ty)),2251 if (ty.isTuple(zcu)) {
2367 field_size * 8,2252 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;
2368 (field_align.toByteUnits() orelse 0) * 8,2253 var fields: std.ArrayList(Builder.Metadata) = .empty;
2369 field_offset * 8,2254 defer fields.deinit(gpa);
2370 ));
2371 }
23722255
2373 const debug_struct_type = try o.builder.debugStructType(2256 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
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 );
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);2261 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val, i| {
2387 return debug_struct_type;2262 const field_ty: Type = .fromInterned(field_ty_ip);
2388 },2263 if (field_val != .none or !field_ty.hasRuntimeBits(zcu)) continue;
2389 .struct_type => {2264
2390 if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) {2265 const field_size = field_ty.abiSize(zcu);
2391 // This can happen if a struct type makes it all the way to2266 const field_align = field_ty.abiAlignment(zcu);
2392 // flush() without ever being instantiated or referenced (even2267 const field_offset = field_align.forward(offset);
2393 // via pointer). The only reason we are hearing about it now is2268 offset = field_offset + field_size;
2394 // that it is being used as a namespace to put other debug types2269
2395 // into. Therefore we can satisfy this by making an empty namespace,2270 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2396 // rather than changing the frontend to unnecessarily resolve the2271 try o.builder.metadataStringFmt("{d}", .{i}),
2397 // struct field types.2272 null, // file
2398 const debug_struct_type = try o.makeEmptyNamespaceDebugType(pt, ty);2273 ty_fwd_ref,
2399 try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type);2274 0, // line
2400 return debug_struct_type;2275 try o.getDebugType(pt, field_ty),
2401 }2276 field_size * 8,
2402 },2277 field_align.toByteUnits().? * 8,
2403 else => {},2278 field_offset * 8,
2404 }2279 ));
2280 }
24052281
2406 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {2282 return o.builder.debugStructType(
2407 const debug_struct_type = try o.makeEmptyNamespaceDebugType(pt, ty);2283 name,
2408 try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type);2284 null, // file
2409 return debug_struct_type;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 );
2410 }2292 }
24112293
2412 const struct_type = zcu.typeToStruct(ty).?;2294 const struct_type = zcu.typeToStruct(ty).?;
24132295
2414 var fields: std.ArrayList(Builder.Metadata) = .empty;2296 const file = try o.getDebugFile(pt, struct_type.zir_index.resolveFile(ip));
2415 defer fields.deinit(gpa);2297 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
24162298 try o.namespaceToDebugScope(pt, parent_namespace)
2417 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);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 itself2304 var fields: std.ArrayList(Builder.Metadata) = .empty;
2422 try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref);2305 defer fields.deinit(gpa);
24232306
2424 comptime assert(struct_layout_version == 2);2307 switch (struct_type.layout) {
2425 var it = struct_type.iterateRuntimeOrder(ip);2308 .@"packed" => {
2426 while (it.next()) |field_index| {2309 try fields.ensureTotalCapacityPrecise(gpa, 1);
2427 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);2310 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2428 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;2311 try o.builder.metadataString("bits"),
2429 const field_size = field_ty.abiSize(zcu);2312 null, // file
2430 const field_align = ty.fieldAlignment(field_index, zcu);2313 ty_fwd_ref,
2431 const field_offset = ty.structFieldOffset(field_index, zcu);2314 0, // line
2432 const field_name = struct_type.fieldName(ip, field_index);2315 try o.getDebugType(pt, .fromInterned(struct_type.packed_backing_int_type)),
2433 fields.appendAssumeCapacity(try o.builder.debugMemberType(2316 ty.abiSize(zcu) * 8,
2434 try o.builder.metadataString(field_name.toSlice(ip)),2317 ty.abiAlignment(zcu).toByteUnits().? * 8,
2435 null, // File2318 0, // offset
2436 debug_fwd_ref,2319 ));
2437 0, // Line2320 },
2438 try o.lowerDebugType(pt, field_ty),2321 .auto, .@"extern" => {
2439 field_size * 8,2322 comptime assert(struct_layout_version == 2);
2440 (field_align.toByteUnits() orelse 0) * 8,2323 try fields.ensureTotalCapacityPrecise(gpa, struct_type.field_types.len);
2441 field_offset * 8,2324 var it = struct_type.iterateRuntimeOrder(ip);
2442 ));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 },
2443 }2347 }
24442348
2445 const debug_struct_type = try o.builder.debugStructType(2349 return o.builder.debugStructType(
2446 try o.builder.metadataString(name),2350 name,
2447 null, // File2351 file,
2448 o.debug_compile_unit.unwrap().?, // Scope2352 scope,
2449 0, // Line2353 line,
2450 null, // Underlying type2354 null, // underlying type
2451 ty.abiSize(zcu) * 8,2355 ty.abiSize(zcu) * 8,
2452 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2356 ty.abiAlignment(zcu).toByteUnits().? * 8,
2453 try o.builder.metadataTuple(fields.items),2357 try o.builder.metadataTuple(fields.items),
2454 );2358 );
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;
2463 },2359 },
2464 .@"union" => {2360 .@"union" => {
2465 const name = try o.allocTypeName(pt, ty);
2466 defer gpa.free(name);
2467
2468 const union_type = ip.loadUnionType(ty.toIntern());2361 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 itself2371 const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_type);
2483 try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref);
24842372
2485 if (layout.payload_size == 0) {2373 if (union_type.layout == .@"packed") {
2486 const debug_union_type = try o.builder.debugStructType(2374 const bitpack_field = try o.builder.debugMemberType(
2487 try o.builder.metadataString(name),2375 try o.builder.metadataString("bits"),
2488 null, // File2376 null, // file
2489 o.debug_compile_unit.unwrap().?, // Scope2377 ty_fwd_ref,
2490 0, // Line2378 0, // line
2491 null, // Underlying type2379 try o.getDebugType(pt, .fromInterned(union_type.packed_backing_int_type)),
2492 ty.abiSize(zcu) * 8,2380 ty.abiSize(zcu) * 8,
2493 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2381 ty.abiAlignment(zcu).toByteUnits().? * 8,
2494 try o.builder.metadataTuple(2382 0, // offset
2495 &.{try o.lowerDebugType(pt, Type.fromInterned(union_type.enum_tag_ty))},
2496 ),
2497 );2383 );
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 fully2396 const layout = Type.getUnionLayout(union_type, zcu);
2500 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2501 map_ptr.* = debug_union_type;
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 );
2504 }2424 }
25052425
2506 var fields: std.ArrayList(Builder.Metadata) = .empty;2426 var fields: std.ArrayList(Builder.Metadata) = try .initCapacity(gpa, union_type.field_types.len);
2507 defer fields.deinit(gpa);2427 defer fields.deinit(gpa);
25082428
2509 try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);2429 const payload_fwd_ref = if (layout.tag_size == 0)
25102430 ty_fwd_ref
2511 const debug_union_fwd_ref = if (layout.tag_size == 0)
2512 debug_fwd_ref
2513 else2431 else
2514 try o.builder.debugForwardReference();2432 try o.builder.debugForwardReference();
25152433
2516 const tag_type = union_type.loadTagType(ip);2434 for (0..union_type.field_types.len) |field_index| {
2517
2518 for (0..tag_type.names.len) |field_index| {
2519 const field_ty = union_type.field_types.get(ip)[field_index];2435 const field_ty = union_type.field_types.get(ip)[field_index];
2520 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;
25212436
2522 const field_size = Type.fromInterned(field_ty).abiSize(zcu);2437 const field_size = Type.fromInterned(field_ty).abiSize(zcu);
2523 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {2438 const field_align: InternPool.Alignment = ty.explicitFieldAlignment(field_index, zcu);
2524 .@"packed" => .none,
2525 .auto, .@"extern" => ty.fieldAlignment(field_index, zcu),
2526 };
25272439
2528 const field_name = tag_type.names.get(ip)[field_index];2440 const field_name = enum_tag_ty.enumFieldName(field_index, zcu);
2529 fields.appendAssumeCapacity(try o.builder.debugMemberType(2441 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2530 try o.builder.metadataString(field_name.toSlice(ip)),2442 try o.builder.metadataString(field_name.toSlice(ip)),
2531 null, // File2443 null, // file
2532 debug_union_fwd_ref,2444 payload_fwd_ref,
2533 0, // Line2445 0, // line
2534 try o.lowerDebugType(pt, Type.fromInterned(field_ty)),2446 try o.getDebugType(pt, .fromInterned(field_ty)),
2535 field_size * 8,2447 field_size * 8,
2536 (field_align.toByteUnits() orelse 0) * 8,2448 (field_align.toByteUnits() orelse 0) * 8,
2537 0, // Offset2449 0, // offset
2538 ));2450 ));
2539 }2451 }
25402452
2541 var union_name_buf: ?[:0]const u8 = null;2453 const debug_payload_type = try o.builder.debugUnionType(
2542 defer if (union_name_buf) |buf| gpa.free(buf);2454 payload_name: {
2543 const union_name = if (layout.tag_size == 0) name else name: {2455 if (layout.tag_size == 0) break :payload_name name;
2544 union_name_buf = try std.fmt.allocPrintSentinel(gpa, "{s}:Payload", .{name}, 0);2456 break :payload_name try o.builder.metadataStringFmt("{f}:Payload", .{ty.fmt(pt)});
2545 break :name union_name_buf.?;2457 },
2546 };2458 file,
25472459 scope,
2548 const debug_union_type = try o.builder.debugUnionType(2460 line,
2549 try o.builder.metadataString(union_name),2461 null, // underlying type
2550 null, // File
2551 o.debug_compile_unit.unwrap().?, // Scope
2552 0, // Line
2553 null, // Underlying type
2554 layout.payload_size * 8,2462 layout.payload_size * 8,
2555 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2463 ty.abiAlignment(zcu).toByteUnits().? * 8,
2556 try o.builder.metadataTuple(fields.items),2464 try o.builder.metadataTuple(fields.items),
2557 );2465 );
25582466
2559 o.builder.resolveDebugForwardReference(debug_union_fwd_ref, debug_union_type);
2560
2561 if (layout.tag_size == 0) {2467 if (layout.tag_size == 0) {
2562 // Set to real type now that it has been lowered fully2468 return debug_payload_type;
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;
2567 }2469 }
25682470
2569 var tag_offset: u64 = undefined;2471 o.builder.resolveDebugForwardReference(payload_fwd_ref, debug_payload_type);
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 }
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(
2580 try o.builder.metadataString("tag"),2482 try o.builder.metadataString("tag"),
2581 null, // File2483 null, // file
2582 debug_fwd_ref,2484 ty_fwd_ref,
2583 0, // Line2485 0, // line
2584 try o.lowerDebugType(pt, Type.fromInterned(union_type.enum_tag_ty)),2486 try o.getDebugType(pt, enum_tag_ty),
2585 layout.tag_size * 8,2487 layout.tag_size * 8,
2586 (layout.tag_align.toByteUnits() orelse 0) * 8,2488 layout.tag_align.toByteUnits().? * 8,
2587 tag_offset * 8,2489 tag_offset * 8,
2588 );2490 );
25892491
2590 const debug_payload_type = try o.builder.debugMemberType(2492 const payload_member_type = try o.builder.debugMemberType(
2591 try o.builder.metadataString("payload"),2493 try o.builder.metadataString("payload"),
2592 null, // File2494 null, // file
2593 debug_fwd_ref,2495 ty_fwd_ref,
2594 0, // Line2496 0, // line
2595 debug_union_type,2497 debug_payload_type,
2596 layout.payload_size * 8,2498 layout.payload_size * 8,
2597 (layout.payload_align.toByteUnits() orelse 0) * 8,2499 layout.payload_align.toByteUnits().? * 8,
2598 payload_offset * 8,2500 payload_offset * 8,
2599 );2501 );
26002502
2601 const full_fields: [2]Builder.Metadata =2503 const full_fields: [2]Builder.Metadata =
2602 if (layout.tag_align.compare(.gte, layout.payload_align))2504 if (layout.tag_align.compare(.gte, layout.payload_align))
2603 .{ debug_tag_type, debug_payload_type }2505 .{ tag_member_type, payload_member_type }
2604 else2506 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(2509 return o.builder.debugStructType(
2608 try o.builder.metadataString(name),2510 name,
2609 null, // File2511 file,
2610 o.debug_compile_unit.unwrap().?, // Scope2512 scope,
2611 0, // Line2513 line,
2612 null, // Underlying type2514 null, // underlying type
2613 ty.abiSize(zcu) * 8,2515 ty.abiSize(zcu) * 8,
2614 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2516 ty.abiAlignment(zcu).toByteUnits().? * 8,
2615 try o.builder.metadataTuple(&full_fields),2517 try o.builder.metadataTuple(&full_fields),
2616 );2518 );
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);2527 const line = ty.typeDeclSrcLine(zcu).? + 1;
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;
26232528
2624 return debug_tagged_union_type;2529 if (!ty.hasRuntimeBits(zcu)) {
2625 },2530 return o.builder.debugStructType(
2626 .@"fn" => {2531 name,
2627 const fn_info = zcu.typeToFunc(ty).?;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);2542 const enum_type = ip.loadEnumType(ty.toIntern());
2630 defer debug_param_types.deinit();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.2550 for (enumerators, enum_type.field_names.get(ip), 0..) |*out, field_name, field_index| {
2635 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(zcu)) {2551 var space: Value.BigIntSpace = undefined;
2636 const sret = firstParamSRet(fn_info, zcu, target);2552 const field_val: std.math.big.int.Const = switch (enum_type.field_values.len) {
2637 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);2553 0 => std.math.big.int.Mutable.init(&space.limbs, field_index).toConst(),
2638 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, ret_ty));2554 else => Value.fromInterned(enum_type.field_values.get(ip)[field_index]).toBigInt(&space, zcu),
26392555 };
2640 if (sret) {2556 out.* = try o.builder.debugEnumerator(
2641 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));2557 try o.builder.metadataString(field_name.toSlice(ip)),
2642 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, ptr_ty));2558 int_info.signedness == .unsigned,
2643 }2559 int_info.bits,
2644 } else {2560 field_val,
2645 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, Type.void));2561 );
2646 }2562 }
26472563
2648 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {2564 const debug_enum_type = try o.builder.debugEnumerationType(
2649 // Stack trace pointer.2565 name,
2650 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, .fromInterned(.ptr_usize_type)));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);
2651 }2580 }
26522581
2653 for (0..fn_info.param_types.len) |i| {2582 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2654 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]);2583 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2655 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;2584 try o.namespaceToDebugScope(pt, parent_namespace)
2585 else
2586 file;
26562587
2657 if (isByRef(param_ty, zcu)) {2588 const line = ty.typeDeclSrcLine(zcu).? + 1;
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 }
26642589
2665 const debug_function_type = try o.builder.debugSubroutineType(2590 return o.builder.debugStructType(
2666 try o.builder.metadataTuple(debug_param_types.items),2591 name,
2592 file,
2593 scope,
2594 line,
2595 null, // underlying type
2596 0, // size
2597 ty.abiAlignment(zcu).toByteUnits().? * 8,
2598 null, // fields
2667 );2599 );
2668
2669 try o.debug_type_map.put(gpa, ty.toIntern(), debug_function_type);
2670 return debug_function_type;
2671 },2600 },
2672 .comptime_int => unreachable,
2673 .comptime_float => unreachable,
2674 .type => unreachable,
2675 .undefined => unreachable,
2676 .null => unreachable,
2677 .enum_literal => unreachable,
2678
2679 .frame => @panic("TODO implement lowerDebugType for Frame types"),2601 .frame => @panic("TODO implement lowerDebugType for Frame types"),
2680 .@"anyframe" => @panic("TODO implement lowerDebugType for AnyFrame types"),2602 .@"anyframe" => @panic("TODO implement lowerDebugType for AnyFrame types"),
2681 }2603 }
2682 }2604 }
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 {
2685 const zcu = pt.zcu;2608 const zcu = pt.zcu;
2686 const namespace = zcu.namespacePtr(namespace_index);2609 const ip = &zcu.intern_pool;
2687 if (namespace.parent == .none) return try o.getDebugFile(pt, namespace.file_scope);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;
2694 }2649 }
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 {
2697 const zcu = pt.zcu;2652 const zcu = pt.zcu;
2698 const ip = &zcu.intern_pool;2653 const namespace = zcu.namespacePtr(namespace_index);
2699 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));2654 if (namespace.parent == .none) return try o.getDebugFile(pt, namespace.file_scope);
2700 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|2655 return o.getDebugType(pt, .fromInterned(namespace.owner_type));
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 );
2714 }2656 }
27152657
2716 fn allocTypeName(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error![:0]const u8 {2658 fn allocTypeName(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error![:0]const u8 {
...@@ -2804,7 +2746,7 @@ pub const Object = struct {...@@ -2804,7 +2746,7 @@ pub const Object = struct {
2804 function_index.setCallConv(cc_info.llvm_cc, &o.builder);2746 function_index.setCallConv(cc_info.llvm_cc, &o.builder);
28052747
2806 if (cc_info.align_stack) {2748 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);
2808 } else {2750 } else {
2809 _ = try attributes.removeFnAttr(.alignstack);2751 _ = try attributes.removeFnAttr(.alignstack);
2810 }2752 }
...@@ -2885,40 +2827,6 @@ pub const Object = struct {...@@ -2885,40 +2827,6 @@ pub const Object = struct {
28852827
2886 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);2828 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
2922 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);2830 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
2923 return function_index;2831 return function_index;
2924 }2832 }
...@@ -3223,7 +3131,7 @@ pub const Object = struct {...@@ -3223,7 +3131,7 @@ pub const Object = struct {
3223 ),3131 ),
3224 .opt_type => |child_ty| {3132 .opt_type => |child_ty| {
3225 // Must stay in sync with `opt_payload` logic in `lowerPtr`.3133 // 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
3228 const payload_ty = try o.lowerType(pt, Type.fromInterned(child_ty));3136 const payload_ty = try o.lowerType(pt, Type.fromInterned(child_ty));
3229 if (t.optionalReprIsPayload(zcu)) return payload_ty;3137 if (t.optionalReprIsPayload(zcu)) return payload_ty;
...@@ -3245,7 +3153,7 @@ pub const Object = struct {...@@ -3245,7 +3153,7 @@ pub const Object = struct {
3245 // Must stay in sync with `codegen.errUnionPayloadOffset`.3153 // Must stay in sync with `codegen.errUnionPayloadOffset`.
3246 // See logic in `lowerPtr`.3154 // See logic in `lowerPtr`.
3247 const error_type = try o.errorIntType(pt);3155 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))
3249 return error_type;3157 return error_type;
3250 const payload_type = try o.lowerType(pt, Type.fromInterned(error_union_type.payload_type));3158 const payload_type = try o.lowerType(pt, Type.fromInterned(error_union_type.payload_type));
32513159
...@@ -3287,7 +3195,7 @@ pub const Object = struct {...@@ -3287,7 +3195,7 @@ pub const Object = struct {
3287 const struct_type = ip.loadStructType(t.toIntern());3195 const struct_type = ip.loadStructType(t.toIntern());
32883196
3289 if (struct_type.layout == .@"packed") {3197 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));
3291 try o.type_map.put(o.gpa, t.toIntern(), int_ty);3199 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3292 return int_ty;3200 return int_ty;
3293 }3201 }
...@@ -3301,18 +3209,20 @@ pub const Object = struct {...@@ -3301,18 +3209,20 @@ pub const Object = struct {
33013209
3302 comptime assert(struct_layout_version == 2);3210 comptime assert(struct_layout_version == 2);
3303 var offset: u64 = 0;3211 var offset: u64 = 0;
3304 var big_align: InternPool.Alignment = .@"1";
3305 var struct_kind: Builder.Type.Structure.Kind = .normal;3212 var struct_kind: Builder.Type.Structure.Kind = .normal;
3306 // 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).3213 // 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).
3307 var it = struct_type.iterateRuntimeOrder(ip);3214 var it = struct_type.iterateRuntimeOrder(ip);
3215 var max_field_ty_align: InternPool.Alignment = .@"1";
3308 while (it.next()) |field_index| {3216 while (it.next()) |field_index| {
3309 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);3217 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3310 const field_align = t.fieldAlignment(field_index, zcu);
3311 const field_ty_align = field_ty.abiAlignment(zcu);3218 const field_ty_align = field_ty.abiAlignment(zcu);
3312 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";3219 max_field_ty_align = max_field_ty_align.maxStrict(field_ty_align);
3313 big_align = big_align.max(field_align);3220
3314 const prev_offset = offset;3221 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
3317 const padding_len = offset - prev_offset;3227 const padding_len = offset - prev_offset;
3318 if (padding_len > 0) try llvm_field_types.append(3228 if (padding_len > 0) try llvm_field_types.append(
...@@ -3320,11 +3230,11 @@ pub const Object = struct {...@@ -3320,11 +3230,11 @@ pub const Object = struct {
3320 try o.builder.arrayType(padding_len, .i8),3230 try o.builder.arrayType(padding_len, .i8),
3321 );3231 );
33223232
3323 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3233 if (!field_ty.hasRuntimeBits(zcu)) {
3324 // This is a zero-bit field. If there are runtime bits after this field,3234 // This is a zero-bit field. If there are runtime bits after this field,
3325 // map to the next LLVM field (which we know exists): otherwise, don't3235 // map to the next LLVM field (which we know exists): otherwise, don't
3326 // map the field, indicating it's at the end of the struct.3236 // 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) {
3328 try o.struct_field_map.put(o.gpa, .{3238 try o.struct_field_map.put(o.gpa, .{
3329 .struct_ty = t.toIntern(),3239 .struct_ty = t.toIntern(),
3330 .field_index = field_index,3240 .field_index = field_index,
...@@ -3343,12 +3253,15 @@ pub const Object = struct {...@@ -3343,12 +3253,15 @@ pub const Object = struct {
3343 }3253 }
3344 {3254 {
3345 const prev_offset = offset;3255 const prev_offset = offset;
3346 offset = big_align.forward(offset);3256 offset = struct_type.alignment.forward(offset);
3347 const padding_len = offset - prev_offset;3257 const padding_len = offset - prev_offset;
3348 if (padding_len > 0) try llvm_field_types.append(3258 if (padding_len > 0) try llvm_field_types.append(
3349 o.gpa,3259 o.gpa,
3350 try o.builder.arrayType(padding_len, .i8),3260 try o.builder.arrayType(padding_len, .i8),
3351 );3261 );
3262 if (@ctz(offset) < max_field_ty_align.toLog2Units()) {
3263 struct_kind = .@"packed"; // prevent unexpected trailing padding
3264 }
3352 }3265 }
33533266
3354 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));3267 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
...@@ -3391,7 +3304,7 @@ pub const Object = struct {...@@ -3391,7 +3304,7 @@ pub const Object = struct {
3391 o.gpa,3304 o.gpa,
3392 try o.builder.arrayType(padding_len, .i8),3305 try o.builder.arrayType(padding_len, .i8),
3393 );3306 );
3394 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) {3307 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {
3395 // This is a zero-bit field. If there are runtime bits after this field,3308 // This is a zero-bit field. If there are runtime bits after this field,
3396 // map to the next LLVM field (which we know exists): otherwise, don't3309 // map to the next LLVM field (which we know exists): otherwise, don't
3397 // map the field, indicating it's at the end of the struct.3310 // map the field, indicating it's at the end of the struct.
...@@ -3426,16 +3339,17 @@ pub const Object = struct {...@@ -3426,16 +3339,17 @@ pub const Object = struct {
3426 if (o.type_map.get(t.toIntern())) |value| return value;3339 if (o.type_map.get(t.toIntern())) |value| return value;
34273340
3428 const union_obj = ip.loadUnionType(t.toIntern());3341 const union_obj = ip.loadUnionType(t.toIntern());
3429 const layout = Type.getUnionLayout(union_obj, zcu);
34303342
3431 if (union_obj.flagsUnordered(ip).layout == .@"packed") {3343 if (union_obj.layout == .@"packed") {
3432 const int_ty = try o.builder.intType(@intCast(t.bitSize(zcu)));3344 const int_ty = try o.lowerType(pt, .fromInterned(union_obj.packed_backing_int_type));
3433 try o.type_map.put(o.gpa, t.toIntern(), int_ty);3345 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3434 return int_ty;3346 return int_ty;
3435 }3347 }
34363348
3349 const layout = Type.getUnionLayout(union_obj, zcu);
3350
3437 if (layout.payload_size == 0) {3351 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));
3439 try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty);3353 try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty);
3440 return enum_tag_ty;3354 return enum_tag_ty;
3441 }3355 }
...@@ -3467,7 +3381,7 @@ pub const Object = struct {...@@ -3467,7 +3381,7 @@ pub const Object = struct {
3467 );3381 );
3468 return ty;3382 return ty;
3469 }3383 }
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
3472 // Put the tag before or after the payload depending on which one's3386 // Put the tag before or after the payload depending on which one's
3473 // alignment is greater.3387 // alignment is greater.
...@@ -3502,7 +3416,7 @@ pub const Object = struct {...@@ -3502,7 +3416,7 @@ pub const Object = struct {
3502 }3416 }
3503 return gop.value_ptr.*;3417 return gop.value_ptr.*;
3504 },3418 },
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)),
3506 .func_type => |func_type| try o.lowerTypeFn(pt, func_type),3420 .func_type => |func_type| try o.lowerTypeFn(pt, func_type),
3507 .error_set_type, .inferred_error_set_type => try o.errorIntType(pt),3421 .error_set_type, .inferred_error_set_type => try o.errorIntType(pt),
3508 // values, not types3422 // values, not types
...@@ -3516,13 +3430,13 @@ pub const Object = struct {...@@ -3516,13 +3430,13 @@ pub const Object = struct {
3516 .error_union,3430 .error_union,
3517 .enum_literal,3431 .enum_literal,
3518 .enum_tag,3432 .enum_tag,
3519 .empty_enum_value,
3520 .float,3433 .float,
3521 .ptr,3434 .ptr,
3522 .slice,3435 .slice,
3523 .opt,3436 .opt,
3524 .aggregate,3437 .aggregate,
3525 .un,3438 .un,
3439 .bitpack,
3526 // memoization, not types3440 // memoization, not types
3527 .memoized_call,3441 .memoized_call,
3528 => unreachable,3442 => unreachable,
...@@ -3530,20 +3444,6 @@ pub const Object = struct {...@@ -3530,20 +3444,6 @@ pub const Object = struct {
3530 };3444 };
3531 }3445 }
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
3547 fn lowerTypeFn(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {3447 fn lowerTypeFn(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
3548 const zcu = pt.zcu;3448 const zcu = pt.zcu;
3549 const ip = &zcu.intern_pool;3449 const ip = &zcu.intern_pool;
...@@ -3558,9 +3458,9 @@ pub const Object = struct {...@@ -3558,9 +3458,9 @@ pub const Object = struct {
3558 }3458 }
35593459
3560 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {3460 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {
3561 const stack_trace_ty = zcu.builtin_decl_values.get(.StackTrace);3461 // First parameter is a pointer to `std.builtin.StackTrace`.
3562 const ptr_ty = try pt.ptrType(.{ .child = stack_trace_ty });3462 const llvm_ptr_ty = try o.builder.ptrType(toLlvmAddressSpace(.generic, target));
3563 try llvm_params.append(o.gpa, try o.lowerType(pt, ptr_ty));3463 try llvm_params.append(o.gpa, llvm_ptr_ty);
3564 }3464 }
35653465
3566 var it = iterateParamTypes(o, pt, fn_info);3466 var it = iterateParamTypes(o, pt, fn_info);
...@@ -3610,84 +3510,6 @@ pub const Object = struct {...@@ -3610,84 +3510,6 @@ pub const Object = struct {
3610 );3510 );
3611 }3511 }
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
3691 fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {3513 fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {
3692 const zcu = pt.zcu;3514 const zcu = pt.zcu;
3693 const ip = &zcu.intern_pool;3515 const ip = &zcu.intern_pool;
...@@ -3700,7 +3522,9 @@ pub const Object = struct {...@@ -3700,7 +3522,9 @@ pub const Object = struct {
3700 return o.builder.undefConst(try o.lowerType(pt, Type.fromInterned(val_key.typeOf())));3522 return o.builder.undefConst(try o.lowerType(pt, Type.fromInterned(val_key.typeOf())));
3701 }3523 }
37023524
3703 const ty = Type.fromInterned(val_key.typeOf());3525 const ty: Type = .fromInterned(val_key.typeOf());
3526 ty.assertHasLayout(zcu);
3527
3704 return switch (val_key) {3528 return switch (val_key) {
3705 .int_type,3529 .int_type,
3706 .ptr_type,3530 .ptr_type,
...@@ -3722,10 +3546,8 @@ pub const Object = struct {...@@ -3722,10 +3546,8 @@ pub const Object = struct {
37223546
3723 .undef => unreachable, // handled above3547 .undef => unreachable, // handled above
3724 .simple_value => |simple_value| switch (simple_value) {3548 .simple_value => |simple_value| switch (simple_value) {
3725 .undefined => unreachable, // non-runtime value
3726 .void => unreachable, // non-runtime value3549 .void => unreachable, // non-runtime value
3727 .null => unreachable, // non-runtime value3550 .null => unreachable, // non-runtime value
3728 .empty_tuple => unreachable, // non-runtime value
3729 .@"unreachable" => unreachable, // non-runtime value3551 .@"unreachable" => unreachable, // non-runtime value
37303552
3731 .false => .false,3553 .false => .false,
...@@ -3733,7 +3555,6 @@ pub const Object = struct {...@@ -3733,7 +3555,6 @@ pub const Object = struct {
3733 },3555 },
3734 .variable,3556 .variable,
3735 .enum_literal,3557 .enum_literal,
3736 .empty_enum_value,
3737 => unreachable, // non-runtime values3558 => unreachable, // non-runtime values
3738 .@"extern" => |@"extern"| {3559 .@"extern" => |@"extern"| {
3739 const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav);3560 const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav);
...@@ -3763,7 +3584,7 @@ pub const Object = struct {...@@ -3763,7 +3584,7 @@ pub const Object = struct {
3763 };3584 };
3764 const err_int_ty = try pt.errorIntType();3585 const err_int_ty = try pt.errorIntType();
3765 const payload_type = ty.errorUnionPayload(zcu);3586 const payload_type = ty.errorUnionPayload(zcu);
3766 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {3587 if (!payload_type.hasRuntimeBits(zcu)) {
3767 // We use the error type directly as the type.3588 // We use the error type directly as the type.
3768 return o.lowerValue(pt, err_val);3589 return o.lowerValue(pt, err_val);
3769 }3590 }
...@@ -3825,7 +3646,7 @@ pub const Object = struct {...@@ -3825,7 +3646,7 @@ pub const Object = struct {
3825 const payload_ty = ty.optionalChild(zcu);3646 const payload_ty = ty.optionalChild(zcu);
38263647
3827 const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none));3648 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)) {
3829 return non_null_bit;3650 return non_null_bit;
3830 }3651 }
3831 const llvm_ty = try o.lowerType(pt, ty);3652 const llvm_ty = try o.lowerType(pt, ty);
...@@ -3861,6 +3682,7 @@ pub const Object = struct {...@@ -3861,6 +3682,7 @@ pub const Object = struct {
3861 fields[0..llvm_ty_fields.len],3682 fields[0..llvm_ty_fields.len],
3862 ), vals[0..llvm_ty_fields.len]);3683 ), vals[0..llvm_ty_fields.len]);
3863 },3684 },
3685 .bitpack => |bitpack| return o.lowerValue(pt, bitpack.backing_int_val),
3864 .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {3686 .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {
3865 .array_type => |array_type| switch (aggregate.storage) {3687 .array_type => |array_type| switch (aggregate.storage) {
3866 .bytes => |bytes| try o.builder.stringConst(try o.builder.string(3688 .bytes => |bytes| try o.builder.stringConst(try o.builder.string(
...@@ -3992,7 +3814,7 @@ pub const Object = struct {...@@ -3992,7 +3814,7 @@ pub const Object = struct {
3992 0..,3814 0..,
3993 ) |field_ty, field_val, field_index| {3815 ) |field_ty, field_val, field_index| {
3994 if (field_val != .none) continue;3816 if (field_val != .none) continue;
3995 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;3817 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
39963818
3997 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);3819 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);
3998 big_align = big_align.max(field_align);3820 big_align = big_align.max(field_align);
...@@ -4038,16 +3860,8 @@ pub const Object = struct {...@@ -4038,16 +3860,8 @@ pub const Object = struct {
4038 },3860 },
4039 .struct_type => {3861 .struct_type => {
4040 const struct_type = ip.loadStructType(ty.toIntern());3862 const struct_type = ip.loadStructType(ty.toIntern());
4041 assert(struct_type.haveLayout(ip));
4042 const struct_ty = try o.lowerType(pt, ty);3863 const struct_ty = try o.lowerType(pt, ty);
4043 if (struct_type.layout == .@"packed") {3864 assert(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 }
4051 const llvm_len = struct_ty.aggregateLen(&o.builder);3865 const llvm_len = struct_ty.aggregateLen(&o.builder);
40523866
4053 const ExpectedContents = extern struct {3867 const ExpectedContents = extern struct {
...@@ -4067,15 +3881,12 @@ pub const Object = struct {...@@ -4067,15 +3881,12 @@ pub const Object = struct {
4067 comptime assert(struct_layout_version == 2);3881 comptime assert(struct_layout_version == 2);
4068 var llvm_index: usize = 0;3882 var llvm_index: usize = 0;
4069 var offset: u64 = 0;3883 var offset: u64 = 0;
4070 var big_align: InternPool.Alignment = .@"1";
4071 var need_unnamed = false;3884 var need_unnamed = false;
4072 var field_it = struct_type.iterateRuntimeOrder(ip);3885 var field_it = struct_type.iterateRuntimeOrder(ip);
4073 while (field_it.next()) |field_index| {3886 while (field_it.next()) |field_index| {
4074 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);3887 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);
4077 const prev_offset = offset;3888 const prev_offset = offset;
4078 offset = field_align.forward(offset);3889 offset = struct_type.field_offsets.get(ip)[field_index];
40793890
4080 const padding_len = offset - prev_offset;3891 const padding_len = offset - prev_offset;
4081 if (padding_len > 0) {3892 if (padding_len > 0) {
...@@ -4088,7 +3899,7 @@ pub const Object = struct {...@@ -4088,7 +3899,7 @@ pub const Object = struct {
4088 llvm_index += 1;3899 llvm_index += 1;
4089 }3900 }
40903901
4091 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3902 if (!field_ty.hasRuntimeBits(zcu)) {
4092 // This is a zero-bit field - we only needed it for the alignment.3903 // This is a zero-bit field - we only needed it for the alignment.
4093 continue;3904 continue;
4094 }3905 }
...@@ -4106,7 +3917,7 @@ pub const Object = struct {...@@ -4106,7 +3917,7 @@ pub const Object = struct {
4106 }3917 }
4107 {3918 {
4108 const prev_offset = offset;3919 const prev_offset = offset;
4109 offset = big_align.forward(offset);3920 offset = struct_type.alignment.forward(offset);
4110 const padding_len = offset - prev_offset;3921 const padding_len = offset - prev_offset;
4111 if (padding_len > 0) {3922 if (padding_len > 0) {
4112 fields[llvm_index] = try o.builder.arrayType(padding_len, .i8);3923 fields[llvm_index] = try o.builder.arrayType(padding_len, .i8);
...@@ -4130,19 +3941,13 @@ pub const Object = struct {...@@ -4130,19 +3941,13 @@ pub const Object = struct {
4130 if (layout.payload_size == 0) return o.lowerValue(pt, un.tag);3941 if (layout.payload_size == 0) return o.lowerValue(pt, un.tag);
41313942
4132 const union_obj = zcu.typeToUnion(ty).?;3943 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
4135 var need_unnamed = false;3947 var need_unnamed = false;
4136 const payload = if (un.tag != .none) p: {3948 const payload = if (un.tag != .none) p: {
4137 const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;3949 const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
4138 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);3950 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
4147 // Sometimes we must make an unnamed struct because LLVM does3952 // Sometimes we must make an unnamed struct because LLVM does
4148 // not support bitcasting our payload struct to the true union payload type.3953 // not support bitcasting our payload struct to the true union payload type.
...@@ -4150,14 +3955,14 @@ pub const Object = struct {...@@ -4150,14 +3955,14 @@ pub const Object = struct {
4150 // must pointer cast to the expected type before accessing the union.3955 // must pointer cast to the expected type before accessing the union.
4151 need_unnamed = layout.most_aligned_field != field_index;3956 need_unnamed = layout.most_aligned_field != field_index;
41523957
4153 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3958 if (!field_ty.hasRuntimeBits(zcu)) {
4154 const padding_len = layout.payload_size;3959 const padding_len = layout.payload_size;
4155 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));3960 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));
4156 }3961 }
4157 const payload = try o.lowerValue(pt, un.val);3962 const payload = try o.lowerValue(pt, un.val);
4158 const payload_ty = payload.typeOf(&o.builder);3963 const payload_ty = payload.typeOf(&o.builder);
4159 if (payload_ty != union_ty.structFields(&o.builder)[3964 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))
4161 ]) need_unnamed = true;3966 ]) need_unnamed = true;
4162 const field_size = field_ty.abiSize(zcu);3967 const field_size = field_ty.abiSize(zcu);
4163 if (field_size == layout.payload_size) break :p payload;3968 if (field_size == layout.payload_size) break :p payload;
...@@ -4169,13 +3974,6 @@ pub const Object = struct {...@@ -4169,13 +3974,6 @@ pub const Object = struct {
4169 );3974 );
4170 } else p: {3975 } else p: {
4171 assert(layout.tag_size == 0);3976 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
4179 const union_val = try o.lowerValue(pt, un.val);3977 const union_val = try o.lowerValue(pt, un.val);
4180 need_unnamed = true;3978 need_unnamed = true;
4181 break :p union_val;3979 break :p union_val;
...@@ -4277,7 +4075,14 @@ pub const Object = struct {...@@ -4277,7 +4075,14 @@ pub const Object = struct {
4277 };4075 };
4278 return o.lowerPtr(pt, field.base, offset + field_off);4076 return o.lowerPtr(pt, field.base, offset + field_off);
4279 },4077 },
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,
4281 };4086 };
4282 }4087 }
42834088
...@@ -4302,12 +4107,11 @@ pub const Object = struct {...@@ -4302,12 +4107,11 @@ pub const Object = struct {
43024107
4303 const ptr_ty = Type.fromInterned(uav.orig_ty);4108 const ptr_ty = Type.fromInterned(uav.orig_ty);
43044109
4305 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";4110 if (!uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
4306 if ((!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) or4111 return o.lowerPtrToVoid(pt, ptr_ty);
4307 (is_fn_body and zcu.typeToFunc(uav_ty).?.is_generic)) return o.lowerPtrToVoid(pt, ptr_ty);4112 }
43084113
4309 if (is_fn_body)4114 assert(uav_ty.zigTypeTag(zcu) != .@"fn"); // should be using a Nav ref
4310 @panic("TODO");
43114115
4312 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(zcu), target);4116 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(zcu), target);
4313 const alignment = ptr_ty.ptrAlignment(zcu);4117 const alignment = ptr_ty.ptrAlignment(zcu);
...@@ -4330,14 +4134,11 @@ pub const Object = struct {...@@ -4330,14 +4134,11 @@ pub const Object = struct {
4330 const nav_ty = Type.fromInterned(nav.typeOf(ip));4134 const nav_ty = Type.fromInterned(nav.typeOf(ip));
4331 const ptr_ty = try pt.navPtrType(nav_index);4135 const ptr_ty = try pt.navPtrType(nav_index);
43324136
4333 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";4137 if (nav.getExtern(ip) == null and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
4334 if ((!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) or
4335 (is_fn_body and zcu.typeToFunc(nav_ty).?.is_generic))
4336 {
4337 return o.lowerPtrToVoid(pt, ptr_ty);4138 return o.lowerPtrToVoid(pt, ptr_ty);
4338 }4139 }
43394140
4340 const llvm_global = if (is_fn_body)4141 const llvm_global = if (nav_ty.zigTypeTag(zcu) == .@"fn")
4341 (try o.resolveLlvmFunction(pt, nav_index)).ptrConst(&o.builder).global4142 (try o.resolveLlvmFunction(pt, nav_index)).ptrConst(&o.builder).global
4342 else4143 else
4343 (try o.resolveGlobalNav(pt, nav_index)).ptrConst(&o.builder).global;4144 (try o.resolveGlobalNav(pt, nav_index)).ptrConst(&o.builder).global;
...@@ -4380,21 +4181,18 @@ pub const Object = struct {...@@ -4380,21 +4181,18 @@ pub const Object = struct {
4380 /// types to work around a LLVM deficiency when targeting ARM/AArch64.4181 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
4381 fn getAtomicAbiType(o: *Object, pt: Zcu.PerThread, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {4182 fn getAtomicAbiType(o: *Object, pt: Zcu.PerThread, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {
4382 const zcu = pt.zcu;4183 const zcu = pt.zcu;
4383 const ip = &zcu.intern_pool;4184 switch (ty.zigTypeTag(zcu)) {
4384 const int_ty = switch (ty.zigTypeTag(zcu)) {4185 .int, .@"enum", .@"struct", .@"union" => {},
4385 .int => ty,
4386 .@"enum" => ty.intTagType(zcu),
4387 .@"struct" => Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntTypeUnordered(ip)),
4388 .float => {4186 .float => {
4389 if (!is_rmw_xchg) return .none;4187 if (!is_rmw_xchg) return .none;
4390 return o.builder.intType(@intCast(ty.abiSize(zcu) * 8));4188 return o.builder.intType(@intCast(ty.abiSize(zcu) * 8));
4391 },4189 },
4392 .bool => return .i8,4190 .bool => return .i8,
4393 else => return .none,4191 else => return .none,
4394 };4192 }
4395 const bit_count = int_ty.intInfo(zcu).bits;4193 const bit_count = ty.bitSize(zcu);
4396 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {4194 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));
4398 } else {4196 } else {
4399 return .none;4197 return .none;
4400 }4198 }
...@@ -4435,11 +4233,11 @@ pub const Object = struct {...@@ -4435,11 +4233,11 @@ pub const Object = struct {
4435 if (ptr_info.flags.is_const) {4233 if (ptr_info.flags.is_const) {
4436 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);4234 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4437 }4235 }
4438 const elem_align = if (ptr_info.flags.alignment != .none)4236 const elem_align: Builder.Alignment.Lazy = switch (ptr_info.flags.alignment) {
4439 ptr_info.flags.alignment4237 else => |a| .wrap(a.toLlvm()),
4440 else4238 .none => try o.lazyAbiAlignment(pt, .fromInterned(ptr_info.child)),
4441 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1");4239 };
4442 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder);4240 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
4443 } else if (ccAbiPromoteInt(fn_info.cc, zcu, param_ty)) |s| switch (s) {4241 } else if (ccAbiPromoteInt(fn_info.cc, zcu, param_ty)) |s| switch (s) {
4444 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),4242 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),
4445 .unsigned => try attributes.addParamAttr(llvm_arg_i, .zeroext, &o.builder),4243 .unsigned => try attributes.addParamAttr(llvm_arg_i, .zeroext, &o.builder),
...@@ -4456,7 +4254,7 @@ pub const Object = struct {...@@ -4456,7 +4254,7 @@ pub const Object = struct {
4456 ) Allocator.Error!void {4254 ) Allocator.Error!void {
4457 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);4255 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4458 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);4256 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);
4460 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);4258 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);
4461 }4259 }
44624260
...@@ -4502,7 +4300,7 @@ pub const Object = struct {...@@ -4502,7 +4300,7 @@ pub const Object = struct {
4502 const ret_ty = try o.lowerType(pt, Type.slice_const_u8_sentinel_0);4300 const ret_ty = try o.lowerType(pt, Type.slice_const_u8_sentinel_0);
4503 const target = &zcu.root_mod.resolved_target.result;4301 const target = &zcu.root_mod.resolved_target.result;
4504 const function_index = try o.builder.addFunction(4302 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),
4506 try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_type.name.fmt(ip)}),4304 try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_type.name.fmt(ip)}),
4507 toLlvmAddressSpace(.generic, target),4305 toLlvmAddressSpace(.generic, target),
4508 );4306 );
...@@ -4525,12 +4323,16 @@ pub const Object = struct {...@@ -4525,12 +4323,16 @@ pub const Object = struct {
45254323
4526 const bad_value_block = try wip.block(1, "BadValue");4324 const bad_value_block = try wip.block(1, "BadValue");
4527 const tag_int_value = wip.arg(0);4325 const tag_int_value = wip.arg(0);
4528 var wip_switch =4326 var wip_switch = try wip.@"switch"(
4529 try wip.@"switch"(tag_int_value, bad_value_block, @intCast(enum_type.names.len), .none);4327 tag_int_value,
4328 bad_value_block,
4329 @intCast(enum_type.field_names.len),
4330 .none,
4331 );
4530 defer wip_switch.finish(&wip);4332 defer wip_switch.finish(&wip);
45314333
4532 for (0..enum_type.names.len) |field_index| {4334 for (0..enum_type.field_names.len) |field_index| {
4533 const name = try o.builder.stringNull(enum_type.names.get(ip)[field_index].toSlice(ip));4335 const name = try o.builder.stringNull(enum_type.field_names.get(ip)[field_index].toSlice(ip));
4534 const name_init = try o.builder.stringConst(name);4336 const name_init = try o.builder.stringConst(name);
4535 const name_variable_index =4337 const name_variable_index =
4536 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);4338 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
...@@ -4562,6 +4364,11 @@ pub const Object = struct {...@@ -4562,6 +4364,11 @@ pub const Object = struct {
4562 try wip.finish();4364 try wip.finish();
4563 return function_index;4365 return function_index;
4564 }4366 }
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 }
4565};4372};
45664373
4567pub const NavGen = struct {4374pub const NavGen = struct {
...@@ -4601,10 +4408,44 @@ pub const NavGen = struct {...@@ -4601,10 +4408,44 @@ pub const NavGen = struct {
4601 const ty = Type.fromInterned(nav.typeOf(ip));4408 const ty = Type.fromInterned(nav.typeOf(ip));
46024409
4603 if (linkage != .internal and ip.isFunctionType(ty.toIntern())) {4410 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);
4605 } else {4446 } else {
4606 const variable_index = try o.resolveGlobalNav(pt, nav_index);4447 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);
4608 if (resolved.@"linksection".toSlice(ip)) |section|4449 if (resolved.@"linksection".toSlice(ip)) |section|
4609 variable_index.setSection(try o.builder.string(section), &o.builder);4450 variable_index.setSection(try o.builder.string(section), &o.builder);
4610 if (is_const) variable_index.setMutability(.constant, &o.builder);4451 if (is_const) variable_index.setMutability(.constant, &o.builder);
...@@ -4630,7 +4471,7 @@ pub const NavGen = struct {...@@ -4630,7 +4471,7 @@ pub const NavGen = struct {
4630 debug_file, // File4471 debug_file, // File
4631 debug_file, // Scope4472 debug_file, // Scope
4632 line_number,4473 line_number,
4633 try o.lowerDebugType(pt, ty),4474 try o.getDebugType(pt, ty),
4634 variable_index,4475 variable_index,
4635 .{ .local = linkage == .internal },4476 .{ .local = linkage == .internal },
4636 );4477 );
...@@ -4752,7 +4593,7 @@ pub const FuncGen = struct {...@@ -4752,7 +4593,7 @@ pub const FuncGen = struct {
4752 /// Have we seen loads or stores involving `allowzero` pointers?4593 /// Have we seen loads or stores involving `allowzero` pointers?
4753 allowzero_access: bool = false,4594 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 {
4756 // LLVM already considers null pointers to be valid in non-generic address spaces, so avoid4597 // LLVM already considers null pointers to be valid in non-generic address spaces, so avoid
4757 // pessimizing optimization for functions with accesses to such pointers.4598 // pessimizing optimization for functions with accesses to such pointers.
4758 if (info.flags.address_space == .generic and info.flags.is_allowzero) self.allowzero_access = true;4599 if (info.flags.address_space == .generic and info.flags.is_allowzero) self.allowzero_access = true;
...@@ -5220,7 +5061,7 @@ pub const FuncGen = struct {...@@ -5220,7 +5061,7 @@ pub const FuncGen = struct {
5220 try o.builder.metadataString(nav.fqn.toSlice(&zcu.intern_pool)),5061 try o.builder.metadataString(nav.fqn.toSlice(&zcu.intern_pool)),
5221 line_number,5062 line_number,
5222 line_number + func.lbrace_line,5063 line_number + func.lbrace_line,
5223 try o.lowerDebugType(pt, fn_ty),5064 try o.getDebugType(pt, fn_ty),
5224 .{5065 .{
5225 .di_flags = .{ .StaticMember = true },5066 .di_flags = .{ .StaticMember = true },
5226 .sp_flags = .{5067 .sp_flags = .{
...@@ -5490,10 +5331,10 @@ pub const FuncGen = struct {...@@ -5490,10 +5331,10 @@ pub const FuncGen = struct {
5490 if (ptr_info.flags.is_const) {5331 if (ptr_info.flags.is_const) {
5491 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);5332 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
5492 }5333 }
5493 const elem_align = (if (ptr_info.flags.alignment != .none)5334 const elem_align: Builder.Alignment.Lazy = switch (ptr_info.flags.alignment) {
5494 @as(InternPool.Alignment, ptr_info.flags.alignment)5335 else => |a| .wrap(a.toLlvm()),
5495 else5336 .none => try o.lazyAbiAlignment(pt, .fromInterned(ptr_info.child)),
5496 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();5337 };
5497 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);5338 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
5498 },5339 },
5499 };5340 };
...@@ -5518,7 +5359,7 @@ pub const FuncGen = struct {...@@ -5518,7 +5359,7 @@ pub const FuncGen = struct {
5518 return .none;5359 return .none;
5519 }5360 }
55205361
5521 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(zcu)) {5362 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBits(zcu)) {
5522 return .none;5363 return .none;
5523 }5364 }
55245365
...@@ -5637,7 +5478,7 @@ pub const FuncGen = struct {...@@ -5637,7 +5478,7 @@ pub const FuncGen = struct {
5637 return;5478 return;
5638 }5479 }
5639 const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?;5480 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)) {
5641 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {5482 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
5642 // Functions with an empty error set are emitted with an error code5483 // Functions with an empty error set are emitted with an error code
5643 // return type and return zero so they can be function pointers coerced5484 // return type and return zero so they can be function pointers coerced
...@@ -5702,7 +5543,7 @@ pub const FuncGen = struct {...@@ -5702,7 +5543,7 @@ pub const FuncGen = struct {
5702 const ptr_ty = self.typeOf(un_op);5543 const ptr_ty = self.typeOf(un_op);
5703 const ret_ty = ptr_ty.childType(zcu);5544 const ret_ty = ptr_ty.childType(zcu);
5704 const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?;5545 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)) {
5706 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {5547 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
5707 // Functions with an empty error set are emitted with an error code5548 // Functions with an empty error set are emitted with an error code
5708 // return type and return zero so they can be function pointers coerced5549 // return type and return zero so they can be function pointers coerced
...@@ -5833,14 +5674,13 @@ pub const FuncGen = struct {...@@ -5833,14 +5674,13 @@ pub const FuncGen = struct {
5833 const o = self.ng.object;5674 const o = self.ng.object;
5834 const pt = self.ng.pt;5675 const pt = self.ng.pt;
5835 const zcu = pt.zcu;5676 const zcu = pt.zcu;
5836 const ip = &zcu.intern_pool;
5837 const scalar_ty = operand_ty.scalarType(zcu);5677 const scalar_ty = operand_ty.scalarType(zcu);
5838 const int_ty = switch (scalar_ty.zigTypeTag(zcu)) {5678 const int_ty = switch (scalar_ty.zigTypeTag(zcu)) {
5839 .@"enum" => scalar_ty.intTagType(zcu),5679 .@"enum" => scalar_ty.intTagType(zcu),
5840 .int, .bool, .pointer, .error_set => scalar_ty,5680 .int, .bool, .pointer, .error_set => scalar_ty,
5841 .optional => blk: {5681 .optional => blk: {
5842 const payload_ty = operand_ty.optionalChild(zcu);5682 const payload_ty = operand_ty.optionalChild(zcu);
5843 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu) or5683 if (!payload_ty.hasRuntimeBits(zcu) or
5844 operand_ty.optionalReprIsPayload(zcu))5684 operand_ty.optionalReprIsPayload(zcu))
5845 {5685 {
5846 break :blk operand_ty;5686 break :blk operand_ty;
...@@ -5912,12 +5752,7 @@ pub const FuncGen = struct {...@@ -5912,12 +5752,7 @@ pub const FuncGen = struct {
5912 return phi.toValue();5752 return phi.toValue();
5913 },5753 },
5914 .float => return self.buildFloatCmp(fast, op, operand_ty, .{ lhs, rhs }),5754 .float => return self.buildFloatCmp(fast, op, operand_ty, .{ lhs, rhs }),
5915 .@"struct" => blk: {5755 .@"struct" => scalar_ty.bitpackBackingInt(zcu),
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 },
5921 else => unreachable,5756 else => unreachable,
5922 };5757 };
5923 const is_signed = int_ty.isSignedInt(zcu);5758 const is_signed = int_ty.isSignedInt(zcu);
...@@ -5953,7 +5788,7 @@ pub const FuncGen = struct {...@@ -5953,7 +5788,7 @@ pub const FuncGen = struct {
5953 return .none;5788 return .none;
5954 }5789 }
59555790
5956 const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu);5791 const have_block_result = inst_ty.hasRuntimeBits(zcu);
59575792
5958 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };5793 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };
5959 defer if (have_block_result) breaks.list.deinit(self.gpa);5794 defer if (have_block_result) breaks.list.deinit(self.gpa);
...@@ -6000,7 +5835,7 @@ pub const FuncGen = struct {...@@ -6000,7 +5835,7 @@ pub const FuncGen = struct {
60005835
6001 // Add the values to the lists only if the break provides a value.5836 // Add the values to the lists only if the break provides a value.
6002 const operand_ty = self.typeOf(branch.operand);5837 const operand_ty = self.typeOf(branch.operand);
6003 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {5838 if (operand_ty.hasRuntimeBits(zcu)) {
6004 const val = try self.resolveInst(branch.operand);5839 const val = try self.resolveInst(branch.operand);
60055840
6006 // For the phi node, we need the basic blocks and the values of the5841 // For the phi node, we need the basic blocks and the values of the
...@@ -6309,7 +6144,7 @@ pub const FuncGen = struct {...@@ -6309,7 +6144,7 @@ pub const FuncGen = struct {
6309 const pt = fg.ng.pt;6144 const pt = fg.ng.pt;
6310 const zcu = pt.zcu;6145 const zcu = pt.zcu;
6311 const payload_ty = err_union_ty.errorUnionPayload(zcu);6146 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);
6313 const err_union_llvm_ty = try o.lowerType(pt, err_union_ty);6148 const err_union_llvm_ty = try o.lowerType(pt, err_union_ty);
6314 const error_type = try o.errorIntType(pt);6149 const error_type = try o.errorIntType(pt);
63156150
...@@ -6645,7 +6480,7 @@ pub const FuncGen = struct {...@@ -6645,7 +6480,7 @@ pub const FuncGen = struct {
6645 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));6480 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));
6646 const slice_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst));6481 const slice_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst));
6647 const operand = try self.resolveInst(ty_op.operand);6482 const operand = try self.resolveInst(ty_op.operand);
6648 if (!array_ty.hasRuntimeBitsIgnoreComptime(zcu))6483 if (!array_ty.hasRuntimeBits(zcu))
6649 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");6484 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");
6650 const ptr = try self.wip.gep(.inbounds, try o.lowerType(pt, array_ty), operand, &.{6485 const ptr = try self.wip.gep(.inbounds, try o.lowerType(pt, array_ty), operand, &.{
6651 try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0),6486 try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0),
...@@ -6828,7 +6663,7 @@ pub const FuncGen = struct {...@@ -6828,7 +6663,7 @@ pub const FuncGen = struct {
6828 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6663 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6829 const slice_ptr = try self.resolveInst(ty_op.operand);6664 const slice_ptr = try self.resolveInst(ty_op.operand);
6830 const slice_ptr_ty = self.typeOf(ty_op.operand);6665 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
6833 return self.wip.gepStruct(slice_llvm_ty, slice_ptr, index, "");6668 return self.wip.gepStruct(slice_llvm_ty, slice_ptr, index, "");
6834 }6669 }
...@@ -6842,7 +6677,7 @@ pub const FuncGen = struct {...@@ -6842,7 +6677,7 @@ pub const FuncGen = struct {
6842 const slice = try self.resolveInst(bin_op.lhs);6677 const slice = try self.resolveInst(bin_op.lhs);
6843 const index = try self.resolveInst(bin_op.rhs);6678 const index = try self.resolveInst(bin_op.rhs);
6844 const elem_ty = slice_ty.childType(zcu);6679 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);
6846 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");6681 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");
6847 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");6682 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");
6848 if (isByRef(elem_ty, zcu)) {6683 if (isByRef(elem_ty, zcu)) {
...@@ -6867,7 +6702,7 @@ pub const FuncGen = struct {...@@ -6867,7 +6702,7 @@ pub const FuncGen = struct {
68676702
6868 const slice = try self.resolveInst(bin_op.lhs);6703 const slice = try self.resolveInst(bin_op.lhs);
6869 const index = try self.resolveInst(bin_op.rhs);6704 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));
6871 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");6706 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");
6872 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");6707 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");
6873 }6708 }
...@@ -6906,16 +6741,11 @@ pub const FuncGen = struct {...@@ -6906,16 +6741,11 @@ pub const FuncGen = struct {
6906 const zcu = pt.zcu;6741 const zcu = pt.zcu;
6907 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6742 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6908 const ptr_ty = self.typeOf(bin_op.lhs);6743 const ptr_ty = self.typeOf(bin_op.lhs);
6909 const elem_ty = ptr_ty.childType(zcu);6744 const elem_ty = ptr_ty.indexableElem(zcu);
6910 const llvm_elem_ty = try o.lowerPtrElemTy(pt, elem_ty);6745 const llvm_elem_ty = try o.lowerType(pt, elem_ty);
6911 const base_ptr = try self.resolveInst(bin_op.lhs);6746 const base_ptr = try self.resolveInst(bin_op.lhs);
6912 const rhs = try self.resolveInst(bin_op.rhs);6747 const rhs = try self.resolveInst(bin_op.rhs);
6913 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch6748 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{rhs}, "");
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}, "");
6919 if (isByRef(elem_ty, zcu)) {6749 if (isByRef(elem_ty, zcu)) {
6920 self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu));6750 self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu));
6921 const ptr_align = (ptr_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm();6751 const ptr_align = (ptr_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm();
...@@ -6934,8 +6764,8 @@ pub const FuncGen = struct {...@@ -6934,8 +6764,8 @@ pub const FuncGen = struct {
6934 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6764 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6935 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;6765 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
6936 const ptr_ty = self.typeOf(bin_op.lhs);6766 const ptr_ty = self.typeOf(bin_op.lhs);
6937 const elem_ty = ptr_ty.childType(zcu);6767 const elem_ty = ptr_ty.indexableElem(zcu);
6938 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return self.resolveInst(bin_op.lhs);6768 assert(elem_ty.hasRuntimeBits(zcu));
69396769
6940 const base_ptr = try self.resolveInst(bin_op.lhs);6770 const base_ptr = try self.resolveInst(bin_op.lhs);
6941 const rhs = try self.resolveInst(bin_op.rhs);6771 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6943,12 +6773,8 @@ pub const FuncGen = struct {...@@ -6943,12 +6773,8 @@ pub const FuncGen = struct {
6943 const elem_ptr = ty_pl.ty.toType();6773 const elem_ptr = ty_pl.ty.toType();
6944 if (elem_ptr.ptrInfo(zcu).flags.vector_index != .none) return base_ptr;6774 if (elem_ptr.ptrInfo(zcu).flags.vector_index != .none) return base_ptr;
69456775
6946 const llvm_elem_ty = try o.lowerPtrElemTy(pt, elem_ty);6776 const llvm_elem_ty = try o.lowerType(pt, elem_ty);
6947 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(zcu))6777 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{rhs}, "");
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}, "");
6952 }6778 }
69536779
6954 fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6780 fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
...@@ -6956,7 +6782,7 @@ pub const FuncGen = struct {...@@ -6956,7 +6782,7 @@ pub const FuncGen = struct {
6956 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;6782 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
6957 const struct_ptr = try self.resolveInst(struct_field.struct_operand);6783 const struct_ptr = try self.resolveInst(struct_field.struct_operand);
6958 const struct_ptr_ty = self.typeOf(struct_field.struct_operand);6784 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);
6960 }6786 }
69616787
6962 fn airStructFieldPtrIndex(6788 fn airStructFieldPtrIndex(
...@@ -6967,7 +6793,7 @@ pub const FuncGen = struct {...@@ -6967,7 +6793,7 @@ pub const FuncGen = struct {
6967 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6793 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6968 const struct_ptr = try self.resolveInst(ty_op.operand);6794 const struct_ptr = try self.resolveInst(ty_op.operand);
6969 const struct_ptr_ty = self.typeOf(ty_op.operand);6795 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);
6971 }6797 }
69726798
6973 fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6799 fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
...@@ -6980,7 +6806,7 @@ pub const FuncGen = struct {...@@ -6980,7 +6806,7 @@ pub const FuncGen = struct {
6980 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);6806 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
6981 const field_index = struct_field.field_index;6807 const field_index = struct_field.field_index;
6982 const field_ty = struct_ty.fieldType(field_index, zcu);6808 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
6985 if (!isByRef(struct_ty, zcu)) {6811 if (!isByRef(struct_ty, zcu)) {
6986 assert(!isByRef(field_ty, zcu));6812 assert(!isByRef(field_ty, zcu));
...@@ -6999,11 +6825,6 @@ pub const FuncGen = struct {...@@ -6999,11 +6825,6 @@ pub const FuncGen = struct {
6999 const truncated_int =6825 const truncated_int =
7000 try self.wip.cast(.trunc, shifted_value, same_size_int, "");6826 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
7001 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");6827 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, "");
7007 }6828 }
7008 return self.wip.cast(.trunc, shifted_value, elem_llvm_ty, "");6829 return self.wip.cast(.trunc, shifted_value, elem_llvm_ty, "");
7009 },6830 },
...@@ -7021,11 +6842,6 @@ pub const FuncGen = struct {...@@ -7021,11 +6842,6 @@ pub const FuncGen = struct {
7021 const truncated_int =6842 const truncated_int =
7022 try self.wip.cast(.trunc, containing_int, same_size_int, "");6843 try self.wip.cast(.trunc, containing_int, same_size_int, "");
7023 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");6844 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, "");
7029 }6845 }
7030 return self.wip.cast(.trunc, containing_int, elem_llvm_ty, "");6846 return self.wip.cast(.trunc, containing_int, elem_llvm_ty, "");
7031 },6847 },
...@@ -7041,15 +6857,17 @@ pub const FuncGen = struct {...@@ -7041,15 +6857,17 @@ pub const FuncGen = struct {
7041 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;6857 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
7042 const field_ptr =6858 const field_ptr =
7043 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");6859 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);
7045 const field_ptr_ty = try pt.ptrType(.{6861 const field_ptr_ty = try pt.ptrType(.{
7046 .child = field_ty.toIntern(),6862 .child = field_ty.toIntern(),
7047 .flags = .{ .alignment = alignment },6863 .flags = .{ .alignment = explicit_alignment },
7048 });6864 });
7049 if (isByRef(field_ty, zcu)) {6865 if (isByRef(field_ty, zcu)) {
7050 assert(alignment != .none);6866 const alignment = switch (explicit_alignment) {
7051 const field_alignment = alignment.toLlvm();6867 .none => field_ty.abiAlignment(zcu),
7052 return self.loadByRef(field_ptr, field_ty, field_alignment, .normal);6868 else => |a| a,
6869 };
6870 return self.loadByRef(field_ptr, field_ty, alignment.toLlvm(), .normal);
7053 } else {6871 } else {
7054 return self.load(field_ptr, field_ptr_ty);6872 return self.load(field_ptr, field_ptr_ty);
7055 }6873 }
...@@ -7057,7 +6875,7 @@ pub const FuncGen = struct {...@@ -7057,7 +6875,7 @@ pub const FuncGen = struct {
7057 .@"union" => {6875 .@"union" => {
7058 const union_llvm_ty = try o.lowerType(pt, struct_ty);6876 const union_llvm_ty = try o.lowerType(pt, struct_ty);
7059 const layout = struct_ty.unionGetLayout(zcu);6877 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));
7061 const field_ptr =6879 const field_ptr =
7062 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");6880 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");
7063 const payload_alignment = layout.payload_align.toLlvm();6881 const payload_alignment = layout.payload_align.toLlvm();
...@@ -7150,7 +6968,7 @@ pub const FuncGen = struct {...@@ -7150,7 +6968,7 @@ pub const FuncGen = struct {
7150 self.file,6968 self.file,
7151 self.scope,6969 self.scope,
7152 self.prev_dbg_line,6970 self.prev_dbg_line,
7153 try o.lowerDebugType(pt, ptr_ty.childType(zcu)),6971 try o.getDebugType(pt, ptr_ty.childType(zcu)),
7154 );6972 );
71556973
7156 _ = try self.wip.callIntrinsic(6974 _ = try self.wip.callIntrinsic(
...@@ -7183,7 +7001,7 @@ pub const FuncGen = struct {...@@ -7183,7 +7001,7 @@ pub const FuncGen = struct {
7183 self.file,7001 self.file,
7184 self.scope,7002 self.scope,
7185 self.prev_dbg_line,7003 self.prev_dbg_line,
7186 try o.lowerDebugType(pt, operand_ty),7004 try o.getDebugType(pt, operand_ty),
7187 arg_no: {7005 arg_no: {
7188 self.arg_inline_index += 1;7006 self.arg_inline_index += 1;
7189 break :arg_no self.arg_inline_index;7007 break :arg_no self.arg_inline_index;
...@@ -7193,7 +7011,7 @@ pub const FuncGen = struct {...@@ -7193,7 +7011,7 @@ pub const FuncGen = struct {
7193 self.file,7011 self.file,
7194 self.scope,7012 self.scope,
7195 self.prev_dbg_line,7013 self.prev_dbg_line,
7196 try o.lowerDebugType(pt, operand_ty),7014 try o.getDebugType(pt, operand_ty),
7197 );7015 );
71987016
7199 const zcu = pt.zcu;7017 const zcu = pt.zcu;
...@@ -7284,6 +7102,7 @@ pub const FuncGen = struct {...@@ -7284,6 +7102,7 @@ pub const FuncGen = struct {
7284 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);7102 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);
7285 const pt = self.ng.pt;7103 const pt = self.ng.pt;
7286 const zcu = pt.zcu;7104 const zcu = pt.zcu;
7105 const ip = &zcu.intern_pool;
7287 const target = zcu.getTarget();7106 const target = zcu.getTarget();
72887107
7289 var llvm_ret_i: usize = 0;7108 var llvm_ret_i: usize = 0;
...@@ -7308,7 +7127,7 @@ pub const FuncGen = struct {...@@ -7308,7 +7127,7 @@ pub const FuncGen = struct {
7308 const output_inst = try self.resolveInst(output.operand);7127 const output_inst = try self.resolveInst(output.operand);
7309 const output_ty = self.typeOf(output.operand);7128 const output_ty = self.typeOf(output.operand);
7310 assert(output_ty.zigTypeTag(zcu) == .pointer);7129 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
7313 switch (constraint[0]) {7132 switch (constraint[0]) {
7314 '=' => {},7133 '=' => {},
...@@ -7426,7 +7245,7 @@ pub const FuncGen = struct {...@@ -7426,7 +7245,7 @@ pub const FuncGen = struct {
7426 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {7245 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {
7427 if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu));7246 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));
7430 } else .none;7249 } else .none;
74317250
7432 llvm_param_i += 1;7251 llvm_param_i += 1;
...@@ -7440,7 +7259,7 @@ pub const FuncGen = struct {...@@ -7440,7 +7259,7 @@ pub const FuncGen = struct {
7440 if (constraint[0] != '+') continue;7259 if (constraint[0] != '+') continue;
74417260
7442 const rw_ty = self.typeOf(output.operand);7261 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));
7444 if (llvm_ret_indirect[output.index]) {7263 if (llvm_ret_indirect[output.index]) {
7445 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];7264 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];
7446 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);7265 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);
...@@ -7467,30 +7286,21 @@ pub const FuncGen = struct {...@@ -7467,30 +7286,21 @@ pub const FuncGen = struct {
7467 total_i += 1;7286 total_i += 1;
7468 }7287 }
74697288
7470 const ip = &zcu.intern_pool;
7471 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
7472 const struct_type: Type = .fromInterned(aggregate.ty);
7473 if (total_i != 0) try llvm_constraints.append(gpa, ',');7289 if (total_i != 0) try llvm_constraints.append(gpa, ',');
7474 switch (aggregate.storage) {7290 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
7475 .elems => |elems| for (elems, 0..) |elem, i| {7291 const clobbers_ty = clobbers_val.typeOf(zcu);
7476 switch (elem) {7292 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
7477 .bool_true => {7293 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
7478 const name = struct_type.structFieldName(i, zcu).toSlice(ip).?;7294 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
7479 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);7295 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
7480 },7296 const limb_bits = @bitSizeOf(std.math.big.Limb);
7481 .bool_false => continue,7297 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
7482 else => unreachable,7298 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
7483 }7299 0 => continue, // field is false
7484 },7300 1 => {}, // field is true
7485 .repeated_elem => |elem| switch (elem) {7301 }
7486 .bool_true => for (0..struct_type.structFieldCount(zcu)) |i| {7302 const name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
7487 const name = struct_type.structFieldName(i, zcu).toSlice(ip).?;7303 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
7488 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
7489 },
7490 .bool_false => {},
7491 else => unreachable,
7492 },
7493 .bytes => @panic("TODO"),
7494 }7304 }
74957305
7496 // We have finished scanning through all inputs/outputs, so the number of7306 // We have finished scanning through all inputs/outputs, so the number of
...@@ -7676,7 +7486,7 @@ pub const FuncGen = struct {...@@ -7676,7 +7486,7 @@ pub const FuncGen = struct {
76767486
7677 comptime assert(optional_layout_version == 3);7487 comptime assert(optional_layout_version == 3);
76787488
7679 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7489 if (!payload_ty.hasRuntimeBits(zcu)) {
7680 const loaded = if (operand_is_ptr)7490 const loaded = if (operand_is_ptr)
7681 try self.wip.load(access_kind, optional_llvm_ty, operand, .default, "")7491 try self.wip.load(access_kind, optional_llvm_ty, operand, .default, "")
7682 else7492 else
...@@ -7719,7 +7529,7 @@ pub const FuncGen = struct {...@@ -7719,7 +7529,7 @@ pub const FuncGen = struct {
77197529
7720 if (operand_is_ptr) self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu));7530 if (operand_is_ptr) self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu));
77217531
7722 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7532 if (!payload_ty.hasRuntimeBits(zcu)) {
7723 const loaded = if (operand_is_ptr)7533 const loaded = if (operand_is_ptr)
7724 try self.wip.load(access_kind, try o.lowerType(pt, err_union_ty), operand, .default, "")7534 try self.wip.load(access_kind, try o.lowerType(pt, err_union_ty), operand, .default, "")
7725 else7535 else
...@@ -7746,7 +7556,7 @@ pub const FuncGen = struct {...@@ -7746,7 +7556,7 @@ pub const FuncGen = struct {
7746 const operand = try self.resolveInst(ty_op.operand);7556 const operand = try self.resolveInst(ty_op.operand);
7747 const optional_ty = self.typeOf(ty_op.operand).childType(zcu);7557 const optional_ty = self.typeOf(ty_op.operand).childType(zcu);
7748 const payload_ty = optional_ty.optionalChild(zcu);7558 const payload_ty = optional_ty.optionalChild(zcu);
7749 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7559 if (!payload_ty.hasRuntimeBits(zcu)) {
7750 // We have a pointer to a zero-bit value and we need to return7560 // We have a pointer to a zero-bit value and we need to return
7751 // a pointer to a zero-bit value.7561 // a pointer to a zero-bit value.
7752 return operand;7562 return operand;
...@@ -7774,7 +7584,7 @@ pub const FuncGen = struct {...@@ -7774,7 +7584,7 @@ pub const FuncGen = struct {
7774 const access_kind: Builder.MemoryAccessKind =7584 const access_kind: Builder.MemoryAccessKind =
7775 if (optional_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;7585 if (optional_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
77767586
7777 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7587 if (!payload_ty.hasRuntimeBits(zcu)) {
7778 self.maybeMarkAllowZeroAccess(optional_ptr_ty.ptrInfo(zcu));7588 self.maybeMarkAllowZeroAccess(optional_ptr_ty.ptrInfo(zcu));
77797589
7780 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.7590 // 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 {...@@ -7810,7 +7620,7 @@ pub const FuncGen = struct {
7810 const operand = try self.resolveInst(ty_op.operand);7620 const operand = try self.resolveInst(ty_op.operand);
7811 const optional_ty = self.typeOf(ty_op.operand);7621 const optional_ty = self.typeOf(ty_op.operand);
7812 const payload_ty = self.typeOfIndex(inst);7622 const payload_ty = self.typeOfIndex(inst);
7813 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;7623 if (!payload_ty.hasRuntimeBits(zcu)) return .none;
78147624
7815 if (optional_ty.optionalReprIsPayload(zcu)) {7625 if (optional_ty.optionalReprIsPayload(zcu)) {
7816 // Payload value is the same as the optional value.7626 // Payload value is the same as the optional value.
...@@ -7832,7 +7642,7 @@ pub const FuncGen = struct {...@@ -7832,7 +7642,7 @@ pub const FuncGen = struct {
7832 const result_ty = self.typeOfIndex(inst);7642 const result_ty = self.typeOfIndex(inst);
7833 const payload_ty = if (operand_is_ptr) result_ty.childType(zcu) else result_ty;7643 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)) {
7836 return if (operand_is_ptr) operand else .none;7646 return if (operand_is_ptr) operand else .none;
7837 }7647 }
7838 const offset = try errUnionPayloadOffset(payload_ty, pt);7648 const offset = try errUnionPayloadOffset(payload_ty, pt);
...@@ -7876,7 +7686,7 @@ pub const FuncGen = struct {...@@ -7876,7 +7686,7 @@ pub const FuncGen = struct {
7876 if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;7686 if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
78777687
7878 const payload_ty = err_union_ty.errorUnionPayload(zcu);7688 const payload_ty = err_union_ty.errorUnionPayload(zcu);
7879 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7689 if (!payload_ty.hasRuntimeBits(zcu)) {
7880 if (!operand_is_ptr) return operand;7690 if (!operand_is_ptr) return operand;
78817691
7882 self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu));7692 self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu));
...@@ -7912,7 +7722,7 @@ pub const FuncGen = struct {...@@ -7912,7 +7722,7 @@ pub const FuncGen = struct {
7912 const access_kind: Builder.MemoryAccessKind =7722 const access_kind: Builder.MemoryAccessKind =
7913 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;7723 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
79147724
7915 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7725 if (!payload_ty.hasRuntimeBits(zcu)) {
7916 self.maybeMarkAllowZeroAccess(err_union_ptr_ty.ptrInfo(zcu));7726 self.maybeMarkAllowZeroAccess(err_union_ptr_ty.ptrInfo(zcu));
79177727
7918 _ = try self.wip.store(access_kind, non_error_val, operand, .default);7728 _ = try self.wip.store(access_kind, non_error_val, operand, .default);
...@@ -7959,9 +7769,8 @@ pub const FuncGen = struct {...@@ -7959,9 +7769,8 @@ pub const FuncGen = struct {
7959 const struct_llvm_ty = try o.lowerType(pt, struct_ty);7769 const struct_llvm_ty = try o.lowerType(pt, struct_ty);
7960 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;7770 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
7961 assert(self.err_ret_trace != .none);7771 assert(self.err_ret_trace != .none);
7962 const field_ptr =7772 const field_ptr = try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7963 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");7773 const field_alignment = struct_ty.explicitFieldAlignment(field_index, zcu);
7964 const field_alignment = struct_ty.fieldAlignment(field_index, zcu);
7965 const field_ty = struct_ty.fieldType(field_index, zcu);7774 const field_ty = struct_ty.fieldType(field_index, zcu);
7966 const field_ptr_ty = try pt.ptrType(.{7775 const field_ptr_ty = try pt.ptrType(.{
7967 .child = field_ty.toIntern(),7776 .child = field_ty.toIntern(),
...@@ -8002,7 +7811,7 @@ pub const FuncGen = struct {...@@ -8002,7 +7811,7 @@ pub const FuncGen = struct {
8002 const payload_ty = self.typeOf(ty_op.operand);7811 const payload_ty = self.typeOf(ty_op.operand);
8003 const non_null_bit = try o.builder.intValue(.i8, 1);7812 const non_null_bit = try o.builder.intValue(.i8, 1);
8004 comptime assert(optional_layout_version == 3);7813 comptime assert(optional_layout_version == 3);
8005 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return non_null_bit;7814 assert(payload_ty.hasRuntimeBits(zcu));
8006 const operand = try self.resolveInst(ty_op.operand);7815 const operand = try self.resolveInst(ty_op.operand);
8007 const optional_ty = self.typeOfIndex(inst);7816 const optional_ty = self.typeOfIndex(inst);
8008 if (optional_ty.optionalReprIsPayload(zcu)) return operand;7817 if (optional_ty.optionalReprIsPayload(zcu)) return operand;
...@@ -8036,9 +7845,7 @@ pub const FuncGen = struct {...@@ -8036,9 +7845,7 @@ pub const FuncGen = struct {
8036 const err_un_ty = self.typeOfIndex(inst);7845 const err_un_ty = self.typeOfIndex(inst);
8037 const operand = try self.resolveInst(ty_op.operand);7846 const operand = try self.resolveInst(ty_op.operand);
8038 const payload_ty = self.typeOf(ty_op.operand);7847 const payload_ty = self.typeOf(ty_op.operand);
8039 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {7848 assert(payload_ty.hasRuntimeBits(zcu));
8040 return operand;
8041 }
8042 const ok_err_code = try o.builder.intValue(try o.errorIntType(pt), 0);7849 const ok_err_code = try o.builder.intValue(try o.errorIntType(pt), 0);
8043 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);7850 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);
80447851
...@@ -8078,7 +7885,7 @@ pub const FuncGen = struct {...@@ -8078,7 +7885,7 @@ pub const FuncGen = struct {
8078 const err_un_ty = self.typeOfIndex(inst);7885 const err_un_ty = self.typeOfIndex(inst);
8079 const payload_ty = err_un_ty.errorUnionPayload(zcu);7886 const payload_ty = err_un_ty.errorUnionPayload(zcu);
8080 const operand = try self.resolveInst(ty_op.operand);7887 const operand = try self.resolveInst(ty_op.operand);
8081 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return operand;7888 if (!payload_ty.hasRuntimeBits(zcu)) return operand;
8082 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);7889 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);
80837890
8084 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);7891 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
...@@ -8530,7 +8337,7 @@ pub const FuncGen = struct {...@@ -8530,7 +8337,7 @@ pub const FuncGen = struct {
8530 const ptr = try self.resolveInst(bin_op.lhs);8337 const ptr = try self.resolveInst(bin_op.lhs);
8531 const offset = try self.resolveInst(bin_op.rhs);8338 const offset = try self.resolveInst(bin_op.rhs);
8532 const ptr_ty = self.typeOf(bin_op.lhs);8339 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));
8534 switch (ptr_ty.ptrSize(zcu)) {8341 switch (ptr_ty.ptrSize(zcu)) {
8535 // It's a pointer to an array, so according to LLVM we need an extra GEP index.8342 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
8536 .one => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{8343 .one => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{
...@@ -8554,7 +8361,7 @@ pub const FuncGen = struct {...@@ -8554,7 +8361,7 @@ pub const FuncGen = struct {
8554 const offset = try self.resolveInst(bin_op.rhs);8361 const offset = try self.resolveInst(bin_op.rhs);
8555 const negative_offset = try self.wip.neg(offset, "");8362 const negative_offset = try self.wip.neg(offset, "");
8556 const ptr_ty = self.typeOf(bin_op.lhs);8363 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));
8558 switch (ptr_ty.ptrSize(zcu)) {8365 switch (ptr_ty.ptrSize(zcu)) {
8559 // It's a pointer to an array, so according to LLVM we need an extra GEP index.8366 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
8560 .one => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{8367 .one => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{
...@@ -9515,7 +9322,7 @@ pub const FuncGen = struct {...@@ -9515,7 +9322,7 @@ pub const FuncGen = struct {
9515 self.file,9322 self.file,
9516 self.scope,9323 self.scope,
9517 lbrace_line,9324 lbrace_line,
9518 try o.lowerDebugType(pt, inst_ty),9325 try o.getDebugType(pt, inst_ty),
9519 self.arg_index,9326 self.arg_index,
9520 );9327 );
95219328
...@@ -9581,7 +9388,7 @@ pub const FuncGen = struct {...@@ -9581,7 +9388,7 @@ pub const FuncGen = struct {
9581 const zcu = pt.zcu;9388 const zcu = pt.zcu;
9582 const ptr_ty = self.typeOfIndex(inst);9389 const ptr_ty = self.typeOfIndex(inst);
9583 const pointee_type = ptr_ty.childType(zcu);9390 const pointee_type = ptr_ty.childType(zcu);
9584 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu))9391 if (!pointee_type.hasRuntimeBits(zcu))
9585 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();9392 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();
95869393
9587 const pointee_llvm_ty = try o.lowerType(pt, pointee_type);9394 const pointee_llvm_ty = try o.lowerType(pt, pointee_type);
...@@ -9595,7 +9402,7 @@ pub const FuncGen = struct {...@@ -9595,7 +9402,7 @@ pub const FuncGen = struct {
9595 const zcu = pt.zcu;9402 const zcu = pt.zcu;
9596 const ptr_ty = self.typeOfIndex(inst);9403 const ptr_ty = self.typeOfIndex(inst);
9597 const ret_ty = ptr_ty.childType(zcu);9404 const ret_ty = ptr_ty.childType(zcu);
9598 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu))9405 if (!ret_ty.hasRuntimeBits(zcu))
9599 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();9406 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();
9600 if (self.ret_ptr != .none) return self.ret_ptr;9407 if (self.ret_ptr != .none) return self.ret_ptr;
9601 const ret_llvm_ty = try o.lowerType(pt, ret_ty);9408 const ret_llvm_ty = try o.lowerType(pt, ret_ty);
...@@ -9849,7 +9656,7 @@ pub const FuncGen = struct {...@@ -9849,7 +9656,7 @@ pub const FuncGen = struct {
9849 const ptr_ty = self.typeOf(atomic_load.ptr);9656 const ptr_ty = self.typeOf(atomic_load.ptr);
9850 const info = ptr_ty.ptrInfo(zcu);9657 const info = ptr_ty.ptrInfo(zcu);
9851 const elem_ty = Type.fromInterned(info.child);9658 const elem_ty = Type.fromInterned(info.child);
9852 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;9659 if (!elem_ty.hasRuntimeBits(zcu)) return .none;
9853 const ordering = toLlvmAtomicOrdering(atomic_load.order);9660 const ordering = toLlvmAtomicOrdering(atomic_load.order);
9854 const llvm_abi_ty = try o.getAtomicAbiType(pt, elem_ty, false);9661 const llvm_abi_ty = try o.getAtomicAbiType(pt, elem_ty, false);
9855 const ptr_alignment = (if (info.flags.alignment != .none)9662 const ptr_alignment = (if (info.flags.alignment != .none)
...@@ -9897,7 +9704,7 @@ pub const FuncGen = struct {...@@ -9897,7 +9704,7 @@ pub const FuncGen = struct {
9897 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9704 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9898 const ptr_ty = self.typeOf(bin_op.lhs);9705 const ptr_ty = self.typeOf(bin_op.lhs);
9899 const operand_ty = ptr_ty.childType(zcu);9706 const operand_ty = ptr_ty.childType(zcu);
9900 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .none;9707 if (!operand_ty.hasRuntimeBits(zcu)) return .none;
9901 const ptr = try self.resolveInst(bin_op.lhs);9708 const ptr = try self.resolveInst(bin_op.lhs);
9902 var element = try self.resolveInst(bin_op.rhs);9709 var element = try self.resolveInst(bin_op.rhs);
9903 const llvm_abi_ty = try o.getAtomicAbiType(pt, operand_ty, false);9710 const llvm_abi_ty = try o.getAtomicAbiType(pt, operand_ty, false);
...@@ -10310,14 +10117,14 @@ pub const FuncGen = struct {...@@ -10310,14 +10117,14 @@ pub const FuncGen = struct {
10310 const ip = &zcu.intern_pool;10117 const ip = &zcu.intern_pool;
10311 const enum_type = ip.loadEnumType(enum_ty.toIntern());10118 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
10314 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());10121 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());
10315 if (gop.found_existing) return gop.value_ptr.*;10122 if (gop.found_existing) return gop.value_ptr.*;
10316 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));10123 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));
1031710124
10318 const target = &zcu.root_mod.resolved_target.result;10125 const target = &zcu.root_mod.resolved_target.result;
10319 const function_index = try o.builder.addFunction(10126 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),
10321 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_type.name.fmt(ip)}),10128 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_type.name.fmt(ip)}),
10322 toLlvmAddressSpace(.generic, target),10129 toLlvmAddressSpace(.generic, target),
10323 );10130 );
...@@ -10338,13 +10145,13 @@ pub const FuncGen = struct {...@@ -10338,13 +10145,13 @@ pub const FuncGen = struct {
10338 defer wip.deinit();10145 defer wip.deinit();
10339 wip.cursor = .{ .block = try wip.block(0, "Entry") };10146 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");
10342 const unnamed_block = try wip.block(1, "Unnamed");10149 const unnamed_block = try wip.block(1, "Unnamed");
10343 const tag_int_value = wip.arg(0);10150 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);
10345 defer wip_switch.finish(&wip);10152 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| {
10348 const this_tag_int_value = try o.lowerValue(10155 const this_tag_int_value = try o.lowerValue(
10349 pt,10156 pt,
10350 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),10157 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
...@@ -10813,15 +10620,14 @@ pub const FuncGen = struct {...@@ -10813,15 +10620,14 @@ pub const FuncGen = struct {
10813 },10620 },
10814 .@"struct" => {10621 .@"struct" => {
10815 if (zcu.typeToPackedStruct(result_ty)) |struct_type| {10622 if (zcu.typeToPackedStruct(result_ty)) |struct_type| {
10816 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);10623 const backing_int_ty: Type = .fromInterned(struct_type.packed_backing_int_type);
10817 assert(backing_int_ty != .none);10624 const big_bits = backing_int_ty.bitSize(zcu);
10818 const big_bits = Type.fromInterned(backing_int_ty).bitSize(zcu);
10819 const int_ty = try o.builder.intType(@intCast(big_bits));10625 const int_ty = try o.builder.intType(@intCast(big_bits));
10820 comptime assert(Type.packed_struct_layout_version == 2);10626 comptime assert(Type.packed_struct_layout_version == 2);
10821 var running_int = try o.builder.intValue(int_ty, 0);10627 var running_int = try o.builder.intValue(int_ty, 0);
10822 var running_bits: u16 = 0;10628 var running_bits: u16 = 0;
10823 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {10629 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
10826 const non_int_val = try self.resolveInst(elem);10632 const non_int_val = try self.resolveInst(elem);
10827 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu));10633 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu));
...@@ -10853,12 +10659,12 @@ pub const FuncGen = struct {...@@ -10853,12 +10659,12 @@ pub const FuncGen = struct {
1085310659
10854 const llvm_elem = try self.resolveInst(elem);10660 const llvm_elem = try self.resolveInst(elem);
10855 const llvm_i = o.llvmFieldIndex(result_ty, i).?;10661 const llvm_i = o.llvmFieldIndex(result_ty, i).?;
10856 const field_ptr =10662 const field_ptr = try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");
10857 try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");10663
10858 const field_ptr_ty = try pt.ptrType(.{10664 const field_ptr_ty = try pt.ptrType(.{
10859 .child = self.typeOf(elem).toIntern(),10665 .child = self.typeOf(elem).toIntern(),
10860 .flags = .{10666 .flags = .{
10861 .alignment = result_ty.fieldAlignment(i, zcu),10667 .alignment = result_ty.explicitFieldAlignment(i, zcu),
10862 },10668 },
10863 });10669 });
10864 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);10670 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);
...@@ -10920,28 +10726,16 @@ pub const FuncGen = struct {...@@ -10920,28 +10726,16 @@ pub const FuncGen = struct {
10920 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;10726 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
10921 const union_ty = self.typeOfIndex(inst);10727 const union_ty = self.typeOfIndex(inst);
10922 const union_llvm_ty = try o.lowerType(pt, union_ty);10728 const union_llvm_ty = try o.lowerType(pt, union_ty);
10923 const layout = union_ty.unionGetLayout(zcu);
10924 const union_obj = zcu.typeToUnion(union_ty).?;10729 const union_obj = zcu.typeToUnion(union_ty).?;
1092510730
10926 if (union_obj.flagsUnordered(ip).layout == .@"packed") {10731 assert(union_obj.layout != .@"packed");
10927 const big_bits = union_ty.bitSize(zcu);10732
10928 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));10733 const layout = Type.getUnionLayout(union_obj, zcu);
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 }
1093810734
10939 const tag_int_val = blk: {10735 const tag_int_val = blk: {
10940 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);10736 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
10941 const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];10737 const tag_val = try pt.enumValueFieldIndex(tag_ty, extra.field_index);
10942 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, zcu).?;10738 break :blk tag_val.intFromEnum(zcu);
10943 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
10944 break :blk try tag_val.intFromEnum(tag_ty, pt);
10945 };10739 };
10946 if (layout.payload_size == 0) {10740 if (layout.payload_size == 0) {
10947 if (layout.tag_size == 0) {10741 if (layout.tag_size == 0) {
...@@ -10963,16 +10757,14 @@ pub const FuncGen = struct {...@@ -10963,16 +10757,14 @@ pub const FuncGen = struct {
10963 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);10757 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10964 const field_llvm_ty = try o.lowerType(pt, field_ty);10758 const field_llvm_ty = try o.lowerType(pt, field_ty);
10965 const field_size = field_ty.abiSize(zcu);10759 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);
10967 const llvm_usize = try o.lowerType(pt, Type.usize);10761 const llvm_usize = try o.lowerType(pt, Type.usize);
10968 const usize_zero = try o.builder.intValue(llvm_usize, 0);10762 const usize_zero = try o.builder.intValue(llvm_usize, 0);
1096910763
10764 assert(field_ty.hasRuntimeBits(zcu));
10765
10970 const llvm_union_ty = t: {10766 const llvm_union_ty = t: {
10971 const payload_ty = p: {10767 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 }
10976 if (field_size == layout.payload_size) {10768 if (field_size == layout.payload_size) {
10977 break :p field_llvm_ty;10769 break :p field_llvm_ty;
10978 }10770 }
...@@ -10982,7 +10774,7 @@ pub const FuncGen = struct {...@@ -10982,7 +10774,7 @@ pub const FuncGen = struct {
10982 });10774 });
10983 };10775 };
10984 if (layout.tag_size == 0) break :t try o.builder.structType(.normal, &.{payload_ty});10776 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));
10986 var fields: [3]Builder.Type = undefined;10778 var fields: [3]Builder.Type = undefined;
10987 var fields_len: usize = 2;10779 var fields_len: usize = 2;
10988 if (layout.tag_align.compare(.gte, layout.payload_align)) {10780 if (layout.tag_align.compare(.gte, layout.payload_align)) {
...@@ -11023,11 +10815,11 @@ pub const FuncGen = struct {...@@ -11023,11 +10815,11 @@ pub const FuncGen = struct {
11023 const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align));10815 const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align));
11024 const indices: [2]Builder.Value = .{ usize_zero, try o.builder.intValue(.i32, tag_index) };10816 const indices: [2]Builder.Value = .{ usize_zero, try o.builder.intValue(.i32, tag_index) };
11025 const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, "");10817 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));
11027 var big_int_space: Value.BigIntSpace = undefined;10819 var big_int_space: Value.BigIntSpace = undefined;
11028 const tag_big_int = tag_int_val.toBigInt(&big_int_space, zcu);10820 const tag_big_int = tag_int_val.toBigInt(&big_int_space, zcu);
11029 const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int);10821 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();
11031 _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment);10823 _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment);
11032 }10824 }
1103310825
...@@ -11274,63 +11066,45 @@ pub const FuncGen = struct {...@@ -11274,63 +11066,45 @@ pub const FuncGen = struct {
1127411066
11275 fn fieldPtr(11067 fn fieldPtr(
11276 self: *FuncGen,11068 self: *FuncGen,
11277 inst: Air.Inst.Index,11069 aggregate_ptr: Builder.Value,
11278 struct_ptr: Builder.Value,11070 aggregate_ptr_ty: Type,
11279 struct_ptr_ty: Type,
11280 field_index: u32,11071 field_index: u32,
11281 ) !Builder.Value {11072 ) !Builder.Value {
11282 const o = self.ng.object;11073 const o = self.ng.object;
11283 const pt = self.ng.pt;11074 const pt = self.ng.pt;
11284 const zcu = pt.zcu;11075 const zcu = pt.zcu;
11285 const struct_ty = struct_ptr_ty.childType(zcu);11076 const aggregate_ty = aggregate_ptr_ty.childType(zcu);
11286 switch (struct_ty.zigTypeTag(zcu)) {11077 if (aggregate_ty.containerLayout(zcu) == .@"packed") {
11287 .@"struct" => switch (struct_ty.containerLayout(zcu)) {11078 // A pointer to a bitpack field is equivalent to a pointer to the whole bitpack; the
11288 .@"packed" => {11079 // bit offset is represented in the pointer *type*.
11289 const result_ty = self.typeOfIndex(inst);11080 return aggregate_ptr;
11290 const result_ty_info = result_ty.ptrInfo(zcu);11081 }
11291 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu);11082 switch (aggregate_ty.zigTypeTag(zcu)) {
11292 const struct_type = zcu.typeToStruct(struct_ty).?;11083 .@"struct" => {
1129311084 if (!aggregate_ty.hasRuntimeBits(zcu)) {
11294 if (result_ty_info.packed_offset.host_size != 0) {11085 return aggregate_ptr;
11295 // From LLVM's perspective, a pointer to a packed struct and a pointer11086 }
11296 // to a field of a packed struct are the same. The difference is in the11087 const struct_llvm_ty = try o.lowerType(pt, aggregate_ty);
11297 // Zig pointer type which provides information for how to mask and shift11088 if (o.llvmFieldIndex(aggregate_ty, field_index)) |llvm_field_index| {
11298 // out the relevant bits when accessing the pointee.11089 return self.wip.gepStruct(struct_llvm_ty, aggregate_ptr, llvm_field_index, "");
11299 return struct_ptr;11090 } else {
11300 }11091 // If we found no index then this means this is a zero sized field at the
1130111092 // end of the struct. Treat our struct pointer as an array of two and get
11302 // We have a pointer to a packed struct field that happens to be byte-aligned.11093 // the index to the element at index `1` to get a pointer to the end of
11303 // Offset our operand pointer by the correct number of bytes.11094 // the struct.
11304 const byte_offset = @divExact(zcu.structPackedFieldBitOffset(struct_type, field_index) + struct_ptr_ty_info.packed_offset.bit_offset, 8);11095 const llvm_index = try o.builder.intValue(
11305 if (byte_offset == 0) return struct_ptr;11096 try o.lowerType(pt, Type.usize),
11306 const usize_ty = try o.lowerType(pt, Type.usize);11097 @intFromBool(aggregate_ty.hasRuntimeBits(zcu)),
11307 const llvm_index = try o.builder.intValue(usize_ty, byte_offset);11098 );
11308 return self.wip.gep(.inbounds, .i8, struct_ptr, &.{llvm_index}, "");11099 return self.wip.gep(.inbounds, struct_llvm_ty, aggregate_ptr, &.{llvm_index}, "");
11309 },11100 }
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 },
11327 },11101 },
11328 .@"union" => {11102 .@"union" => {
11329 const layout = struct_ty.unionGetLayout(zcu);11103 const layout = aggregate_ty.unionGetLayout(zcu);
11330 if (layout.payload_size == 0 or struct_ty.containerLayout(zcu) == .@"packed") return struct_ptr;11104 if (layout.payload_size == 0) return aggregate_ptr;
11331 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));11105 const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align));
11332 const union_llvm_ty = try o.lowerType(pt, struct_ty);11106 const union_llvm_ty = try o.lowerType(pt, aggregate_ty);
11333 return self.wip.gepStruct(union_llvm_ty, struct_ptr, payload_index, "");11107 return self.wip.gepStruct(union_llvm_ty, aggregate_ptr, payload_index, "");
11334 },11108 },
11335 else => unreachable,11109 else => unreachable,
11336 }11110 }
...@@ -11406,7 +11180,7 @@ pub const FuncGen = struct {...@@ -11406,7 +11180,7 @@ pub const FuncGen = struct {
11406 const zcu = pt.zcu;11180 const zcu = pt.zcu;
11407 const info = ptr_ty.ptrInfo(zcu);11181 const info = ptr_ty.ptrInfo(zcu);
11408 const elem_ty = Type.fromInterned(info.child);11182 const elem_ty = Type.fromInterned(info.child);
11409 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;11183 if (!elem_ty.hasRuntimeBits(zcu)) return .none;
1141011184
11411 const ptr_alignment = (if (info.flags.alignment != .none)11185 const ptr_alignment = (if (info.flags.alignment != .none)
11412 @as(InternPool.Alignment, info.flags.alignment)11186 @as(InternPool.Alignment, info.flags.alignment)
...@@ -11478,7 +11252,7 @@ pub const FuncGen = struct {...@@ -11478,7 +11252,7 @@ pub const FuncGen = struct {
11478 const zcu = pt.zcu;11252 const zcu = pt.zcu;
11479 const info = ptr_ty.ptrInfo(zcu);11253 const info = ptr_ty.ptrInfo(zcu);
11480 const elem_ty = Type.fromInterned(info.child);11254 const elem_ty = Type.fromInterned(info.child);
11481 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {11255 if (!elem_ty.hasRuntimeBits(zcu)) {
11482 return;11256 return;
11483 }11257 }
11484 const ptr_alignment = ptr_ty.ptrAlignment(zcu).toLlvm();11258 const ptr_alignment = ptr_ty.ptrAlignment(zcu).toLlvm();
...@@ -12061,7 +11835,7 @@ fn returnTypeByRef(zcu: *Zcu, target: *const std.Target, ty: Type) bool {...@@ -12061,7 +11835,7 @@ fn returnTypeByRef(zcu: *Zcu, target: *const std.Target, ty: Type) bool {
1206111835
12062fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: *const std.Target) bool {11836fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: *const std.Target) bool {
12063 const return_type = Type.fromInterned(fn_info.return_type);11837 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
12066 return switch (fn_info.cc) {11840 return switch (fn_info.cc) {
12067 .auto => returnTypeByRef(zcu, target, return_type),11841 .auto => returnTypeByRef(zcu, target, return_type),
...@@ -12101,11 +11875,9 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: *const std.Target) bool {...@@ -12101,11 +11875,9 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: *const std.Target) bool {
12101fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11875fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
12102 const zcu = pt.zcu;11876 const zcu = pt.zcu;
12103 const return_type = Type.fromInterned(fn_info.return_type);11877 const return_type = Type.fromInterned(fn_info.return_type);
12104 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) {11878 if (!return_type.hasRuntimeBits(zcu)) {
12105 // If the return type is an error set or an error union, then we make this11879 assert(!return_type.isError(zcu));
12106 // anyerror return type instead, so that it can be coerced into a function11880 return .void;
12107 // pointer type which has anyerror as the return type.
12108 return if (return_type.isError(zcu)) try o.errorIntType(pt) else .void;
12109 }11881 }
12110 const target = zcu.getTarget();11882 const target = zcu.getTarget();
12111 switch (fn_info.cc) {11883 switch (fn_info.cc) {
...@@ -12149,7 +11921,7 @@ fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType)...@@ -12149,7 +11921,7 @@ fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType)
12149 var types: [8]Builder.Type = undefined;11921 var types: [8]Builder.Type = undefined;
12150 for (0..return_type.structFieldCount(zcu)) |field_index| {11922 for (0..return_type.structFieldCount(zcu)) |field_index| {
12151 const field_ty = return_type.fieldType(field_index, zcu);11923 const field_ty = return_type.fieldType(field_index, zcu);
12152 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;11924 if (!field_ty.hasRuntimeBits(zcu)) continue;
12153 types[types_len] = try o.lowerType(pt, field_ty);11925 types[types_len] = try o.lowerType(pt, field_ty);
12154 types_len += 1;11926 types_len += 1;
12155 }11927 }
...@@ -12187,6 +11959,7 @@ fn lowerSystemVFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.Fu...@@ -12187,6 +11959,7 @@ fn lowerSystemVFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.Fu
12187 const zcu = pt.zcu;11959 const zcu = pt.zcu;
12188 const ip = &zcu.intern_pool;11960 const ip = &zcu.intern_pool;
12189 const return_type = Type.fromInterned(fn_info.return_type);11961 const return_type = Type.fromInterned(fn_info.return_type);
11962 return_type.assertHasLayout(zcu);
12190 if (isScalar(zcu, return_type)) {11963 if (isScalar(zcu, return_type)) {
12191 return o.lowerType(pt, return_type);11964 return o.lowerType(pt, return_type);
12192 }11965 }
...@@ -12235,9 +12008,7 @@ fn lowerSystemVFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.Fu...@@ -12235,9 +12008,7 @@ fn lowerSystemVFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.Fu
12235 assert(first_non_integer orelse classes.len == types_index);12008 assert(first_non_integer orelse classes.len == types_index);
12236 switch (ip.indexToKey(return_type.toIntern())) {12009 switch (ip.indexToKey(return_type.toIntern())) {
12237 .struct_type => {12010 .struct_type => {
12238 const struct_type = ip.loadStructType(return_type.toIntern());12011 const size = return_type.abiSize(zcu);
12239 assert(struct_type.haveLayout(ip));
12240 const size: u64 = struct_type.sizeUnordered(ip);
12241 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);12012 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
12242 if (size % 8 > 0) {12013 if (size % 8 > 0) {
12243 types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8));12014 types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8));
...@@ -12273,7 +12044,7 @@ const ParamTypeIterator = struct {...@@ -12273,7 +12044,7 @@ const ParamTypeIterator = struct {
12273 i64_array: u8,12044 i64_array: u8,
12274 };12045 };
1227512046
12276 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {12047 fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
12277 if (it.zig_index >= it.fn_info.param_types.len) return null;12048 if (it.zig_index >= it.fn_info.param_types.len) return null;
12278 const ip = &it.pt.zcu.intern_pool;12049 const ip = &it.pt.zcu.intern_pool;
12279 const ty = it.fn_info.param_types.get(ip)[it.zig_index];12050 const ty = it.fn_info.param_types.get(ip)[it.zig_index];
...@@ -12282,7 +12053,7 @@ const ParamTypeIterator = struct {...@@ -12282,7 +12053,7 @@ const ParamTypeIterator = struct {
12282 }12053 }
1228312054
12284 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.12055 /// `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 {
12286 assert(std.meta.eql(it.pt, fg.ng.pt));12057 assert(std.meta.eql(it.pt, fg.ng.pt));
12287 const ip = &it.pt.zcu.intern_pool;12058 const ip = &it.pt.zcu.intern_pool;
12288 if (it.zig_index >= it.fn_info.param_types.len) {12059 if (it.zig_index >= it.fn_info.param_types.len) {
...@@ -12301,7 +12072,7 @@ const ParamTypeIterator = struct {...@@ -12301,7 +12072,7 @@ const ParamTypeIterator = struct {
12301 const zcu = pt.zcu;12072 const zcu = pt.zcu;
12302 const target = zcu.getTarget();12073 const target = zcu.getTarget();
1230312074
12304 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {12075 if (!ty.hasRuntimeBits(zcu)) {
12305 it.zig_index += 1;12076 it.zig_index += 1;
12306 return .no_bits;12077 return .no_bits;
12307 }12078 }
...@@ -12396,7 +12167,7 @@ const ParamTypeIterator = struct {...@@ -12396,7 +12167,7 @@ const ParamTypeIterator = struct {
12396 it.types_len = 0;12167 it.types_len = 0;
12397 for (0..ty.structFieldCount(zcu)) |field_index| {12168 for (0..ty.structFieldCount(zcu)) |field_index| {
12398 const field_ty = ty.fieldType(field_index, zcu);12169 const field_ty = ty.fieldType(field_index, zcu);
12399 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;12170 if (!field_ty.hasRuntimeBits(zcu)) continue;
12400 it.types_buffer[it.types_len] = try it.object.lowerType(pt, field_ty);12171 it.types_buffer[it.types_len] = try it.object.lowerType(pt, field_ty);
12401 it.types_len += 1;12172 it.types_len += 1;
12402 }12173 }
...@@ -12473,6 +12244,7 @@ const ParamTypeIterator = struct {...@@ -12473,6 +12244,7 @@ const ParamTypeIterator = struct {
12473 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {12244 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
12474 const zcu = it.pt.zcu;12245 const zcu = it.pt.zcu;
12475 const ip = &zcu.intern_pool;12246 const ip = &zcu.intern_pool;
12247 ty.assertHasLayout(zcu);
12476 const classes = x86_64_abi.classifySystemV(ty, zcu, zcu.getTarget(), .arg);12248 const classes = x86_64_abi.classifySystemV(ty, zcu, zcu.getTarget(), .arg);
12477 if (classes[0] == .memory) {12249 if (classes[0] == .memory) {
12478 it.zig_index += 1;12250 it.zig_index += 1;
...@@ -12544,9 +12316,7 @@ const ParamTypeIterator = struct {...@@ -12544,9 +12316,7 @@ const ParamTypeIterator = struct {
12544 }12316 }
12545 switch (ip.indexToKey(ty.toIntern())) {12317 switch (ip.indexToKey(ty.toIntern())) {
12546 .struct_type => {12318 .struct_type => {
12547 const struct_type = ip.loadStructType(ty.toIntern());12319 const size = ty.abiSize(zcu);
12548 assert(struct_type.haveLayout(ip));
12549 const size: u64 = struct_type.sizeUnordered(ip);
12550 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);12320 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
12551 if (size % 8 > 0) {12321 if (size % 8 > 0) {
12552 types_buffer[types_index - 1] =12322 types_buffer[types_index - 1] =
...@@ -12720,14 +12490,14 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {...@@ -12720,14 +12490,14 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {
12720 },12490 },
12721 .error_union => {12491 .error_union => {
12722 const payload_ty = ty.errorUnionPayload(zcu);12492 const payload_ty = ty.errorUnionPayload(zcu);
12723 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {12493 if (!payload_ty.hasRuntimeBits(zcu)) {
12724 return false;12494 return false;
12725 }12495 }
12726 return true;12496 return true;
12727 },12497 },
12728 .optional => {12498 .optional => {
12729 const payload_ty = ty.optionalChild(zcu);12499 const payload_ty = ty.optionalChild(zcu);
12730 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {12500 if (!payload_ty.hasRuntimeBits(zcu)) {
12731 return false;12501 return false;
12732 }12502 }
12733 if (ty.optionalReprIsPayload(zcu)) {12503 if (ty.optionalReprIsPayload(zcu)) {
src/codegen/mips/abi.zig+2-2
...@@ -13,7 +13,7 @@ pub const Context = enum { ret, arg };...@@ -13,7 +13,7 @@ pub const Context = enum { ret, arg };
1313
14pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {14pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
15 const target = zcu.getTarget();15 const target = zcu.getTarget();
16 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu));16 std.debug.assert(ty.hasRuntimeBits(zcu));
1717
18 const max_direct_size = target.ptrBitWidth() * 2;18 const max_direct_size = target.ptrBitWidth() * 2;
19 switch (ty.zigTypeTag(zcu)) {19 switch (ty.zigTypeTag(zcu)) {
...@@ -44,7 +44,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -44,7 +44,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
44 return .byval;44 return .byval;
45 },45 },
46 .vector => {46 .vector => {
47 const elem_type = ty.elemType2(zcu);47 const elem_type = ty.childType(zcu);
48 switch (elem_type.zigTypeTag(zcu)) {48 switch (elem_type.zigTypeTag(zcu)) {
49 .bool, .int => {49 .bool, .int => {
50 const bit_size = ty.bitSize(zcu);50 const bit_size = ty.bitSize(zcu);
src/codegen/riscv64/CodeGen.zig+45-58
...@@ -2673,7 +2673,7 @@ fn genBinOp(...@@ -2673,7 +2673,7 @@ fn genBinOp(
2673 defer func.register_manager.unlockReg(tmp_lock);2673 defer func.register_manager.unlockReg(tmp_lock);
26742674
2675 // RISC-V has no immediate mul, so we copy the size to a temporary register2675 // 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);
2677 const elem_size_reg = try func.copyToTmpRegister(Type.u64, .{ .immediate = elem_size });2677 const elem_size_reg = try func.copyToTmpRegister(Type.u64, .{ .immediate = elem_size });
26782678
2679 try func.genBinOp(2679 try func.genBinOp(
...@@ -3257,7 +3257,7 @@ fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {...@@ -3257,7 +3257,7 @@ fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {
3257 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3257 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3258 const result: MCValue = result: {3258 const result: MCValue = result: {
3259 const pl_ty = func.typeOfIndex(inst);3259 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
3262 const opt_mcv = try func.resolveInst(ty_op.operand);3262 const opt_mcv = try func.resolveInst(ty_op.operand);
3263 if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {3263 if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
...@@ -3331,7 +3331,7 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3331,7 +3331,7 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {
3331 break :result .{ .immediate = 0 };3331 break :result .{ .immediate = 0 };
3332 }3332 }
33333333
3334 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3334 if (!payload_ty.hasRuntimeBits(zcu)) {
3335 break :result operand;3335 break :result operand;
3336 }3336 }
33373337
...@@ -3384,7 +3384,7 @@ fn genUnwrapErrUnionPayloadMir(...@@ -3384,7 +3384,7 @@ fn genUnwrapErrUnionPayloadMir(
3384 const payload_ty = err_union_ty.errorUnionPayload(zcu);3384 const payload_ty = err_union_ty.errorUnionPayload(zcu);
33853385
3386 const result: MCValue = result: {3386 const result: MCValue = result: {
3387 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;3387 if (!payload_ty.hasRuntimeBits(zcu)) break :result .none;
33883388
3389 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu));3389 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
3390 switch (err_union) {3390 switch (err_union) {
...@@ -3547,7 +3547,7 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {...@@ -3547,7 +3547,7 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {
3547 const operand = try func.resolveInst(ty_op.operand);3547 const operand = try func.resolveInst(ty_op.operand);
35483548
3549 const result: MCValue = result: {3549 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
3552 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));3552 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
3553 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));3553 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
...@@ -3571,7 +3571,7 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3571,7 +3571,7 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {
3571 const err_ty = eu_ty.errorUnionSet(zcu);3571 const err_ty = eu_ty.errorUnionSet(zcu);
35723572
3573 const result: MCValue = result: {3573 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
3576 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));3576 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
3577 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));3577 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
...@@ -3761,7 +3761,7 @@ fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3761,7 +3761,7 @@ fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void {
37613761
3762 const result: MCValue = result: {3762 const result: MCValue = result: {
3763 const elem_ty = func.typeOfIndex(inst);3763 const elem_ty = func.typeOfIndex(inst);
3764 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;3764 assert(elem_ty.hasRuntimeBits(zcu));
37653765
3766 const slice_ty = func.typeOf(bin_op.lhs);3766 const slice_ty = func.typeOf(bin_op.lhs);
3767 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);3767 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
...@@ -3913,9 +3913,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3913,9 +3913,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void {
3913 const base_ptr_ty = func.typeOf(bin_op.lhs);3913 const base_ptr_ty = func.typeOf(bin_op.lhs);
39143914
3915 const result: MCValue = if (!is_volatile and func.liveness.isUnused(inst)) .unreach else result: {3915 const result: MCValue = if (!is_volatile and func.liveness.isUnused(inst)) .unreach else result: {
3916 const elem_ty = base_ptr_ty.elemType2(zcu);3916 const elem_ty = base_ptr_ty.indexableElem(zcu);
3917 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;3917 assert(elem_ty.hasRuntimeBits(zcu));
3918
3919 const base_ptr_mcv = try func.resolveInst(bin_op.lhs);3918 const base_ptr_mcv = try func.resolveInst(bin_op.lhs);
3920 const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) {3919 const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) {
3921 .register => |reg| func.register_manager.lockRegAssumeUnused(reg),3920 .register => |reg| func.register_manager.lockRegAssumeUnused(reg),
...@@ -4618,7 +4617,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -4618,7 +4617,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
4618 const src_mcv = try func.resolveInst(operand);4617 const src_mcv = try func.resolveInst(operand);
4619 const struct_ty = func.typeOf(operand);4618 const struct_ty = func.typeOf(operand);
4620 const field_ty = struct_ty.fieldType(index, zcu);4619 const field_ty = struct_ty.fieldType(index, zcu);
4621 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;4620 assert(field_ty.hasRuntimeBits(zcu));
46224621
4623 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {4622 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
4624 .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8),4623 .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 {...@@ -5127,7 +5126,6 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
5127 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5126 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5128 const pt = func.pt;5127 const pt = func.pt;
5129 const zcu = pt.zcu;5128 const zcu = pt.zcu;
5130 const ip = &zcu.intern_pool;
51315129
5132 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {5130 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
5133 const lhs_ty = func.typeOf(bin_op.lhs);5131 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 {...@@ -5141,28 +5139,23 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
5141 .optional,5139 .optional,
5142 .@"struct",5140 .@"struct",
5143 => {5141 => {
5144 const int_ty = switch (lhs_ty.zigTypeTag(zcu)) {5142 const int_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) {
5145 .@"enum" => lhs_ty.intTagType(zcu),5143 .@"enum" => lhs_ty.intTagType(zcu),
5146 .int => lhs_ty,5144 .int => lhs_ty,
5147 .bool => Type.u1,5145 .bool => .u1,
5148 .pointer => Type.u64,5146 .pointer => .u64,
5149 .error_set => Type.anyerror,5147 .error_set => .anyerror,
5150 .optional => blk: {5148 .optional => blk: {
5151 const payload_ty = lhs_ty.optionalChild(zcu);5149 const payload_ty = lhs_ty.optionalChild(zcu);
5152 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5150 if (!payload_ty.hasRuntimeBits(zcu)) {
5153 break :blk Type.u1;5151 break :blk .u1;
5154 } else if (lhs_ty.isPtrLikeOptional(zcu)) {5152 } else if (lhs_ty.isPtrLikeOptional(zcu)) {
5155 break :blk Type.u64;5153 break :blk .u64;
5156 } else {5154 } else {
5157 return func.fail("TODO riscv cmp non-pointer optionals", .{});5155 return func.fail("TODO riscv cmp non-pointer optionals", .{});
5158 }5156 }
5159 },5157 },
5160 .@"struct" => blk: {5158 .@"struct", .@"union" => lhs_ty.bitpackBackingInt(zcu),
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 },
5166 else => unreachable,5159 else => unreachable,
5167 };5160 };
51685161
...@@ -5926,8 +5919,7 @@ fn airBr(func: *Func, inst: Air.Inst.Index) !void {...@@ -5926,8 +5919,7 @@ fn airBr(func: *Func, inst: Air.Inst.Index) !void {
5926 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;5919 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
59275920
5928 const block_ty = func.typeOfIndex(br.block_inst);5921 const block_ty = func.typeOfIndex(br.block_inst);
5929 const block_unused =5922 const block_unused = !block_ty.hasRuntimeBits(zcu) or func.liveness.isUnused(br.block_inst);
5930 !block_ty.hasRuntimeBitsIgnoreComptime(zcu) or func.liveness.isUnused(br.block_inst);
5931 const block_tracking = func.inst_tracking.getPtr(br.block_inst).?;5923 const block_tracking = func.inst_tracking.getPtr(br.block_inst).?;
5932 const block_data = func.blocks.getPtr(br.block_inst).?;5924 const block_data = func.blocks.getPtr(br.block_inst).?;
5933 const first_br = block_data.relocs.items.len == 0;5925 const first_br = block_data.relocs.items.len == 0;
...@@ -6150,31 +6142,26 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {...@@ -6150,31 +6142,26 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {
61506142
6151 const zcu = func.pt.zcu;6143 const zcu = func.pt.zcu;
6152 const ip = &zcu.intern_pool;6144 const ip = &zcu.intern_pool;
6153 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;6145 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
6154 const struct_type: Type = .fromInterned(aggregate.ty);6146 const clobbers_ty = clobbers_val.typeOf(zcu);
6155 switch (aggregate.storage) {6147 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
6156 .elems => |elems| for (elems, 0..) |elem, i| {6148 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
6157 switch (elem) {6149 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
6158 .bool_true => {6150 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
6159 const clobber = struct_type.structFieldName(i, zcu).toSlice(ip).?;6151 const limb_bits = @bitSizeOf(std.math.big.Limb);
6160 assert(clobber.len != 0);6152 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
6161 if (std.mem.eql(u8, clobber, "memory")) {6153 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
6162 // nothing really to do6154 0 => continue, // field is false
6163 } else {6155 1 => {}, // field is true
6164 try func.register_manager.getReg(parseRegName(clobber) orelse6156 }
6165 return func.fail("invalid clobber: '{s}'", .{clobber}), null);6157 const clobber = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
6166 }6158 assert(clobber.len != 0);
6167 },6159 if (std.mem.eql(u8, clobber, "memory")) {
6168 .bool_false => continue,6160 // nothing really to do
6169 else => unreachable,6161 } else {
6170 }6162 try func.register_manager.getReg(parseRegName(clobber) orelse
6171 },6163 return func.fail("invalid clobber: '{s}'", .{clobber}), null);
6172 .repeated_elem => |elem| switch (elem) {6164 }
6173 .bool_true => @panic("TODO"),
6174 .bool_false => {},
6175 else => unreachable,
6176 },
6177 .bytes => @panic("TODO"),
6178 }6165 }
61796166
6180 const Label = struct {6167 const Label = struct {
...@@ -8255,7 +8242,7 @@ fn resolveCallingConventionValues(...@@ -8255,7 +8242,7 @@ fn resolveCallingConventionValues(
8255 // Return values8242 // Return values
8256 if (ret_ty.zigTypeTag(zcu) == .noreturn) {8243 if (ret_ty.zigTypeTag(zcu) == .noreturn) {
8257 result.return_value = InstTracking.init(.unreach);8244 result.return_value = InstTracking.init(.unreach);
8258 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {8245 } else if (!ret_ty.hasRuntimeBits(zcu)) {
8259 result.return_value = InstTracking.init(.none);8246 result.return_value = InstTracking.init(.none);
8260 } else {8247 } else {
8261 var ret_tracking: [2]InstTracking = undefined;8248 var ret_tracking: [2]InstTracking = undefined;
...@@ -8306,7 +8293,7 @@ fn resolveCallingConventionValues(...@@ -8306,7 +8293,7 @@ fn resolveCallingConventionValues(
8306 var param_float_reg_i: usize = 0;8293 var param_float_reg_i: usize = 0;
83078294
8308 for (param_types, result.args) |ty, *arg| {8295 for (param_types, result.args) |ty, *arg| {
8309 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {8296 if (!ty.hasRuntimeBits(zcu)) {
8310 assert(cc == .auto);8297 assert(cc == .auto);
8311 arg.* = .none;8298 arg.* = .none;
8312 continue;8299 continue;
...@@ -8421,10 +8408,10 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {...@@ -8421,10 +8408,10 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {
8421}8408}
84228409
8423pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {8410pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
8424 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;8411 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
8425 const payload_align = payload_ty.abiAlignment(zcu);8412 const payload_align = payload_ty.abiAlignment(zcu);
8426 const error_align = Type.anyerror.abiAlignment(zcu);8413 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)) {
8428 return 0;8415 return 0;
8429 } else {8416 } else {
8430 return payload_align.forward(Type.anyerror.abiSize(zcu));8417 return payload_align.forward(Type.anyerror.abiSize(zcu));
...@@ -8432,10 +8419,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {...@@ -8432,10 +8419,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
8432}8419}
84338420
8434pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {8421pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
8435 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;8422 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
8436 const payload_align = payload_ty.abiAlignment(zcu);8423 const payload_align = payload_ty.abiAlignment(zcu);
8437 const error_align = Type.anyerror.abiAlignment(zcu);8424 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)) {
8439 return error_align.forward(payload_ty.abiSize(zcu));8426 return error_align.forward(payload_ty.abiSize(zcu));
8440 } else {8427 } else {
8441 return 0;8428 return 0;
src/codegen/riscv64/abi.zig+2-2
...@@ -11,7 +11,7 @@ pub const Class = enum { memory, byval, integer, double_integer, fields };...@@ -11,7 +11,7 @@ pub const Class = enum { memory, byval, integer, double_integer, fields };
1111
12pub fn classifyType(ty: Type, zcu: *Zcu) Class {12pub fn classifyType(ty: Type, zcu: *Zcu) Class {
13 const target = zcu.getTarget();13 const target = zcu.getTarget();
14 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu));14 std.debug.assert(ty.hasRuntimeBits(zcu));
1515
16 const max_byval_size = target.ptrBitWidth() * 2;16 const max_byval_size = target.ptrBitWidth() * 2;
17 switch (ty.zigTypeTag(zcu)) {17 switch (ty.zigTypeTag(zcu)) {
...@@ -27,7 +27,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {...@@ -27,7 +27,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {
27 var field_count: usize = 0;27 var field_count: usize = 0;
28 for (0..ty.structFieldCount(zcu)) |field_index| {28 for (0..ty.structFieldCount(zcu)) |field_index| {
29 const field_ty = ty.fieldType(field_index, zcu);29 const field_ty = ty.fieldType(field_index, zcu);
30 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;30 if (!field_ty.hasRuntimeBits(zcu)) continue;
31 if (field_ty.isRuntimeFloat())31 if (field_ty.isRuntimeFloat())
32 any_fp = true32 any_fp = true
33 else if (!field_ty.isAbiInt(zcu))33 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 {...@@ -1102,7 +1102,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
1102fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {1102fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
1103 try self.blocks.putNoClobber(self.gpa, inst, .{1103 try self.blocks.putNoClobber(self.gpa, inst, .{
1104 // A block is a setup to be able to jump to the end.1104 // A block is a setup to be able to jump to the end.
1105 .relocs = .{},1105 .relocs = .empty,
1106 // It also acts as a receptacle for break operands.1106 // It also acts as a receptacle for break operands.
1107 // Here we use `MCValue.none` to represent a null value so that the first1107 // Here we use `MCValue.none` to represent a null value so that the first
1108 // break instruction will choose a MCValue for the block result and overwrite1108 // 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 {...@@ -1376,19 +1376,19 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1376 const rhs = try self.resolveInst(bin_op.rhs);1376 const rhs = try self.resolveInst(bin_op.rhs);
1377 const lhs_ty = self.typeOf(bin_op.lhs);1377 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)) {
1380 .vector => unreachable, // Handled by cmp_vector.1380 .vector => unreachable, // Handled by cmp_vector.
1381 .@"enum" => lhs_ty.intTagType(zcu),1381 .@"enum" => lhs_ty.intTagType(zcu),
1382 .int => lhs_ty,1382 .int => lhs_ty,
1383 .bool => Type.u1,1383 .bool => .u1,
1384 .pointer => Type.usize,1384 .pointer => .usize,
1385 .error_set => Type.u16,1385 .error_set => .u16,
1386 .optional => blk: {1386 .optional => blk: {
1387 const payload_ty = lhs_ty.optionalChild(zcu);1387 const payload_ty = lhs_ty.optionalChild(zcu);
1388 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {1388 if (!payload_ty.hasRuntimeBits(zcu)) {
1389 break :blk Type.u1;1389 break :blk .u1;
1390 } else if (lhs_ty.isPtrLikeOptional(zcu)) {1390 } else if (lhs_ty.isPtrLikeOptional(zcu)) {
1391 break :blk Type.usize;1391 break :blk .usize;
1392 } else {1392 } else {
1393 return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{});1393 return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{});
1394 }1394 }
...@@ -3452,8 +3452,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)...@@ -3452,8 +3452,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
3452 if (err_ty.errorSetIsEmpty(zcu)) {3452 if (err_ty.errorSetIsEmpty(zcu)) {
3453 return error_union_mcv;3453 return error_union_mcv;
3454 }3454 }
3455 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3455 if (!payload_ty.hasRuntimeBits(zcu)) {
3456 return MCValue.none;3456 return .none;
3457 }3457 }
34583458
3459 const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu));3459 const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
...@@ -4481,7 +4481,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -4481,7 +4481,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
4481 const ty = self.typeOf(ref);4481 const ty = self.typeOf(ref);
44824482
4483 // If the type has no codegen bits, no need to store it.4483 // 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
4486 if (ref.toIndex()) |inst| {4486 if (ref.toIndex()) |inst| {
4487 return self.getResolvedInstValue(inst);4487 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 {...@@ -208,7 +208,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
208 try cg.args.ensureUnusedCapacity(gpa, fn_info.param_types.len);208 try cg.args.ensureUnusedCapacity(gpa, fn_info.param_types.len);
209 for (fn_info.param_types.get(ip)) |param_ty_index| {209 for (fn_info.param_types.get(ip)) |param_ty_index| {
210 const param_ty: Type = .fromInterned(param_ty_index);210 const param_ty: Type = .fromInterned(param_ty_index);
211 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;211 if (!param_ty.hasRuntimeBits(zcu)) continue;
212212
213 const param_type_id = try cg.resolveType(param_ty, .direct);213 const param_type_id = try cg.resolveType(param_ty, .direct);
214 const arg_result_id = cg.module.allocId();214 const arg_result_id = cg.module.allocId();
...@@ -689,7 +689,7 @@ fn constInt(cg: *CodeGen, ty: Type, value: anytype) !Id {...@@ -689,7 +689,7 @@ fn constInt(cg: *CodeGen, ty: Type, value: anytype) !Id {
689 .comptime_int => if (value < 0) .signed else .unsigned,689 .comptime_int => if (value < 0) .signed else .unsigned,
690 else => unreachable,690 else => unreachable,
691 };691 };
692 if (@sizeOf(@TypeOf(value)) >= 4 and big_int) {692 if (@TypeOf(value) != comptime_int and @sizeOf(@TypeOf(value)) >= 4 and big_int) {
693 const value64: u64 = switch (signedness) {693 const value64: u64 = switch (signedness) {
694 .signed => @bitCast(@as(i64, @intCast(value))),694 .signed => @bitCast(@as(i64, @intCast(value))),
695 .unsigned => @as(u64, @intCast(value)),695 .unsigned => @as(u64, @intCast(value)),
...@@ -814,14 +814,11 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {...@@ -814,14 +814,11 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
814 .@"extern",814 .@"extern",
815 .func,815 .func,
816 .enum_literal,816 .enum_literal,
817 .empty_enum_value,
818 => unreachable, // non-runtime values817 => unreachable, // non-runtime values
819818
820 .simple_value => |simple_value| switch (simple_value) {819 .simple_value => |simple_value| switch (simple_value) {
821 .undefined,
822 .void,820 .void,
823 .null,821 .null,
824 .empty_tuple,
825 .@"unreachable",822 .@"unreachable",
826 => unreachable, // non-runtime values823 => unreachable, // non-runtime values
827824
...@@ -887,7 +884,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {...@@ -887,7 +884,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
887 return try cg.constructComposite(comp_ty_id, &constituents);884 return try cg.constructComposite(comp_ty_id, &constituents);
888 },885 },
889 .enum_tag => {886 .enum_tag => {
890 const int_val = try val.intFromEnum(ty, pt);887 const int_val = val.intFromEnum(zcu);
891 const int_ty = ty.intTagType(zcu);888 const int_ty = ty.intTagType(zcu);
892 break :cache try cg.constant(int_ty, int_val, repr);889 break :cache try cg.constant(int_ty, int_val, repr);
893 },890 },
...@@ -962,18 +959,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {...@@ -962,18 +959,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
962 },959 },
963 .struct_type => {960 .struct_type => {
964 const struct_type = zcu.typeToStruct(ty).?;961 const struct_type = zcu.typeToStruct(ty).?;
965962 assert(struct_type.layout != .@"packed"); // packed structs use `bitpack`
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 }
977963
978 var types = std.array_list.Managed(Type).init(gpa);964 var types = std.array_list.Managed(Type).init(gpa);
979 defer types.deinit();965 defer types.deinit();
...@@ -984,7 +970,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {...@@ -984,7 +970,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
984 var it = struct_type.iterateRuntimeOrder(ip);970 var it = struct_type.iterateRuntimeOrder(ip);
985 while (it.next()) |field_index| {971 while (it.next()) |field_index| {
986 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);972 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)) {
988 // This is a zero-bit field - we only needed it for the alignment.974 // This is a zero-bit field - we only needed it for the alignment.
989 continue;975 continue;
990 }976 }
...@@ -1004,20 +990,24 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {...@@ -1004,20 +990,24 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
1004 else => unreachable,990 else => unreachable,
1005 },991 },
1006 .un => |un| {992 .un => |un| {
993 assert(ty.containerLayout(zcu) != .@"packed"); // packed unions use `bitpack`
1007 if (un.tag == .none) {994 if (un.tag == .none) {
1008 assert(ty.containerLayout(zcu) == .@"packed"); // TODO995 @panic("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));
1011 }996 }
1012 const active_field = ty.unionTagFieldIndex(.fromInterned(un.tag), zcu).?;997 const active_field = ty.unionTagFieldIndex(.fromInterned(un.tag), zcu).?;
1013 const union_obj = zcu.typeToUnion(ty).?;998 const union_obj = zcu.typeToUnion(ty).?;
1014 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[active_field]);999 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))
1016 try cg.constant(field_ty, .fromInterned(un.val), .direct)1001 try cg.constant(field_ty, .fromInterned(un.val), .direct)
1017 else1002 else
1018 null;1003 null;
1019 return try cg.unionInit(ty, active_field, payload);1004 return try cg.unionInit(ty, active_field, payload);
1020 },1005 },
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
1021 .memoized_call => unreachable,1011 .memoized_call => unreachable,
1022 }1012 }
1023 };1013 };
...@@ -1041,7 +1031,7 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id {...@@ -1041,7 +1031,7 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id {
1041 var arena = std.heap.ArenaAllocator.init(gpa);1031 var arena = std.heap.ArenaAllocator.init(gpa);
1042 defer arena.deinit();1032 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);
1045 return cg.derivePtr(derivation);1035 return cg.derivePtr(derivation);
1046}1036}
10471037
...@@ -1150,7 +1140,7 @@ fn constantUavRef(...@@ -1150,7 +1140,7 @@ fn constantUavRef(
1150 }1140 }
11511141
1152 // const is_fn_body = decl_ty.zigTypeTag(zcu) == .@"fn";1142 // const is_fn_body = decl_ty.zigTypeTag(zcu) == .@"fn";
1153 if (!uav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {1143 if (!uav_ty.hasRuntimeBits(zcu)) {
1154 // Pointer to nothing - return undefined1144 // Pointer to nothing - return undefined
1155 return cg.module.constUndef(ty_id);1145 return cg.module.constUndef(ty_id);
1156 }1146 }
...@@ -1196,7 +1186,7 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id {...@@ -1196,7 +1186,7 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id {
1196 },1186 },
1197 }1187 }
11981188
1199 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {1189 if (!nav_ty.hasRuntimeBits(zcu)) {
1200 // Pointer to nothing - return undefined.1190 // Pointer to nothing - return undefined.
1201 return cg.module.constUndef(ty_id);1191 return cg.module.constUndef(ty_id);
1202 }1192 }
...@@ -1258,17 +1248,16 @@ fn resolveTypeName(cg: *CodeGen, ty: Type) ![]const u8 {...@@ -1258,17 +1248,16 @@ fn resolveTypeName(cg: *CodeGen, ty: Type) ![]const u8 {
1258fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {1248fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
1259 const gpa = cg.module.gpa;1249 const gpa = cg.module.gpa;
1260 const zcu = cg.module.zcu;1250 const zcu = cg.module.zcu;
1261 const ip = &zcu.intern_pool;
1262 const union_obj = zcu.typeToUnion(ty).?;1251 const union_obj = zcu.typeToUnion(ty).?;
12631252
1264 if (union_obj.flagsUnordered(ip).layout == .@"packed") {1253 if (union_obj.layout == .@"packed") {
1265 return try cg.module.intType(.unsigned, @intCast(ty.bitSize(zcu)));1254 return try cg.module.intType(.unsigned, @intCast(ty.bitSize(zcu)));
1266 }1255 }
12671256
1268 const layout = cg.unionLayout(ty);1257 const layout = cg.unionLayout(ty);
1269 if (!layout.has_payload) {1258 if (!layout.has_payload) {
1270 // No payload, so represent this as just the tag type.1259 // 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);
1272 }1261 }
12731262
1274 var member_types: [4]Id = undefined;1263 var member_types: [4]Id = undefined;
...@@ -1277,7 +1266,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {...@@ -1277,7 +1266,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
1277 const u8_ty_id = try cg.resolveType(.u8, .direct);1266 const u8_ty_id = try cg.resolveType(.u8, .direct);
12781267
1279 if (layout.tag_size != 0) {1268 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);
1281 member_types[layout.tag_index] = tag_ty_id;1270 member_types[layout.tag_index] = tag_ty_id;
1282 member_names[layout.tag_index] = "(tag)";1271 member_names[layout.tag_index] = "(tag)";
1283 }1272 }
...@@ -1318,7 +1307,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {...@@ -1318,7 +1307,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
13181307
1319fn resolveFnReturnType(cg: *CodeGen, ret_ty: Type) !Id {1308fn resolveFnReturnType(cg: *CodeGen, ret_ty: Type) !Id {
1320 const zcu = cg.module.zcu;1309 const zcu = cg.module.zcu;
1321 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {1310 if (!ret_ty.hasRuntimeBits(zcu)) {
1322 // If the return type is an error set or an error union, then we make this1311 // If the return type is an error set or an error union, then we make this
1323 // anyerror return type instead, so that it can be coerced into a function1312 // anyerror return type instead, so that it can be coerced into a function
1324 // pointer type which has anyerror as the return type.1313 // pointer type which has anyerror as the return type.
...@@ -1392,7 +1381,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {...@@ -1392,7 +1381,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
1392 return cg.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)});1381 return cg.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)});
1393 };1382 };
13941383
1395 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {1384 if (!elem_ty.hasRuntimeBits(zcu)) {
1396 assert(repr == .indirect);1385 assert(repr == .indirect);
1397 if (target.os.tag != .opencl) return cg.fail("cannot generate opaque type", .{});1386 if (target.os.tag != .opencl) return cg.fail("cannot generate opaque type", .{});
1398 return try cg.module.opaqueType("zero-sized-array");1387 return try cg.module.opaqueType("zero-sized-array");
...@@ -1456,7 +1445,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {...@@ -1456,7 +1445,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
1456 var param_index: usize = 0;1445 var param_index: usize = 0;
1457 for (fn_info.param_types.get(ip)) |param_ty_index| {1446 for (fn_info.param_types.get(ip)) |param_ty_index| {
1458 const param_ty: Type = .fromInterned(param_ty_index);1447 const param_ty: Type = .fromInterned(param_ty_index);
1459 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1448 if (!param_ty.hasRuntimeBits(zcu)) continue;
14601449
1461 param_ty_ids[param_index] = try cg.resolveType(param_ty, .direct);1450 param_ty_ids[param_index] = try cg.resolveType(param_ty, .direct);
1462 param_index += 1;1451 param_index += 1;
...@@ -1521,7 +1510,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {...@@ -1521,7 +1510,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
1521 };1510 };
15221511
1523 if (struct_type.layout == .@"packed") {1512 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);
1525 }1514 }
15261515
1527 var member_types = std.array_list.Managed(Id).init(gpa);1516 var member_types = std.array_list.Managed(Id).init(gpa);
...@@ -1536,9 +1525,9 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {...@@ -1536,9 +1525,9 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
1536 var it = struct_type.iterateRuntimeOrder(ip);1525 var it = struct_type.iterateRuntimeOrder(ip);
1537 while (it.next()) |field_index| {1526 while (it.next()) |field_index| {
1538 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);1527 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];
1542 try member_types.append(try cg.resolveType(field_ty, .indirect));1531 try member_types.append(try cg.resolveType(field_ty, .indirect));
1543 try member_names.append(field_name.toSlice(ip));1532 try member_names.append(field_name.toSlice(ip));
1544 try member_offsets.append(@intCast(ty.structFieldOffset(field_index, zcu)));1533 try member_offsets.append(@intCast(ty.structFieldOffset(field_index, zcu)));
...@@ -1559,7 +1548,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {...@@ -1559,7 +1548,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
1559 },1548 },
1560 .optional => {1549 .optional => {
1561 const payload_ty = ty.optionalChild(zcu);1550 const payload_ty = ty.optionalChild(zcu);
1562 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {1551 if (!payload_ty.hasRuntimeBits(zcu)) {
1563 // Just use a bool.1552 // Just use a bool.
1564 // Note: Always generate the bool with indirect format, to save on some sanity1553 // Note: Always generate the bool with indirect format, to save on some sanity
1565 // Perform the conversion to a direct bool when the field is extracted.1554 // Perform the conversion to a direct bool when the field is extracted.
...@@ -1656,7 +1645,7 @@ fn errorUnionLayout(cg: *CodeGen, payload_ty: Type) ErrorUnionLayout {...@@ -1656,7 +1645,7 @@ fn errorUnionLayout(cg: *CodeGen, payload_ty: Type) ErrorUnionLayout {
16561645
1657 const error_first = error_align.compare(.gt, payload_align);1646 const error_first = error_align.compare(.gt, payload_align);
1658 return .{1647 return .{
1659 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu),1648 .payload_has_bits = payload_ty.hasRuntimeBits(zcu),
1660 .error_first = error_first,1649 .error_first = error_first,
1661 };1650 };
1662}1651}
...@@ -3727,7 +3716,6 @@ fn cmp(...@@ -3727,7 +3716,6 @@ fn cmp(
3727 const gpa = cg.module.gpa;3716 const gpa = cg.module.gpa;
3728 const pt = cg.pt;3717 const pt = cg.pt;
3729 const zcu = cg.module.zcu;3718 const zcu = cg.module.zcu;
3730 const ip = &zcu.intern_pool;
3731 const scalar_ty = lhs.ty.scalarType(zcu);3719 const scalar_ty = lhs.ty.scalarType(zcu);
3732 const is_vector = lhs.ty.isVector(zcu);3720 const is_vector = lhs.ty.isVector(zcu);
37333721
...@@ -3740,7 +3728,7 @@ fn cmp(...@@ -3740,7 +3728,7 @@ fn cmp(
3740 },3728 },
3741 .@"struct" => {3729 .@"struct" => {
3742 const struct_ty = zcu.typeToPackedStruct(scalar_ty).?;3730 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);
3744 return try cg.cmp(op, lhs.pun(ty), rhs.pun(ty));3732 return try cg.cmp(op, lhs.pun(ty), rhs.pun(ty));
3745 },3733 },
3746 .error_set => {3734 .error_set => {
...@@ -3781,7 +3769,7 @@ fn cmp(...@@ -3781,7 +3769,7 @@ fn cmp(
37813769
3782 const payload_ty = ty.optionalChild(zcu);3770 const payload_ty = ty.optionalChild(zcu);
3783 if (ty.optionalReprIsPayload(zcu)) {3771 if (ty.optionalReprIsPayload(zcu)) {
3784 assert(payload_ty.hasRuntimeBitsIgnoreComptime(zcu));3772 assert(payload_ty.hasRuntimeBits(zcu));
3785 assert(!payload_ty.isSlice(zcu));3773 assert(!payload_ty.isSlice(zcu));
37863774
3787 return try cg.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty));3775 return try cg.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty));
...@@ -3790,12 +3778,12 @@ fn cmp(...@@ -3790,12 +3778,12 @@ fn cmp(
3790 const lhs_id = try lhs.materialize(cg);3778 const lhs_id = try lhs.materialize(cg);
3791 const rhs_id = try rhs.materialize(cg);3779 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))
3794 try cg.extractField(.bool, lhs_id, 1)3782 try cg.extractField(.bool, lhs_id, 1)
3795 else3783 else
3796 try cg.convertToDirect(.bool, lhs_id);3784 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))
3799 try cg.extractField(.bool, rhs_id, 1)3787 try cg.extractField(.bool, rhs_id, 1)
3800 else3788 else
3801 try cg.convertToDirect(.bool, rhs_id);3789 try cg.convertToDirect(.bool, rhs_id);
...@@ -3803,7 +3791,7 @@ fn cmp(...@@ -3803,7 +3791,7 @@ fn cmp(
3803 const lhs_valid: Temporary = .init(.bool, lhs_valid_id);3791 const lhs_valid: Temporary = .init(.bool, lhs_valid_id);
3804 const rhs_valid: Temporary = .init(.bool, rhs_valid_id);3792 const rhs_valid: Temporary = .init(.bool, rhs_valid_id);
38053793
3806 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3794 if (!payload_ty.hasRuntimeBits(zcu)) {
3807 return try cg.cmp(op, lhs_valid, rhs_valid);3795 return try cg.cmp(op, lhs_valid, rhs_valid);
3808 }3796 }
38093797
...@@ -4141,7 +4129,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -4141,7 +4129,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4141 const array_ptr_id = try cg.resolve(ty_op.operand);4129 const array_ptr_id = try cg.resolve(ty_op.operand);
4142 const len_id = try cg.constInt(.usize, array_ty.arrayLen(zcu));4130 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))
4145 // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type.4133 // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type.
4146 try cg.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id)4134 try cg.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id)
4147 else4135 else
...@@ -4177,12 +4165,12 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -4177,12 +4165,12 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4177 .@"struct" => {4165 .@"struct" => {
4178 if (zcu.typeToPackedStruct(result_ty)) |struct_type| {4166 if (zcu.typeToPackedStruct(result_ty)) |struct_type| {
4179 comptime assert(Type.packed_struct_layout_version == 2);4167 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);
4181 var running_int_id = try cg.constInt(backing_int_ty, 0);4169 var running_int_id = try cg.constInt(backing_int_ty, 0);
4182 var running_bits: u16 = 0;4170 var running_bits: u16 = 0;
4183 for (struct_type.field_types.get(ip), elements) |field_ty_ip, element| {4171 for (struct_type.field_types.get(ip), elements) |field_ty_ip, element| {
4184 const field_ty: Type = .fromInterned(field_ty_ip);4172 const field_ty: Type = .fromInterned(field_ty_ip);
4185 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;4173 if (!field_ty.hasRuntimeBits(zcu)) continue;
4186 const field_id = try cg.resolve(element);4174 const field_id = try cg.resolve(element);
4187 const ty_bit_size: u16 = @intCast(field_ty.bitSize(zcu));4175 const ty_bit_size: u16 = @intCast(field_ty.bitSize(zcu));
4188 const field_int_ty = try cg.pt.intType(.unsigned, ty_bit_size);4176 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 {...@@ -4242,7 +4230,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4242 const field_index = it.next().?;4230 const field_index = it.next().?;
4243 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;4231 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
4244 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);4232 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
4247 const id = try cg.resolve(element);4235 const id = try cg.resolve(element);
4248 types[index] = field_ty;4236 types[index] = field_ty;
...@@ -4381,7 +4369,7 @@ fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -4381,7 +4369,7 @@ fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4381fn ptrElemPtr(cg: *CodeGen, ptr_ty: Type, ptr_id: Id, index_id: Id) !Id {4369fn ptrElemPtr(cg: *CodeGen, ptr_ty: Type, ptr_id: Id, index_id: Id) !Id {
4382 const zcu = cg.module.zcu;4370 const zcu = cg.module.zcu;
4383 // Construct new pointer type for the resulting pointer4371 // 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);
4385 const elem_ty_id = try cg.resolveType(elem_ty, .indirect);4373 const elem_ty_id = try cg.resolveType(elem_ty, .indirect);
4386 const elem_ptr_ty_id = try cg.module.ptrType(elem_ty_id, cg.module.storageClass(ptr_ty.ptrAddressSpace(zcu)));4374 const elem_ptr_ty_id = try cg.module.ptrType(elem_ty_id, cg.module.storageClass(ptr_ty.ptrAddressSpace(zcu)));
4387 if (ptr_ty.isSinglePointer(zcu)) {4375 if (ptr_ty.isSinglePointer(zcu)) {
...@@ -4402,10 +4390,7 @@ fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -4402,10 +4390,7 @@ fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4402 const elem_ty = src_ptr_ty.childType(zcu);4390 const elem_ty = src_ptr_ty.childType(zcu);
4403 const ptr_id = try cg.resolve(bin_op.lhs);4391 const ptr_id = try cg.resolve(bin_op.lhs);
44044392
4405 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4393 assert(elem_ty.hasRuntimeBits(zcu));
4406 const dst_ptr_ty = cg.typeOfIndex(inst);
4407 return try cg.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id);
4408 }
44094394
4410 const index_id = try cg.resolve(bin_op.rhs);4395 const index_id = try cg.resolve(bin_op.rhs);
4411 return try cg.ptrElemPtr(src_ptr_ty, ptr_id, index_id);4396 return try cg.ptrElemPtr(src_ptr_ty, ptr_id, index_id);
...@@ -4483,7 +4468,7 @@ fn airSetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) !void {...@@ -4483,7 +4468,7 @@ fn airSetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) !void {
44834468
4484 if (layout.tag_size == 0) return;4469 if (layout.tag_size == 0) return;
44854470
4486 const tag_ty = un_ty.unionTagTypeSafety(zcu).?;4471 const tag_ty = un_ty.unionTagTypeRuntime(zcu).?;
4487 const tag_ty_id = try cg.resolveType(tag_ty, .indirect);4472 const tag_ty_id = try cg.resolveType(tag_ty, .indirect);
4488 const tag_ptr_ty_id = try cg.module.ptrType(tag_ty_id, cg.module.storageClass(un_ptr_ty.ptrAddressSpace(zcu)));4473 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 {...@@ -4509,7 +4494,7 @@ fn airGetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4509 const union_handle = try cg.resolve(ty_op.operand);4494 const union_handle = try cg.resolve(ty_op.operand);
4510 if (!layout.has_payload) return union_handle;4495 if (!layout.has_payload) return union_handle;
45114496
4512 const tag_ty = un_ty.unionTagTypeSafety(zcu).?;4497 const tag_ty = un_ty.unionTagTypeRuntime(zcu).?;
4513 return try cg.extractField(tag_ty, union_handle, layout.tag_index);4498 return try cg.extractField(tag_ty, union_handle, layout.tag_index);
4514}4499}
45154500
...@@ -4529,39 +4514,16 @@ fn unionInit(...@@ -4529,39 +4514,16 @@ fn unionInit(
4529 const zcu = cg.module.zcu;4514 const zcu = cg.module.zcu;
4530 const ip = &zcu.intern_pool;4515 const ip = &zcu.intern_pool;
4531 const union_ty = zcu.typeToUnion(ty).?;4516 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
4534 const layout = cg.unionLayout(ty);4519 const layout = cg.unionLayout(ty);
4535 const payload_ty: Type = .fromInterned(union_ty.field_types.get(ip)[active_field]);4520 const payload_ty: Type = .fromInterned(union_ty.field_types.get(ip)[active_field]);
45364521
4537 if (union_ty.flagsUnordered(ip).layout == .@"packed") {4522 assert(union_ty.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 }
45614523
4562 const tag_int = if (layout.tag_size != 0) blk: {4524 const tag_int = if (layout.tag_size != 0) blk: {
4563 const tag_val = try pt.enumValueFieldIndex(tag_ty, active_field);4525 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);
4565 break :blk tag_int_val.toUnsignedInt(zcu);4527 break :blk tag_int_val.toUnsignedInt(zcu);
4566 } else 0;4528 } else 0;
45674529
...@@ -4580,7 +4542,7 @@ fn unionInit(...@@ -4580,7 +4542,7 @@ fn unionInit(
4580 try cg.store(tag_ty, ptr_id, tag_id, .{});4542 try cg.store(tag_ty, ptr_id, tag_id, .{});
4581 }4543 }
45824544
4583 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4545 if (payload_ty.hasRuntimeBits(zcu)) {
4584 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);4546 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);
4585 const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, .function);4547 const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, .function);
4586 const pl_ptr_id = try cg.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index});4548 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 {...@@ -4616,7 +4578,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
46164578
4617 const union_obj = zcu.typeToUnion(ty).?;4579 const union_obj = zcu.typeToUnion(ty).?;
4618 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[extra.field_index]);4580 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))
4620 try cg.resolve(extra.init)4582 try cg.resolve(extra.init)
4621 else4583 else
4622 null;4584 null;
...@@ -4634,7 +4596,7 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -4634,7 +4596,7 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
4634 const field_index = struct_field.field_index;4596 const field_index = struct_field.field_index;
4635 const field_ty = object_ty.fieldType(field_index, zcu);4597 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
4639 switch (object_ty.zigTypeTag(zcu)) {4601 switch (object_ty.zigTypeTag(zcu)) {
4640 .@"struct" => switch (object_ty.containerLayout(zcu)) {4602 .@"struct" => switch (object_ty.containerLayout(zcu)) {
...@@ -4776,33 +4738,36 @@ fn structFieldPtr(...@@ -4776,33 +4738,36 @@ fn structFieldPtr(
4776 },4738 },
4777 .@"struct" => switch (object_ty.containerLayout(zcu)) {4739 .@"struct" => switch (object_ty.containerLayout(zcu)) {
4778 .@"packed" => return cg.todo("implement field access for packed structs", .{}),4740 .@"packed" => return cg.todo("implement field access for packed structs", .{}),
4779 else => {4741 .auto, .@"extern" => {
4780 return try cg.accessChain(result_ty_id, object_ptr, &.{field_index});4742 return try cg.accessChain(result_ty_id, object_ptr, &.{field_index});
4781 },4743 },
4782 },4744 },
4783 .@"union" => {4745 .@"union" => switch (object_ty.containerLayout(zcu)) {
4784 const layout = cg.unionLayout(object_ty);4746 .@"packed" => return cg.todo("implement field access for packed unions", .{}),
4785 if (!layout.has_payload) {4747 .auto, .@"extern" => {
4786 // Asked to get a pointer to a zero-sized field. Just lower this4748 const layout = cg.unionLayout(object_ty);
4787 // to undefined, there is no reason to make it be a valid pointer.4749 if (!layout.has_payload) {
4788 return try cg.module.constUndef(result_ty_id);4750 // Asked to get a pointer to a zero-sized field. Just lower this
4789 }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));4755 const storage_class = cg.module.storageClass(object_ptr_ty.ptrAddressSpace(zcu));
4792 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);4756 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);4757 const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, storage_class);
4794 const pl_ptr_id = blk: {4758 const pl_ptr_id = blk: {
4795 if (object_ty.containerLayout(zcu) == .@"packed") break :blk object_ptr;4759 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});4760 break :blk try cg.accessChain(pl_ptr_ty_id, object_ptr, &.{layout.payload_index});
4797 };4761 };
47984762
4799 const active_pl_ptr_id = cg.module.allocId();4763 const active_pl_ptr_id = cg.module.allocId();
4800 try cg.body.emit(cg.module.gpa, .OpBitcast, .{4764 try cg.body.emit(cg.module.gpa, .OpBitcast, .{
4801 .id_result_type = result_ty_id,4765 .id_result_type = result_ty_id,
4802 .id_result = active_pl_ptr_id,4766 .id_result = active_pl_ptr_id,
4803 .operand = pl_ptr_id,4767 .operand = pl_ptr_id,
4804 });4768 });
4805 return active_pl_ptr_id;4769 return active_pl_ptr_id;
4770 },
4806 },4771 },
4807 else => unreachable,4772 else => unreachable,
4808 }4773 }
...@@ -5028,7 +4993,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -5028,7 +4993,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)
5028 const gpa = cg.module.gpa;4993 const gpa = cg.module.gpa;
5029 const zcu = cg.module.zcu;4994 const zcu = cg.module.zcu;
5030 const ty = cg.typeOfIndex(inst);4995 const ty = cg.typeOfIndex(inst);
5031 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu);4996 const have_block_result = ty.hasRuntimeBits(zcu);
50324997
5033 const cf = switch (cg.control_flow) {4998 const cf = switch (cg.control_flow) {
5034 .structured => |*cf| cf,4999 .structured => |*cf| cf,
...@@ -5166,7 +5131,7 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5166,7 +5131,7 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
51665131
5167 switch (cg.control_flow) {5132 switch (cg.control_flow) {
5168 .structured => |*cf| {5133 .structured => |*cf| {
5169 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {5134 if (operand_ty.hasRuntimeBits(zcu)) {
5170 const operand_id = try cg.resolve(br.operand);5135 const operand_id = try cg.resolve(br.operand);
5171 const block_result_var_id = cf.block_results.get(br.block_inst).?;5136 const block_result_var_id = cf.block_results.get(br.block_inst).?;
5172 try cg.store(operand_ty, block_result_var_id, operand_id, .{});5137 try cg.store(operand_ty, block_result_var_id, operand_id, .{});
...@@ -5177,7 +5142,7 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5177,7 +5142,7 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
5177 },5142 },
5178 .unstructured => |cf| {5143 .unstructured => |cf| {
5179 const block = cf.blocks.get(br.block_inst).?;5144 const block = cf.blocks.get(br.block_inst).?;
5180 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {5145 if (operand_ty.hasRuntimeBits(zcu)) {
5181 const operand_id = try cg.resolve(br.operand);5146 const operand_id = try cg.resolve(br.operand);
5182 // block_label should not be undefined here, lest there5147 // block_label should not be undefined here, lest there
5183 // is a br or br_void in the function's body.5148 // is a br or br_void in the function's body.
...@@ -5335,7 +5300,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5335,7 +5300,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) !void {
5335 const zcu = cg.module.zcu;5300 const zcu = cg.module.zcu;
5336 const operand = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5301 const operand = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5337 const ret_ty = cg.typeOf(operand);5302 const ret_ty = cg.typeOf(operand);
5338 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5303 if (!ret_ty.hasRuntimeBits(zcu)) {
5339 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;5304 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
5340 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {5305 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
5341 // Functions with an empty error set are emitted with an error code5306 // 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 {...@@ -5359,7 +5324,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) !void {
5359 const ptr_ty = cg.typeOf(un_op);5324 const ptr_ty = cg.typeOf(un_op);
5360 const ret_ty = ptr_ty.childType(zcu);5325 const ret_ty = ptr_ty.childType(zcu);
53615326
5362 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5327 if (!ret_ty.hasRuntimeBits(zcu)) {
5363 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;5328 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
5364 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {5329 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
5365 // Functions with an empty error set are emitted with an error code5330 // 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 {...@@ -5576,7 +5541,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum {
55765541
5577 const is_non_null_id = blk: {5542 const is_non_null_id = blk: {
5578 if (is_pointer) {5543 if (is_pointer) {
5579 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5544 if (payload_ty.hasRuntimeBits(zcu)) {
5580 const storage_class = cg.module.storageClass(operand_ty.ptrAddressSpace(zcu));5545 const storage_class = cg.module.storageClass(operand_ty.ptrAddressSpace(zcu));
5581 const bool_indirect_ty_id = try cg.resolveType(.bool, .indirect);5546 const bool_indirect_ty_id = try cg.resolveType(.bool, .indirect);
5582 const bool_ptr_ty_id = try cg.module.ptrType(bool_indirect_ty_id, storage_class);5547 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 {...@@ -5587,7 +5552,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum {
5587 break :blk try cg.load(.bool, operand_id, .{});5552 break :blk try cg.load(.bool, operand_id, .{});
5588 }5553 }
55895554
5590 break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))5555 break :blk if (payload_ty.hasRuntimeBits(zcu))
5591 try cg.extractField(.bool, operand_id, 1)5556 try cg.extractField(.bool, operand_id, 1)
5592 else5557 else
5593 // Optional representation is bool indicating whether the optional is set5558 // Optional representation is bool indicating whether the optional is set
...@@ -5656,7 +5621,7 @@ fn airUnwrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -5656,7 +5621,7 @@ fn airUnwrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
5656 const optional_ty = cg.typeOf(ty_op.operand);5621 const optional_ty = cg.typeOf(ty_op.operand);
5657 const payload_ty = cg.typeOfIndex(inst);5622 const payload_ty = cg.typeOfIndex(inst);
56585623
5659 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;5624 if (!payload_ty.hasRuntimeBits(zcu)) return null;
56605625
5661 if (optional_ty.optionalReprIsPayload(zcu)) {5626 if (optional_ty.optionalReprIsPayload(zcu)) {
5662 return operand_id;5627 return operand_id;
...@@ -5675,7 +5640,7 @@ fn airUnwrapOptionalPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -5675,7 +5640,7 @@ fn airUnwrapOptionalPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
5675 const result_ty = cg.typeOfIndex(inst);5640 const result_ty = cg.typeOfIndex(inst);
5676 const result_ty_id = try cg.resolveType(result_ty, .direct);5641 const result_ty_id = try cg.resolveType(result_ty, .direct);
56775642
5678 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5643 if (!payload_ty.hasRuntimeBits(zcu)) {
5679 // There is no payload, but we still need to return a valid pointer.5644 // There is no payload, but we still need to return a valid pointer.
5680 // We can just return anything here, so just return a pointer to the operand.5645 // We can just return anything here, so just return a pointer to the operand.
5681 return try cg.bitCast(result_ty, operand_ty, operand_id);5646 return try cg.bitCast(result_ty, operand_ty, operand_id);
...@@ -5694,9 +5659,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {...@@ -5694,9 +5659,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
5694 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5659 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5695 const payload_ty = cg.typeOf(ty_op.operand);5660 const payload_ty = cg.typeOf(ty_op.operand);
56965661
5697 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5662 assert(payload_ty.hasRuntimeBits(zcu));
5698 return try cg.constBool(true, .indirect);
5699 }
57005663
5701 const operand_id = try cg.resolve(ty_op.operand);5664 const operand_id = try cg.resolve(ty_op.operand);
57025665
...@@ -5792,8 +5755,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5792,8 +5755,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
5792 const int_val: u64 = switch (cond_ty.zigTypeTag(zcu)) {5755 const int_val: u64 = switch (cond_ty.zigTypeTag(zcu)) {
5793 .bool, .int => if (cond_ty.isSignedInt(zcu)) @bitCast(value.toSignedInt(zcu)) else value.toUnsignedInt(zcu),5756 .bool, .int => if (cond_ty.isSignedInt(zcu)) @bitCast(value.toSignedInt(zcu)) else value.toUnsignedInt(zcu),
5794 .@"enum" => blk: {5757 .@"enum" => blk: {
5795 // TODO: figure out of cond_ty is correct (something with enum literals)5758 break :blk value.intFromEnum(zcu).toUnsignedInt(zcu); // TODO: composite integer constants
5796 break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(zcu); // TODO: composite integer constants
5797 },5759 },
5798 .error_set => value.getErrorInt(zcu),5760 .error_set => value.getErrorInt(zcu),
5799 .pointer => value.toUnsignedInt(zcu),5761 .pointer => value.toUnsignedInt(zcu),
...@@ -6070,7 +6032,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie...@@ -6070,7 +6032,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
6070 // before starting to emit OpFunctionCall instructions. Hence the6032 // before starting to emit OpFunctionCall instructions. Hence the
6071 // temporary params buffer.6033 // temporary params buffer.
6072 const arg_ty = cg.typeOf(arg);6034 const arg_ty = cg.typeOf(arg);
6073 if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;6035 if (!arg_ty.hasRuntimeBits(zcu)) continue;
6074 const arg_id = try cg.resolve(arg);6036 const arg_id = try cg.resolve(arg);
60756037
6076 params[n_params] = arg_id;6038 params[n_params] = arg_id;
...@@ -6084,7 +6046,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie...@@ -6084,7 +6046,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
6084 .id_ref_3 = params[0..n_params],6046 .id_ref_3 = params[0..n_params],
6085 });6047 });
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)) {
6088 return null;6050 return null;
6089 }6051 }
60906052
src/codegen/wasm/CodeGen.zig+77-151
...@@ -759,7 +759,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -759,7 +759,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
759 const zcu = pt.zcu;759 const zcu = pt.zcu;
760 const val = (try cg.air.value(ref, pt)).?;760 const val = (try cg.air.value(ref, pt)).?;
761 const ty = cg.typeOf(ref);761 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)) {
763 gop.value_ptr.* = .none;763 gop.value_ptr.* = .none;
764 return .none;764 return .none;
765 }765 }
...@@ -773,7 +773,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -773,7 +773,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
773 const result: WValue = if (isByRef(ty, zcu, cg.target))773 const result: WValue = if (isByRef(ty, zcu, cg.target))
774 .{ .uav_ref = .{ .ip_index = val.toIntern() } }774 .{ .uav_ref = .{ .ip_index = val.toIntern() } }
775 else775 else
776 try cg.lowerConstant(val, ty);776 try cg.lowerConstant(val);
777777
778 gop.value_ptr.* = result;778 gop.value_ptr.* = result;
779 return result;779 return result;
...@@ -786,7 +786,7 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {...@@ -786,7 +786,7 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {
786 return if (isByRef(ty, zcu, cg.target))786 return if (isByRef(ty, zcu, cg.target))
787 .{ .uav_ref = .{ .ip_index = val.toIntern() } }787 .{ .uav_ref = .{ .ip_index = val.toIntern() } }
788 else788 else
789 try cg.lowerConstant(val, ty);789 try cg.lowerConstant(val);
790}790}
791791
792/// NOTE: if result == .stack, it will be stored in .local792/// NOTE: if result == .stack, it will be stored in .local
...@@ -980,7 +980,6 @@ fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {...@@ -980,7 +980,6 @@ fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {
980980
981/// For `std.builtin.CallingConvention.auto`.981/// For `std.builtin.CallingConvention.auto`.
982pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.Valtype {982pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.Valtype {
983 const ip = &zcu.intern_pool;
984 return switch (ty.zigTypeTag(zcu)) {983 return switch (ty.zigTypeTag(zcu)) {
985 .float => switch (ty.floatBits(target)) {984 .float => switch (ty.floatBits(target)) {
986 16 => .i32, // stored/loaded as u16985 16 => .i32, // stored/loaded as u16
...@@ -994,25 +993,13 @@ pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.w...@@ -994,25 +993,13 @@ pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.w
994 33...64 => .i64,993 33...64 => .i64,
995 else => .i32,994 else => .i32,
996 },995 },
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 },
1005 .vector => switch (CodeGen.determineSimdStoreStrategy(ty, zcu, target)) {996 .vector => switch (CodeGen.determineSimdStoreStrategy(ty, zcu, target)) {
1006 .direct => .v128,997 .direct => .v128,
1007 .unrolled => .i32,998 .unrolled => .i32,
1008 },999 },
1009 .@"union" => switch (ty.containerLayout(zcu)) {1000 .@"union", .@"struct" => switch (ty.containerLayout(zcu)) {
1010 .@"packed" => switch (ty.bitSize(zcu)) {1001 .@"packed" => typeToValtype(ty.bitpackBackingInt(zcu), zcu, target),
1011 0...32 => .i32,1002 .auto, .@"extern" => .i32,
1012 33...64 => .i64,
1013 else => .i32,
1014 },
1015 else => .i32,
1016 },1003 },
1017 else => .i32, // all represented as reference/immediate1004 else => .i32, // all represented as reference/immediate
1018 };1005 };
...@@ -1185,7 +1172,7 @@ pub fn generate(...@@ -1185,7 +1172,7 @@ pub fn generate(
1185 const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);1172 const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);
1186 const fn_info = zcu.typeToFunc(fn_ty).?;1173 const fn_info = zcu.typeToFunc(fn_ty).?;
1187 const ret_ty: Type = .fromInterned(fn_info.return_type);1174 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
1190 var cc_result = try resolveCallingConventionValues(zcu, fn_ty, target);1177 var cc_result = try resolveCallingConventionValues(zcu, fn_ty, target);
1191 defer cc_result.deinit(gpa);1178 defer cc_result.deinit(gpa);
...@@ -1244,7 +1231,7 @@ fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {...@@ -1244,7 +1231,7 @@ fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {
1244 if (any_returns and cg.air.instructions.len > 0) {1231 if (any_returns and cg.air.instructions.len > 0) {
1245 const inst: Air.Inst.Index = @enumFromInt(cg.air.instructions.len - 1);1232 const inst: Air.Inst.Index = @enumFromInt(cg.air.instructions.len - 1);
1246 const last_inst_ty = cg.typeOfIndex(inst);1233 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)) {
1248 try cg.addTag(.@"unreachable");1235 try cg.addTag(.@"unreachable");
1249 }1236 }
1250 }1237 }
...@@ -1316,7 +1303,7 @@ fn resolveCallingConventionValues(...@@ -1316,7 +1303,7 @@ fn resolveCallingConventionValues(
1316 switch (cc) {1303 switch (cc) {
1317 .auto => {1304 .auto => {
1318 for (fn_info.param_types.get(ip)) |ty| {1305 for (fn_info.param_types.get(ip)) |ty| {
1319 if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) {1306 if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) {
1320 continue;1307 continue;
1321 }1308 }
13221309
...@@ -1326,7 +1313,7 @@ fn resolveCallingConventionValues(...@@ -1326,7 +1313,7 @@ fn resolveCallingConventionValues(
1326 },1313 },
1327 .wasm_mvp => {1314 .wasm_mvp => {
1328 for (fn_info.param_types.get(ip)) |ty| {1315 for (fn_info.param_types.get(ip)) |ty| {
1329 if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) {1316 if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) {
1330 continue;1317 continue;
1331 }1318 }
1332 switch (abi.classifyType(.fromInterned(ty), zcu)) {1319 switch (abi.classifyType(.fromInterned(ty), zcu)) {
...@@ -1357,7 +1344,7 @@ pub fn firstParamSRet(...@@ -1357,7 +1344,7 @@ pub fn firstParamSRet(
1357 zcu: *const Zcu,1344 zcu: *const Zcu,
1358 target: *const std.Target,1345 target: *const std.Target,
1359) bool {1346) bool {
1360 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;1347 if (!return_type.hasRuntimeBits(zcu)) return false;
1361 switch (cc) {1348 switch (cc) {
1362 .@"inline" => unreachable,1349 .@"inline" => unreachable,
1363 .auto => return isByRef(return_type, zcu, target),1350 .auto => return isByRef(return_type, zcu, target),
...@@ -1457,7 +1444,7 @@ fn restoreStackPointer(cg: *CodeGen) !void {...@@ -1457,7 +1444,7 @@ fn restoreStackPointer(cg: *CodeGen) !void {
1457fn allocStack(cg: *CodeGen, ty: Type) !WValue {1444fn allocStack(cg: *CodeGen, ty: Type) !WValue {
1458 const pt = cg.pt;1445 const pt = cg.pt;
1459 const zcu = pt.zcu;1446 const zcu = pt.zcu;
1460 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));1447 assert(ty.hasRuntimeBits(zcu));
1461 if (cg.initial_stack_value == .none) {1448 if (cg.initial_stack_value == .none) {
1462 try cg.initializeStack();1449 try cg.initializeStack();
1463 }1450 }
...@@ -1491,7 +1478,7 @@ fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue {...@@ -1491,7 +1478,7 @@ fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue {
1491 try cg.initializeStack();1478 try cg.initializeStack();
1492 }1479 }
14931480
1494 if (!pointee_ty.hasRuntimeBitsIgnoreComptime(zcu)) {1481 if (!pointee_ty.hasRuntimeBits(zcu)) {
1495 return cg.allocStack(Type.usize); // create a value containing just the stack pointer.1482 return cg.allocStack(Type.usize); // create a value containing just the stack pointer.
1496 }1483 }
14971484
...@@ -1676,7 +1663,6 @@ fn ptrSize(cg: *const CodeGen) u16 {...@@ -1676,7 +1663,6 @@ fn ptrSize(cg: *const CodeGen) u16 {
1676/// For a given `Type`, will return true when the type will be passed1663/// For a given `Type`, will return true when the type will be passed
1677/// by reference, rather than by value1664/// by reference, rather than by value
1678fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {1665fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
1679 const ip = &zcu.intern_pool;
1680 switch (ty.zigTypeTag(zcu)) {1666 switch (ty.zigTypeTag(zcu)) {
1681 .type,1667 .type,
1682 .comptime_int,1668 .comptime_int,
...@@ -1697,20 +1683,10 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {...@@ -1697,20 +1683,10 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
16971683
1698 .array,1684 .array,
1699 .frame,1685 .frame,
1700 => return ty.hasRuntimeBitsIgnoreComptime(zcu),1686 => return ty.hasRuntimeBits(zcu),
1701 .@"union" => {1687 .@"struct", .@"union" => switch (ty.containerLayout(zcu)) {
1702 if (zcu.typeToUnion(ty)) |union_obj| {1688 .@"packed" => return isByRef(ty.bitpackBackingInt(zcu), zcu, target),
1703 if (union_obj.flagsUnordered(ip).layout == .@"packed") {1689 .@"extern", .auto => return ty.hasRuntimeBits(zcu),
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);
1714 },1690 },
1715 .vector => return determineSimdStoreStrategy(ty, zcu, target) == .unrolled,1691 .vector => return determineSimdStoreStrategy(ty, zcu, target) == .unrolled,
1716 .int => return ty.intInfo(zcu).bits > 64,1692 .int => return ty.intInfo(zcu).bits > 64,
...@@ -1718,7 +1694,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {...@@ -1718,7 +1694,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
1718 .float => return ty.floatBits(target) > 64,1694 .float => return ty.floatBits(target) > 64,
1719 .error_union => {1695 .error_union => {
1720 const pl_ty = ty.errorUnionPayload(zcu);1696 const pl_ty = ty.errorUnionPayload(zcu);
1721 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {1697 if (!pl_ty.hasRuntimeBits(zcu)) {
1722 return false;1698 return false;
1723 }1699 }
1724 return true;1700 return true;
...@@ -1727,7 +1703,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {...@@ -1727,7 +1703,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
1727 if (ty.isPtrLikeOptional(zcu)) return false;1703 if (ty.isPtrLikeOptional(zcu)) return false;
1728 const pl_type = ty.optionalChild(zcu);1704 const pl_type = ty.optionalChild(zcu);
1729 if (pl_type.zigTypeTag(zcu) == .error_set) return false;1705 if (pl_type.zigTypeTag(zcu) == .error_set) return false;
1730 return pl_type.hasRuntimeBitsIgnoreComptime(zcu);1706 return pl_type.hasRuntimeBits(zcu);
1731 },1707 },
1732 .pointer => {1708 .pointer => {
1733 // Slices act like struct and will be passed by reference1709 // Slices act like struct and will be passed by reference
...@@ -2069,7 +2045,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2069,7 +2045,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2069 // to the stack instead2045 // to the stack instead
2070 if (cg.return_value != .none) {2046 if (cg.return_value != .none) {
2071 try cg.store(cg.return_value, operand, ret_ty, 0);2047 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)) {
2073 switch (abi.classifyType(ret_ty, zcu)) {2049 switch (abi.classifyType(ret_ty, zcu)) {
2074 .direct => |scalar_type| {2050 .direct => |scalar_type| {
2075 assert(!abi.lowerAsDoubleI64(scalar_type, zcu));2051 assert(!abi.lowerAsDoubleI64(scalar_type, zcu));
...@@ -2082,7 +2058,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2082,7 +2058,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2082 .indirect => unreachable,2058 .indirect => unreachable,
2083 }2059 }
2084 } else {2060 } else {
2085 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and ret_ty.isError(zcu)) {2061 if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) {
2086 try cg.addImm32(0);2062 try cg.addImm32(0);
2087 } else {2063 } else {
2088 try cg.emitWValue(operand);2064 try cg.emitWValue(operand);
...@@ -2099,7 +2075,7 @@ fn airRetPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2099,7 +2075,7 @@ fn airRetPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2099 const child_type = cg.typeOfIndex(inst).childType(zcu);2075 const child_type = cg.typeOfIndex(inst).childType(zcu);
21002076
2101 const result = result: {2077 const result = result: {
2102 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {2078 if (!child_type.hasRuntimeBits(zcu)) {
2103 break :result try cg.allocStack(Type.usize); // create pointer to void2079 break :result try cg.allocStack(Type.usize); // create pointer to void
2104 }2080 }
21052081
...@@ -2121,7 +2097,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2121,7 +2097,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2121 const ret_ty = cg.typeOf(un_op).childType(zcu);2097 const ret_ty = cg.typeOf(un_op).childType(zcu);
21222098
2123 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;2099 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
2124 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2100 if (!ret_ty.hasRuntimeBits(zcu)) {
2125 if (ret_ty.isError(zcu)) {2101 if (ret_ty.isError(zcu)) {
2126 try cg.addImm32(0);2102 try cg.addImm32(0);
2127 }2103 }
...@@ -2177,7 +2153,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie...@@ -2177,7 +2153,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
2177 const arg_val = try cg.resolveInst(arg);2153 const arg_val = try cg.resolveInst(arg);
21782154
2179 const arg_ty = cg.typeOf(arg);2155 const arg_ty = cg.typeOf(arg);
2180 if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;2156 if (!arg_ty.hasRuntimeBits(zcu)) continue;
21812157
2182 try cg.lowerArg(zcu.typeToFunc(fn_ty).?.cc, arg_ty, arg_val);2158 try cg.lowerArg(zcu.typeToFunc(fn_ty).?.cc, arg_ty, arg_val);
2183 }2159 }
...@@ -2199,10 +2175,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie...@@ -2199,10 +2175,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
2199 }2175 }
22002176
2201 const result_value = result_value: {2177 const result_value = result_value: {
2202 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) {2178 if (!ret_ty.hasRuntimeBits(zcu) and !ret_ty.isError(zcu)) {
2203 break :result_value .none;
2204 } else if (ret_ty.isNoReturn(zcu)) {
2205 try cg.addTag(.@"unreachable");
2206 break :result_value .none;2179 break :result_value .none;
2207 } else if (first_param_sret) {2180 } else if (first_param_sret) {
2208 break :result_value sret;2181 break :result_value sret;
...@@ -2323,12 +2296,12 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr...@@ -2323,12 +2296,12 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
2323 const zcu = pt.zcu;2296 const zcu = pt.zcu;
2324 const abi_size = ty.abiSize(zcu);2297 const abi_size = ty.abiSize(zcu);
23252298
2326 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return;2299 if (!ty.hasRuntimeBits(zcu)) return;
23272300
2328 switch (ty.zigTypeTag(zcu)) {2301 switch (ty.zigTypeTag(zcu)) {
2329 .error_union => {2302 .error_union => {
2330 const pl_ty = ty.errorUnionPayload(zcu);2303 const pl_ty = ty.errorUnionPayload(zcu);
2331 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2304 if (!pl_ty.hasRuntimeBits(zcu)) {
2332 return cg.store(lhs, rhs, Type.anyerror, offset);2305 return cg.store(lhs, rhs, Type.anyerror, offset);
2333 }2306 }
23342307
...@@ -2341,7 +2314,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr...@@ -2341,7 +2314,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
2341 return cg.store(lhs, rhs, Type.usize, offset);2314 return cg.store(lhs, rhs, Type.usize, offset);
2342 }2315 }
2343 const pl_ty = ty.optionalChild(zcu);2316 const pl_ty = ty.optionalChild(zcu);
2344 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2317 if (!pl_ty.hasRuntimeBits(zcu)) {
2345 return cg.store(lhs, rhs, Type.u8, offset);2318 return cg.store(lhs, rhs, Type.u8, offset);
2346 }2319 }
2347 if (pl_ty.zigTypeTag(zcu) == .error_set) {2320 if (pl_ty.zigTypeTag(zcu) == .error_set) {
...@@ -2441,7 +2414,7 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2441,7 +2414,7 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2441 const ptr_ty = cg.typeOf(ty_op.operand);2414 const ptr_ty = cg.typeOf(ty_op.operand);
2442 const ptr_info = ptr_ty.ptrInfo(zcu);2415 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
2446 const result = result: {2419 const result = result: {
2447 if (isByRef(ty, zcu, cg.target)) {2420 if (isByRef(ty, zcu, cg.target)) {
...@@ -3092,7 +3065,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro...@@ -3092,7 +3065,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
3092 return switch (ptr.base_addr) {3065 return switch (ptr.base_addr) {
3093 .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },3066 .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },
3094 .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } },3067 .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)),
3096 .eu_payload => |eu_ptr| try cg.lowerPtr(3069 .eu_payload => |eu_ptr| try cg.lowerPtr(
3097 eu_ptr,3070 eu_ptr,
3098 offset + codegen.errUnionPayloadOffset(3071 offset + codegen.errUnionPayloadOffset(
...@@ -3129,10 +3102,11 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro...@@ -3129,10 +3102,11 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
3129 };3102 };
3130}3103}
31313104
3132/// Asserts that `isByRef` returns `false` for `ty`.3105/// Asserts that `isByRef` returns `false` for `val.typeOf(zcu)`.
3133fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {3106fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {
3134 const pt = cg.pt;3107 const pt = cg.pt;
3135 const zcu = pt.zcu;3108 const zcu = pt.zcu;
3109 const ty = val.typeOf(zcu);
3136 assert(!isByRef(ty, zcu, cg.target));3110 assert(!isByRef(ty, zcu, cg.target));
3137 const ip = &zcu.intern_pool;3111 const ip = &zcu.intern_pool;
3138 if (val.isUndef(zcu)) return cg.emitUndefined(ty);3112 if (val.isUndef(zcu)) return cg.emitUndefined(ty);
...@@ -3158,10 +3132,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3158,10 +3132,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
31583132
3159 .undef => unreachable, // handled above3133 .undef => unreachable, // handled above
3160 .simple_value => |simple_value| switch (simple_value) {3134 .simple_value => |simple_value| switch (simple_value) {
3161 .undefined,
3162 .void,3135 .void,
3163 .null,3136 .null,
3164 .empty_tuple,
3165 .@"unreachable",3137 .@"unreachable",
3166 => unreachable, // non-runtime values3138 => unreachable, // non-runtime values
3167 .false, .true => return .{ .imm32 = switch (simple_value) {3139 .false, .true => return .{ .imm32 = switch (simple_value) {
...@@ -3174,7 +3146,6 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3174,7 +3146,6 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3174 .@"extern",3146 .@"extern",
3175 .func,3147 .func,
3176 .enum_literal,3148 .enum_literal,
3177 .empty_enum_value,
3178 => unreachable, // non-runtime values3149 => unreachable, // non-runtime values
3179 .int => {3150 .int => {
3180 const int_info = ty.intInfo(zcu);3151 const int_info = ty.intInfo(zcu);
...@@ -3197,31 +3168,22 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3197,31 +3168,22 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3197 },3168 },
3198 .error_union => |error_union| {3169 .error_union => |error_union| {
3199 const err_int_ty = try pt.errorIntType();3170 const err_int_ty = try pt.errorIntType();
3200 const err_ty, const err_val = switch (error_union.val) {3171 const err_val: Value = switch (error_union.val) {
3201 .err_name => |err_name| .{3172 .err_name => |err_name| .fromInterned(try pt.intern(.{ .err = .{
3202 ty.errorUnionSet(zcu),3173 .ty = ty.errorUnionSet(zcu).toIntern(),
3203 Value.fromInterned(try pt.intern(.{ .err = .{3174 .name = err_name,
3204 .ty = ty.errorUnionSet(zcu).toIntern(),3175 } })),
3205 .name = err_name,3176 .payload => try pt.intValue(err_int_ty, 0),
3206 } })),
3207 },
3208 .payload => .{
3209 err_int_ty,
3210 try pt.intValue(err_int_ty, 0),
3211 },
3212 };3177 };
3213 const payload_type = ty.errorUnionPayload(zcu);3178 const payload_type = ty.errorUnionPayload(zcu);
3214 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {3179 if (!payload_type.hasRuntimeBits(zcu)) {
3215 // We use the error type directly as the type.3180 // We use the error type directly as the type.
3216 return cg.lowerConstant(err_val, err_ty);3181 return cg.lowerConstant(err_val);
3217 }3182 }
32183183
3219 return cg.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});3184 return cg.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
3220 },3185 },
3221 .enum_tag => |enum_tag| {3186 .enum_tag => |enum_tag| return cg.lowerConstant(.fromInterned(enum_tag.int)),
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 },
3225 .float => |float| switch (float.storage) {3187 .float => |float| switch (float.storage) {
3226 .f16 => |f16_val| return .{ .imm32 = @as(u16, @bitCast(f16_val)) },3188 .f16 => |f16_val| return .{ .imm32 = @as(u16, @bitCast(f16_val)) },
3227 .f32 => |f32_val| return .{ .float32 = f32_val },3189 .f32 => |f32_val| return .{ .float32 = f32_val },
...@@ -3231,9 +3193,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3231,9 +3193,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3231 .slice => unreachable, // isByRef == true3193 .slice => unreachable, // isByRef == true
3232 .ptr => return cg.lowerPtr(val.toIntern(), 0),3194 .ptr => return cg.lowerPtr(val.toIntern(), 0),
3233 .opt => if (ty.optionalReprIsPayload(zcu)) {3195 .opt => if (ty.optionalReprIsPayload(zcu)) {
3234 const pl_ty = ty.optionalChild(zcu);
3235 if (val.optionalValue(zcu)) |payload| {3196 if (val.optionalValue(zcu)) |payload| {
3236 return cg.lowerConstant(payload, pl_ty);3197 return cg.lowerConstant(payload);
3237 } else {3198 } else {
3238 return .{ .imm32 = 0 };3199 return .{ .imm32 = 0 };
3239 }3200 }
...@@ -3248,33 +3209,11 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3248,33 +3209,11 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3248 val.writeToMemory(pt, &buf) catch unreachable;3209 val.writeToMemory(pt, &buf) catch unreachable;
3249 return cg.storeSimdImmd(buf);3210 return cg.storeSimdImmd(buf);
3250 },3211 },
3251 .struct_type => {3212 .struct_type => unreachable, // packed structs use `bitpack`
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 },
3265 else => unreachable,3213 else => unreachable,
3266 },3214 },
3267 .un => {3215 .un => unreachable, // packed unions use `bitpack`
3268 const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));3216 .bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)),
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 },
3278 .memoized_call => unreachable,3217 .memoized_call => unreachable,
3279 }3218 }
3280}3219}
...@@ -3289,7 +3228,6 @@ fn storeSimdImmd(cg: *CodeGen, value: [16]u8) !WValue {...@@ -3289,7 +3228,6 @@ fn storeSimdImmd(cg: *CodeGen, value: [16]u8) !WValue {
32893228
3290fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {3229fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
3291 const zcu = cg.pt.zcu;3230 const zcu = cg.pt.zcu;
3292 const ip = &zcu.intern_pool;
3293 switch (ty.zigTypeTag(zcu)) {3231 switch (ty.zigTypeTag(zcu)) {
3294 .bool, .error_set => return .{ .imm32 = 0xaaaaaaaa },3232 .bool, .error_set => return .{ .imm32 = 0xaaaaaaaa },
3295 .int, .@"enum" => switch (ty.intInfo(zcu).bits) {3233 .int, .@"enum" => switch (ty.intInfo(zcu).bits) {
...@@ -3317,17 +3255,9 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {...@@ -3317,17 +3255,9 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
3317 .error_union => {3255 .error_union => {
3318 return .{ .imm32 = 0xaaaaaaaa };3256 return .{ .imm32 = 0xaaaaaaaa };
3319 },3257 },
3320 .@"struct" => {3258 .@"struct", .@"union" => {
3321 const packed_struct = zcu.typeToPackedStruct(ty).?;3259 const backing_int_ty = ty.bitpackBackingInt(zcu);
3322 return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));3260 return cg.emitUndefined(backing_int_ty);
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,
3331 },3261 },
3332 else => return cg.fail("Wasm TODO: emitUndefined for type: {t}\n", .{ty.zigTypeTag(zcu)}),3262 else => return cg.fail("Wasm TODO: emitUndefined for type: {t}\n", .{ty.zigTypeTag(zcu)}),
3333 }3263 }
...@@ -3341,7 +3271,7 @@ fn airBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3341,7 +3271,7 @@ fn airBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3341fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {3271fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
3342 const zcu = cg.pt.zcu;3272 const zcu = cg.pt.zcu;
3343 // if wasm_block_ty is non-empty, we create a register to store the temporary value3273 // 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))
3345 try cg.allocLocal(block_ty)3275 try cg.allocLocal(block_ty)
3346 else3276 else
3347 .none;3277 .none;
...@@ -3455,7 +3385,7 @@ fn cmp(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOpe...@@ -3455,7 +3385,7 @@ fn cmp(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOpe
3455 const zcu = cg.pt.zcu;3385 const zcu = cg.pt.zcu;
3456 if (ty.zigTypeTag(zcu) == .optional and !ty.optionalReprIsPayload(zcu)) {3386 if (ty.zigTypeTag(zcu) == .optional and !ty.optionalReprIsPayload(zcu)) {
3457 const payload_ty = ty.optionalChild(zcu);3387 const payload_ty = ty.optionalChild(zcu);
3458 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3388 if (payload_ty.hasRuntimeBits(zcu)) {
3459 // When we hit this case, we must check the value of optionals3389 // When we hit this case, we must check the value of optionals
3460 // that are not pointers. This means first checking against non-null for3390 // that are not pointers. This means first checking against non-null for
3461 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs3391 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs
...@@ -3798,7 +3728,6 @@ fn structFieldPtr(...@@ -3798,7 +3728,6 @@ fn structFieldPtr(
3798fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {3728fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3799 const pt = cg.pt;3729 const pt = cg.pt;
3800 const zcu = pt.zcu;3730 const zcu = pt.zcu;
3801 const ip = &zcu.intern_pool;
3802 const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3731 const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3803 const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data;3732 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 {...@@ -3806,14 +3735,14 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3806 const operand = try cg.resolveInst(struct_field.struct_operand);3735 const operand = try cg.resolveInst(struct_field.struct_operand);
3807 const field_index = struct_field.field_index;3736 const field_index = struct_field.field_index;
3808 const field_ty = struct_ty.fieldType(field_index, zcu);3737 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
3811 const result: WValue = switch (struct_ty.containerLayout(zcu)) {3740 const result: WValue = switch (struct_ty.containerLayout(zcu)) {
3812 .@"packed" => switch (struct_ty.zigTypeTag(zcu)) {3741 .@"packed" => switch (struct_ty.zigTypeTag(zcu)) {
3813 .@"struct" => result: {3742 .@"struct" => result: {
3814 const packed_struct = zcu.typeToPackedStruct(struct_ty).?;3743 const packed_struct = zcu.typeToPackedStruct(struct_ty).?;
3815 const offset = zcu.structPackedFieldBitOffset(packed_struct, field_index);3744 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);
3817 const host_bits = backing_ty.intInfo(zcu).bits;3746 const host_bits = backing_ty.intInfo(zcu).bits;
38183747
3819 const const_wvalue: WValue = if (33 <= host_bits and host_bits <= 64)3748 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...@@ -3891,7 +3820,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner
3891 const switch_br = cg.air.unwrapSwitch(inst);3820 const switch_br = cg.air.unwrapSwitch(inst);
3892 const target_ty = cg.typeOf(switch_br.operand);3821 const target_ty = cg.typeOf(switch_br.operand);
38933822
3894 assert(target_ty.hasRuntimeBitsIgnoreComptime(zcu));3823 assert(target_ty.hasRuntimeBits(zcu));
38953824
3896 // swap target value with placeholder local, for dispatching3825 // swap target value with placeholder local, for dispatching
3897 const target = if (is_dispatch_loop) target: {3826 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...@@ -4125,7 +4054,7 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kind
4125 }4054 }
41264055
4127 try cg.emitWValue(operand);4056 try cg.emitWValue(operand);
4128 if (op_kind == .ptr or pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4057 if (op_kind == .ptr or pl_ty.hasRuntimeBits(zcu)) {
4129 try cg.addMemArg(.i32_load16_u, .{4058 try cg.addMemArg(.i32_load16_u, .{
4130 .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))),4059 .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))),
4131 .alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?),4060 .alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?),
...@@ -4152,7 +4081,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -4152,7 +4081,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
4152 const payload_ty = eu_ty.errorUnionPayload(zcu);4081 const payload_ty = eu_ty.errorUnionPayload(zcu);
41534082
4154 const result: WValue = result: {4083 const result: WValue = result: {
4155 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4084 if (!payload_ty.hasRuntimeBits(zcu)) {
4156 if (op_is_ptr) {4085 if (op_is_ptr) {
4157 break :result cg.reuseOperand(ty_op.operand, operand);4086 break :result cg.reuseOperand(ty_op.operand, operand);
4158 } else {4087 } else {
...@@ -4172,7 +4101,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -4172,7 +4101,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
4172}4101}
41734102
4174/// E!T -> E op_is_ptr == false4103/// E!T -> E op_is_ptr == false
4175/// *(E!T) -> E op_is_prt == true4104/// *(E!T) -> E op_is_ptr == true
4176/// NOTE: op_is_ptr will not change return type4105/// NOTE: op_is_ptr will not change return type
4177fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {4106fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4178 const zcu = cg.pt.zcu;4107 const zcu = cg.pt.zcu;
...@@ -4192,7 +4121,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I...@@ -4192,7 +4121,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I
4192 if (op_is_ptr or isByRef(eu_ty, zcu, cg.target)) {4121 if (op_is_ptr or isByRef(eu_ty, zcu, cg.target)) {
4193 break :result try cg.load(operand, Type.anyerror, err_offset);4122 break :result try cg.load(operand, Type.anyerror, err_offset);
4194 } else {4123 } else {
4195 assert(!payload_ty.hasRuntimeBitsIgnoreComptime(zcu));4124 assert(!payload_ty.hasRuntimeBits(zcu));
4196 break :result cg.reuseOperand(ty_op.operand, operand);4125 break :result cg.reuseOperand(ty_op.operand, operand);
4197 }4126 }
4198 };4127 };
...@@ -4208,7 +4137,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4208,7 +4137,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42084137
4209 const pl_ty = cg.typeOf(ty_op.operand);4138 const pl_ty = cg.typeOf(ty_op.operand);
4210 const result = result: {4139 const result = result: {
4211 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4140 if (!pl_ty.hasRuntimeBits(zcu)) {
4212 break :result cg.reuseOperand(ty_op.operand, operand);4141 break :result cg.reuseOperand(ty_op.operand, operand);
4213 }4142 }
42144143
...@@ -4238,7 +4167,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4238,7 +4167,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4238 const pl_ty = err_ty.errorUnionPayload(zcu);4167 const pl_ty = err_ty.errorUnionPayload(zcu);
42394168
4240 const result = result: {4169 const result = result: {
4241 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4170 if (!pl_ty.hasRuntimeBits(zcu)) {
4242 break :result cg.reuseOperand(ty_op.operand, operand);4171 break :result cg.reuseOperand(ty_op.operand, operand);
4243 }4172 }
42444173
...@@ -4354,7 +4283,7 @@ fn isNull(cg: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.Opc...@@ -4354,7 +4283,7 @@ fn isNull(cg: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.Opc
4354 if (!optional_ty.optionalReprIsPayload(zcu)) {4283 if (!optional_ty.optionalReprIsPayload(zcu)) {
4355 // When payload is zero-bits, we can treat operand as a value, rather than4284 // When payload is zero-bits, we can treat operand as a value, rather than
4356 // a pointer to the stack value4285 // a pointer to the stack value
4357 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4286 if (payload_ty.hasRuntimeBits(zcu)) {
4358 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {4287 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
4359 return cg.fail("Optional type {f} too big to fit into stack frame", .{optional_ty.fmt(pt)});4288 return cg.fail("Optional type {f} too big to fit into stack frame", .{optional_ty.fmt(pt)});
4360 };4289 };
...@@ -4379,7 +4308,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4379,7 +4308,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4379 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4308 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4380 const opt_ty = cg.typeOf(ty_op.operand);4309 const opt_ty = cg.typeOf(ty_op.operand);
4381 const payload_ty = cg.typeOfIndex(inst);4310 const payload_ty = cg.typeOfIndex(inst);
4382 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4311 if (!payload_ty.hasRuntimeBits(zcu)) {
4383 return cg.finishAir(inst, .none, &.{ty_op.operand});4312 return cg.finishAir(inst, .none, &.{ty_op.operand});
4384 }4313 }
43854314
...@@ -4404,7 +4333,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4404,7 +4333,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44044333
4405 const result = result: {4334 const result = result: {
4406 const payload_ty = opt_ty.optionalChild(zcu);4335 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)) {
4408 break :result cg.reuseOperand(ty_op.operand, operand);4337 break :result cg.reuseOperand(ty_op.operand, operand);
4409 }4338 }
44104339
...@@ -4444,7 +4373,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4444,7 +4373,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4444 const zcu = pt.zcu;4373 const zcu = pt.zcu;
44454374
4446 const result = result: {4375 const result = result: {
4447 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4376 if (!payload_ty.hasRuntimeBits(zcu)) {
4448 const non_null_bit = try cg.allocStack(Type.u1);4377 const non_null_bit = try cg.allocStack(Type.u1);
4449 try cg.emitWValue(non_null_bit);4378 try cg.emitWValue(non_null_bit);
4450 try cg.addImm32(1);4379 try cg.addImm32(1);
...@@ -4612,7 +4541,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4612,7 +4541,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4612 const slice_local = try cg.allocStack(slice_ty);4541 const slice_local = try cg.allocStack(slice_ty);
46134542
4614 // store the array ptr in the slice4543 // store the array ptr in the slice
4615 if (array_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4544 if (array_ty.hasRuntimeBits(zcu)) {
4616 try cg.store(slice_local, operand, Type.usize, 0);4545 try cg.store(slice_local, operand, Type.usize, 0);
4617 }4546 }
46184547
...@@ -5111,7 +5040,7 @@ fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5111,7 +5040,7 @@ fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5111 try cg.emitWValue(dest_alloc);5040 try cg.emitWValue(dest_alloc);
5112 const elem_val = switch (mask_elem.unwrap()) {5041 const elem_val = switch (mask_elem.unwrap()) {
5113 .elem => |idx| try cg.load(operand, elem_ty, @intCast(elem_size * idx)),5042 .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)),
5115 };5044 };
5116 try cg.store(.stack, elem_val, elem_ty, @intCast(dest_alloc.offset() + elem_size * out_idx));5045 try cg.store(.stack, elem_val, elem_ty, @intCast(dest_alloc.offset() + elem_size * out_idx));
5117 }5046 }
...@@ -5252,7 +5181,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5252,7 +5181,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5252 }5181 }
5253 const packed_struct = zcu.typeToPackedStruct(result_ty).?;5182 const packed_struct = zcu.typeToPackedStruct(result_ty).?;
5254 const field_types = packed_struct.field_types;5183 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
5257 // ensure the result is zero'd5186 // ensure the result is zero'd
5258 const result = try cg.allocLocal(backing_type);5187 const result = try cg.allocLocal(backing_type);
...@@ -5265,7 +5194,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5265,7 +5194,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5265 var current_bit: u16 = 0;5194 var current_bit: u16 = 0;
5266 for (elements, 0..) |elem, elem_index| {5195 for (elements, 0..) |elem, elem_index| {
5267 const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);5196 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
5270 const shift_val: WValue = if (backing_type.bitSize(zcu) <= 32)5199 const shift_val: WValue = if (backing_type.bitSize(zcu) <= 32)
5271 .{ .imm32 = current_bit }5200 .{ .imm32 = current_bit }
...@@ -5338,13 +5267,13 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5338,13 +5267,13 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5338 const layout = union_ty.unionGetLayout(zcu);5267 const layout = union_ty.unionGetLayout(zcu);
5339 const union_obj = zcu.typeToUnion(union_ty).?;5268 const union_obj = zcu.typeToUnion(union_ty).?;
5340 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);5269 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
5343 const tag_int = blk: {5272 const tag_int = blk: {
5344 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);5273 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
5345 const enum_field_index = tag_ty.enumFieldIndex(field_name, zcu).?;5274 const enum_field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
5346 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);5275 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);
5348 };5277 };
5349 if (layout.payload_size == 0) {5278 if (layout.payload_size == 0) {
5350 if (layout.tag_size == 0) {5279 if (layout.tag_size == 0) {
...@@ -5366,7 +5295,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5366,7 +5295,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5366 }5295 }
53675296
5368 if (layout.tag_size > 0) {5297 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);
5370 }5299 }
5371 } else {5300 } else {
5372 try cg.store(result_ptr, payload, field_ty, 0);5301 try cg.store(result_ptr, payload, field_ty, 0);
...@@ -5374,7 +5303,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5374,7 +5303,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5374 try cg.store(5303 try cg.store(
5375 result_ptr,5304 result_ptr,
5376 tag_int,5305 tag_int,
5377 Type.fromInterned(union_obj.enum_tag_ty),5306 .fromInterned(union_obj.enum_tag_type),
5378 @intCast(layout.payload_size),5307 @intCast(layout.payload_size),
5379 );5308 );
5380 }5309 }
...@@ -5421,7 +5350,7 @@ fn airWasmMemoryGrow(cg: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5421,7 +5350,7 @@ fn airWasmMemoryGrow(cg: *CodeGen, inst: Air.Inst.Index) !void {
54215350
5422fn cmpOptionals(cg: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {5351fn cmpOptionals(cg: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5423 const zcu = cg.pt.zcu;5352 const zcu = cg.pt.zcu;
5424 assert(operand_ty.hasRuntimeBitsIgnoreComptime(zcu));5353 assert(operand_ty.hasRuntimeBits(zcu));
5425 assert(op == .eq or op == .neq);5354 assert(op == .eq or op == .neq);
5426 const payload_ty = operand_ty.optionalChild(zcu);5355 const payload_ty = operand_ty.optionalChild(zcu);
5427 assert(!isByRef(payload_ty, zcu, cg.target));5356 assert(!isByRef(payload_ty, zcu, cg.target));
...@@ -5675,7 +5604,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -5675,7 +5604,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
5675 );5604 );
56765605
5677 const result = result: {5606 const result = result: {
5678 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5607 if (!payload_ty.hasRuntimeBits(zcu)) {
5679 break :result cg.reuseOperand(ty_op.operand, operand);5608 break :result cg.reuseOperand(ty_op.operand, operand);
5680 }5609 }
56815610
...@@ -6464,7 +6393,7 @@ fn lowerTry(...@@ -6464,7 +6393,7 @@ fn lowerTry(
6464 const zcu = cg.pt.zcu;6393 const zcu = cg.pt.zcu;
64656394
6466 const pl_ty = err_union_ty.errorUnionPayload(zcu);6395 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
6469 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {6398 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
6470 // Block we can jump out of when error is not set6399 // Block we can jump out of when error is not set
...@@ -7102,16 +7031,13 @@ fn callIntrinsic(...@@ -7102,16 +7031,13 @@ fn callIntrinsic(
7102 // Lower all arguments to the stack before we call our function7031 // Lower all arguments to the stack before we call our function
7103 for (args, 0..) |arg, arg_i| {7032 for (args, 0..) |arg, arg_i| {
7104 assert(!(want_sret_param and arg == .stack));7033 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));
7106 try cg.lowerArg(.{ .wasm_mvp = .{} }, Type.fromInterned(param_types[arg_i]), arg);7035 try cg.lowerArg(.{ .wasm_mvp = .{} }, Type.fromInterned(param_types[arg_i]), arg);
7107 }7036 }
71087037
7109 try cg.addInst(.{ .tag = .call_intrinsic, .data = .{ .intrinsic = intrinsic } });7038 try cg.addInst(.{ .tag = .call_intrinsic, .data = .{ .intrinsic = intrinsic } });
71107039
7111 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) {7040 if (!return_type.hasRuntimeBits(zcu)) {
7112 return .none;
7113 } else if (return_type.isNoReturn(zcu)) {
7114 try cg.addTag(.@"unreachable");
7115 return .none;7041 return .none;
7116 } else if (want_sret_param) {7042 } else if (want_sret_param) {
7117 return sret;7043 return sret;
src/codegen/wasm/abi.zig+3-3
...@@ -22,7 +22,7 @@ pub const Class = union(enum) {...@@ -22,7 +22,7 @@ pub const Class = union(enum) {
22/// or returned as value within a wasm function.22/// or returned as value within a wasm function.
23pub fn classifyType(ty: Type, zcu: *const Zcu) Class {23pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
24 const ip = &zcu.intern_pool;24 const ip = &zcu.intern_pool;
25 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));25 assert(ty.hasRuntimeBits(zcu));
26 switch (ty.zigTypeTag(zcu)) {26 switch (ty.zigTypeTag(zcu)) {
27 .int, .@"enum", .error_set => return .{ .direct = ty },27 .int, .@"enum", .error_set => return .{ .direct = ty },
28 .float => return .{ .direct = ty },28 .float => return .{ .direct = ty },
...@@ -47,7 +47,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {...@@ -47,7 +47,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
47 return .indirect;47 return .indirect;
48 }48 }
49 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]);49 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);
51 if (explicit_align != .none) {51 if (explicit_align != .none) {
52 if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu)))52 if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu)))
53 return .indirect;53 return .indirect;
...@@ -56,7 +56,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {...@@ -56,7 +56,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
56 },56 },
57 .@"union" => {57 .@"union" => {
58 const union_obj = zcu.typeToUnion(ty).?;58 const union_obj = zcu.typeToUnion(ty).?;
59 if (union_obj.flagsUnordered(ip).layout == .@"packed") {59 if (union_obj.layout == .@"packed") {
60 return .{ .direct = ty };60 return .{ .direct = ty };
61 }61 }
62 const layout = ty.unionGetLayout(zcu);62 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 {...@@ -43261,7 +43261,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43261 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });43261 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
43262 try ops[0].toSlicePtr(cg);43262 try ops[0].toSlicePtr(cg);
43263 var res: [1]Temp = undefined;43263 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 &.{ .{
43265 .patterns = &.{43265 .patterns = &.{
43266 .{ .src = .{ .to_gpr, .simm32, .none } },43266 .{ .src = .{ .to_gpr, .simm32, .none } },
43267 },43267 },
...@@ -43375,7 +43375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43375,7 +43375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43375 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });43375 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
43376 try ops[0].toSlicePtr(cg);43376 try ops[0].toSlicePtr(cg);
43377 var res: [1]Temp = undefined;43377 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 &.{ .{
43379 .patterns = &.{43379 .patterns = &.{
43380 .{ .src = .{ .to_gpr, .simm32, .none } },43380 .{ .src = .{ .to_gpr, .simm32, .none } },
43381 },43381 },
...@@ -103699,7 +103699,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103699,7 +103699,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103699 .optional_payload => {103699 .optional_payload => {
103700 const ty_op = air_datas[@intFromEnum(inst)].ty_op;103700 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
103701 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});103701 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))
103703 try ops[0].read(ty_op.ty.toType(), .{}, cg)103703 try ops[0].read(ty_op.ty.toType(), .{}, cg)
103704 else103704 else
103705 try cg.tempInit(ty_op.ty.toType(), .none);103705 try cg.tempInit(ty_op.ty.toType(), .none);
...@@ -103745,7 +103745,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103745,7 +103745,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103745 const eu_pl_ty = ty_op.ty.toType();103745 const eu_pl_ty = ty_op.ty.toType();
103746 const eu_pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(eu_pl_ty, zcu));103746 const eu_pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(eu_pl_ty, zcu));
103747 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});103747 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))
103749 try ops[0].read(eu_pl_ty, .{ .disp = eu_pl_off }, cg)103749 try ops[0].read(eu_pl_ty, .{ .disp = eu_pl_off }, cg)
103750 else103750 else
103751 try cg.tempInit(eu_pl_ty, .none);103751 try cg.tempInit(eu_pl_ty, .none);
...@@ -103864,7 +103864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103864,7 +103864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103864 .@"packed" => unreachable,103864 .@"packed" => unreachable,
103865 };103865 };
103866 var ops = try cg.tempsFromOperands(inst, .{struct_field.struct_operand});103866 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))
103868 try ops[0].read(field_ty, .{ .disp = field_off }, cg)103868 try ops[0].read(field_ty, .{ .disp = field_off }, cg)
103869 else103869 else
103870 try cg.tempInit(field_ty, .none);103870 try cg.tempInit(field_ty, .none);
...@@ -103926,7 +103926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103926,7 +103926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103926 .array_elem_val, .legalize_vec_elem_val => {103926 .array_elem_val, .legalize_vec_elem_val => {
103927 const bin_op = air_datas[@intFromEnum(inst)].bin_op;103927 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
103928 const array_ty = cg.typeOf(bin_op.lhs);103928 const array_ty = cg.typeOf(bin_op.lhs);
103929 const res_ty = array_ty.elemType2(zcu);103929 const res_ty = array_ty.childType(zcu);
103930 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });103930 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
103931 var res: [1]Temp = undefined;103931 var res: [1]Temp = undefined;
103932 cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{103932 cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
...@@ -104121,11 +104121,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104121,11 +104121,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104121 },104121 },
104122 .slice_elem_val, .ptr_elem_val => {104122 .slice_elem_val, .ptr_elem_val => {
104123 const bin_op = air_datas[@intFromEnum(inst)].bin_op;104123 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);
104125 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });104125 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
104126 try ops[0].toSlicePtr(cg);104126 try ops[0].toSlicePtr(cg);
104127 var res: [1]Temp = undefined;104127 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 &.{ .{
104129 .dst_constraints = .{ .{ .int = .byte }, .any },104129 .dst_constraints = .{ .{ .int = .byte }, .any },
104130 .patterns = &.{104130 .patterns = &.{
104131 .{ .src = .{ .to_gpr, .simm32, .none } },104131 .{ .src = .{ .to_gpr, .simm32, .none } },
...@@ -171422,10 +171422,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171422,10 +171422,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171422 .auto, .@"extern" => {171422 .auto, .@"extern" => {
171423 for (elems, 0..) |elem_ref, field_index| {171423 for (elems, 0..) |elem_ref, field_index| {
171424 const elem_dies = bt.feed();171424 const elem_dies = bt.feed();
171425 if (loaded_struct.fieldIsComptime(ip, field_index)) continue;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]).hasRuntimeBitsIgnoreComptime(zcu)) {171426 if (!hack_around_sema_opv_bugs or Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]).hasRuntimeBits(zcu)) {
171427 var elem = try cg.tempFromOperand(elem_ref, elem_dies);171427 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);
171429 try elem.die(cg);171429 try elem.die(cg);
171430 try cg.resetTemps(reset_index);171430 try cg.resetTemps(reset_index);
171431 }171431 }
...@@ -171441,7 +171441,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171441,7 +171441,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171441 const elem_dies = bt.feed();171441 const elem_dies = bt.feed();
171442 if (tuple_type.values.get(ip)[field_index] != .none) continue;171442 if (tuple_type.values.get(ip)[field_index] != .none) continue;
171443 const field_type = Type.fromInterned(tuple_type.types.get(ip)[field_index]);171443 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)) {
171445 elem_disp = @intCast(field_type.abiAlignment(zcu).forward(elem_disp));171445 elem_disp = @intCast(field_type.abiAlignment(zcu).forward(elem_disp));
171446 var elem = try cg.tempFromOperand(elem_ref, elem_dies);171446 var elem = try cg.tempFromOperand(elem_ref, elem_dies);
171447 try res.write(&elem, .{ .disp = elem_disp }, cg);171447 try res.write(&elem, .{ .disp = elem_disp }, cg);
...@@ -171467,7 +171467,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171467,7 +171467,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171467 const union_layout = union_ty.unionGetLayout(zcu);171467 const union_layout = union_ty.unionGetLayout(zcu);
171468 if (union_layout.tag_size > 0) {171468 if (union_layout.tag_size > 0) {
171469 var tag_temp = try cg.tempFromValue(try pt.enumValueFieldIndex(171469 var tag_temp = try cg.tempFromValue(try pt.enumValueFieldIndex(
171470 union_ty.unionTagTypeSafety(zcu).?,171470 union_ty.unionTagTypeRuntime(zcu).?,
171471 union_init.field_index,171471 union_init.field_index,
171472 ));171472 ));
171473 try res.write(&tag_temp, .{171473 try res.write(&tag_temp, .{
...@@ -173756,7 +173756,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -173756,7 +173756,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173756173756
173757 var data_off: i32 = 0;173757 var data_off: i32 = 0;
173758 const reset_index = cg.next_temp_index;173758 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;
173760 for (0..tag_names.len) |tag_index| {173760 for (0..tag_names.len) |tag_index| {
173761 var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {173761 var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {
173762 else => unreachable,173762 else => unreachable,
...@@ -174334,7 +174334,7 @@ fn genUnwrapErrUnionPayloadMir(...@@ -174334,7 +174334,7 @@ fn genUnwrapErrUnionPayloadMir(
174334 const payload_ty = err_union_ty.errorUnionPayload(zcu);174334 const payload_ty = err_union_ty.errorUnionPayload(zcu);
174335174335
174336 const result: MCValue = result: {174336 const result: MCValue = result: {
174337 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;174337 if (!payload_ty.hasRuntimeBits(zcu)) break :result .none;
174338174338
174339 const payload_off: u31 = @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));174339 const payload_off: u31 = @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));
174340 switch (err_union) {174340 switch (err_union) {
...@@ -174450,7 +174450,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE...@@ -174450,7 +174450,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE
174450 const pt = self.pt;174450 const pt = self.pt;
174451 const zcu = pt.zcu;174451 const zcu = pt.zcu;
174452 const dst_ty = ptr_ty.childType(zcu);174452 const dst_ty = ptr_ty.childType(zcu);
174453 if (!dst_ty.hasRuntimeBitsIgnoreComptime(zcu)) return;174453 if (!dst_ty.hasRuntimeBits(zcu)) return;
174454 switch (ptr_mcv) {174454 switch (ptr_mcv) {
174455 .none,174455 .none,
174456 .unreach,174456 .unreach,
...@@ -174503,7 +174503,7 @@ fn store(...@@ -174503,7 +174503,7 @@ fn store(
174503 const pt = self.pt;174503 const pt = self.pt;
174504 const zcu = pt.zcu;174504 const zcu = pt.zcu;
174505 const src_ty = ptr_ty.childType(zcu);174505 const src_ty = ptr_ty.childType(zcu);
174506 if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return;174506 if (!src_ty.hasRuntimeBits(zcu)) return;
174507 switch (ptr_mcv) {174507 switch (ptr_mcv) {
174508 .none,174508 .none,
174509 .unreach,174509 .unreach,
...@@ -176615,7 +176615,7 @@ fn lowerSwitchBr(...@@ -176615,7 +176615,7 @@ fn lowerSwitchBr(
176615 break :condition_index condition_index;176615 break :condition_index condition_index;
176616 };176616 };
176617 try cg.spillEflagsIfOccupied();176617 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(
176619 .{ ._, .sub },176619 .{ ._, .sub },
176620 condition_ty,176620 condition_ty,
176621 condition_index,176621 condition_index,
...@@ -176957,7 +176957,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -176957,7 +176957,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void {
176957 const unsigned_condition_ty = try self.pt.intType(.unsigned, self.intInfo(condition_ty).?.bits);176957 const unsigned_condition_ty = try self.pt.intType(.unsigned, self.intInfo(condition_ty).?.bits);
176958 const condition_mcv = block_tracking.short;176958 const condition_mcv = block_tracking.short;
176959 try self.spillEflagsIfOccupied();176959 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(
176961 .{ ._, .sub },176961 .{ ._, .sub },
176962 condition_ty,176962 condition_ty,
176963 condition_mcv,176963 condition_mcv,
...@@ -177054,8 +177054,7 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -177054,8 +177054,7 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void {
177054 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;177054 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
177055177055
177056 const block_ty = self.typeOfIndex(br.block_inst);177056 const block_ty = self.typeOfIndex(br.block_inst);
177057 const block_unused =177057 const block_unused = !block_ty.hasRuntimeBits(zcu) or self.liveness.isUnused(br.block_inst);
177058 !block_ty.hasRuntimeBitsIgnoreComptime(zcu) or self.liveness.isUnused(br.block_inst);
177059 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;177058 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
177060 const block_data = self.blocks.getPtr(br.block_inst).?;177059 const block_data = self.blocks.getPtr(br.block_inst).?;
177061 const first_br = block_data.relocs.items.len == 0;177060 const first_br = block_data.relocs.items.len == 0;
...@@ -177295,41 +177294,38 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -177295,41 +177294,38 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177295 }177294 }
177296177295
177297 const ip = &zcu.intern_pool;177296 const ip = &zcu.intern_pool;
177298 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;177297 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
177299 const struct_type: Type = .fromInterned(aggregate.ty);177298 const clobbers_ty = clobbers_val.typeOf(zcu);
177300 switch (aggregate.storage) {177299 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
177301 .elems => |elems| for (elems, 0..) |elem, i| switch (elem) {177300 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
177302 .bool_true => {177301 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
177303 const clobber = struct_type.structFieldName(i, zcu).toSlice(ip).?;177302 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
177304 assert(clobber.len != 0);177303 const limb_bits = @bitSizeOf(std.math.big.Limb);
177305177304 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
177306 if (std.mem.eql(u8, clobber, "memory") or177305 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
177307 std.mem.eql(u8, clobber, "fpsr") or177306 0 => continue, // field is false
177308 std.mem.eql(u8, clobber, "fpcr") or177307 1 => {}, // field is true
177309 std.mem.eql(u8, clobber, "mxcsr") or177308 }
177310 std.mem.eql(u8, clobber, "dirflag"))177309 const clobber = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
177311 {177310 assert(clobber.len != 0);
177312 // ok, sure177311
177313 } else if (std.mem.eql(u8, clobber, "cc") or177312 if (std.mem.eql(u8, clobber, "memory") or
177314 std.mem.eql(u8, clobber, "flags") or177313 std.mem.eql(u8, clobber, "fpsr") or
177315 std.mem.eql(u8, clobber, "eflags") or177314 std.mem.eql(u8, clobber, "fpcr") or
177316 std.mem.eql(u8, clobber, "rflags"))177315 std.mem.eql(u8, clobber, "mxcsr") or
177317 {177316 std.mem.eql(u8, clobber, "dirflag"))
177318 try self.spillEflagsIfOccupied();177317 {
177319 } else {177318 // ok, sure
177320 try self.register_manager.getReg(parseRegName(clobber) orelse177319 } else if (std.mem.eql(u8, clobber, "cc") or
177321 return self.fail("invalid clobber: '{s}'", .{clobber}), null);177320 std.mem.eql(u8, clobber, "flags") or
177322 }177321 std.mem.eql(u8, clobber, "eflags") or
177323 },177322 std.mem.eql(u8, clobber, "rflags"))
177324 .bool_false => continue,177323 {
177325 else => unreachable,177324 try self.spillEflagsIfOccupied();
177326 },177325 } else {
177327 .repeated_elem => |elem| switch (elem) {177326 try self.register_manager.getReg(parseRegName(clobber) orelse
177328 .bool_true => @panic("TODO"),177327 return self.fail("invalid clobber: '{s}'", .{clobber}), null);
177329 .bool_false => {},177328 }
177330 else => unreachable,
177331 },
177332 .bytes => @panic("TODO"),
177333 }177329 }
177334177330
177335 const Label = struct {177331 const Label = struct {
...@@ -180986,7 +180982,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -180986,7 +180982,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue {
180986 const ty = self.typeOf(ref);180982 const ty = self.typeOf(ref);
180987180983
180988 // If the type has no codegen bits, no need to store it.180984 // 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
180991 const mcv: MCValue = if (ref.toIndex()) |inst| mcv: {180987 const mcv: MCValue = if (ref.toIndex()) |inst| mcv: {
180992 break :mcv self.inst_tracking.getPtr(inst).?.short;180988 break :mcv self.inst_tracking.getPtr(inst).?.short;
...@@ -181105,7 +181101,7 @@ fn resolveCallingConventionValues(...@@ -181105,7 +181101,7 @@ fn resolveCallingConventionValues(
181105 // Return values181101 // Return values
181106 if (ret_ty.isNoReturn(zcu)) {181102 if (ret_ty.isNoReturn(zcu)) {
181107 result.return_value = .init(.unreach);181103 result.return_value = .init(.unreach);
181108 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {181104 } else if (!ret_ty.hasRuntimeBits(zcu)) {
181109 // TODO: is this even possible for C calling convention?181105 // TODO: is this even possible for C calling convention?
181110 result.return_value = .init(.none);181106 result.return_value = .init(.none);
181111 } else {181107 } else {
...@@ -181115,7 +181111,7 @@ fn resolveCallingConventionValues(...@@ -181115,7 +181111,7 @@ fn resolveCallingConventionValues(
181115 var ret_sse = abi.getCAbiSseReturnRegs(cc);181111 var ret_sse = abi.getCAbiSseReturnRegs(cc);
181116 var ret_x87 = abi.getCAbiX87ReturnRegs(cc);181112 var ret_x87 = abi.getCAbiX87ReturnRegs(cc);
181117181113
181118 const classes = switch (cc) {181114 const classes: []const abi.Class = switch (cc) {
181119 .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, cg.target, .ret), .none),181115 .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, cg.target, .ret), .none),
181120 .x86_64_win => &.{abi.classifyWindows(ret_ty, zcu, cg.target, .ret)},181116 .x86_64_win => &.{abi.classifyWindows(ret_ty, zcu, cg.target, .ret)},
181121 else => unreachable,181117 else => unreachable,
...@@ -181182,7 +181178,7 @@ fn resolveCallingConventionValues(...@@ -181182,7 +181178,7 @@ fn resolveCallingConventionValues(
181182181178
181183 // Input params181179 // Input params
181184 params: for (param_types, result.args) |ty, *arg| {181180 params: for (param_types, result.args) |ty, *arg| {
181185 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));181181 assert(ty.hasRuntimeBits(zcu));
181186 result.air_arg_count += 1;181182 result.air_arg_count += 1;
181187 switch (cc) {181183 switch (cc) {
181188 .x86_64_sysv => {},181184 .x86_64_sysv => {},
...@@ -181327,7 +181323,7 @@ fn resolveCallingConventionValues(...@@ -181327,7 +181323,7 @@ fn resolveCallingConventionValues(
181327 // Return values181323 // Return values
181328 result.return_value = if (ret_ty.isNoReturn(zcu))181324 result.return_value = if (ret_ty.isNoReturn(zcu))
181329 .init(.unreach)181325 .init(.unreach)
181330 else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu))181326 else if (!ret_ty.hasRuntimeBits(zcu))
181331 .init(.none)181327 .init(.none)
181332 else return_value: {181328 else return_value: {
181333 const ret_gpr = abi.getCAbiIntReturnRegs(cc);181329 const ret_gpr = abi.getCAbiIntReturnRegs(cc);
...@@ -181357,7 +181353,7 @@ fn resolveCallingConventionValues(...@@ -181357,7 +181353,7 @@ fn resolveCallingConventionValues(
181357181353
181358 // Input params181354 // Input params
181359 for (param_types, result.args) |param_ty, *arg| {181355 for (param_types, result.args) |param_ty, *arg| {
181360 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) {181356 if (!param_ty.hasRuntimeBits(zcu)) {
181361 arg.* = .none;181357 arg.* = .none;
181362 continue;181358 continue;
181363 }181359 }
...@@ -181721,7 +181717,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {...@@ -181721,7 +181717,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
181721 .one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },181717 .one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
181722 .slice => null,181718 .slice => null,
181723 },181719 },
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))
181725 .{ .signedness = .unsigned, .bits = 1 }181721 .{ .signedness = .unsigned, .bits = 1 }
181726 else switch (ip.indexToKey(opt_child)) {181722 else switch (ip.indexToKey(opt_child)) {
181727 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {181723 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
...@@ -181734,7 +181730,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {...@@ -181734,7 +181730,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
181734 else => null,181730 else => null,
181735 },181731 },
181736 .error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type)181732 .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,
181738 .simple_type => |simple_type| return switch (simple_type) {181734 .simple_type => |simple_type| return switch (simple_type) {
181739 .bool => .{ .signedness = .unsigned, .bits = 1 },181735 .bool => .{ .signedness = .unsigned, .bits = 1 },
181740 .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },181736 .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
...@@ -181767,14 +181763,17 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {...@@ -181767,14 +181763,17 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
181767 const loaded_struct = ip.loadStructType(ty_index);181763 const loaded_struct = ip.loadStructType(ty_index);
181768 switch (loaded_struct.layout) {181764 switch (loaded_struct.layout) {
181769 .auto, .@"extern" => return null,181765 .auto, .@"extern" => return null,
181770 .@"packed" => ty_index = loaded_struct.backingIntTypeUnordered(ip),181766 .@"packed" => ty_index = loaded_struct.packed_backing_int_type,
181771 }181767 }
181772 },181768 },
181773 .union_type => return switch (ip.loadUnionType(ty_index).flagsUnordered(ip).layout) {181769 .union_type => {
181774 .auto, .@"extern" => null,181770 const loaded_union = ip.loadUnionType(ty_index);
181775 .@"packed" => .{ .signedness = .unsigned, .bits = @intCast(ty.bitSize(zcu)) },181771 switch (loaded_union.layout) {
181772 .auto, .@"extern" => return null,
181773 .@"packed" => ty_index = loaded_union.packed_backing_int_type,
181774 }
181776 },181775 },
181777 .enum_type => ty_index = ip.loadEnumType(ty_index).tag_ty,181776 .enum_type => ty_index = ip.loadEnumType(ty_index).int_tag_type,
181778 .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },181777 .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
181779 else => return null,181778 else => return null,
181780 };181779 };
...@@ -187919,7 +187918,6 @@ const Select = struct {...@@ -187919,7 +187918,6 @@ const Select = struct {
187919 unsigned_int: Memory.Size,187918 unsigned_int: Memory.Size,
187920 elem_size_is: u8,187919 elem_size_is: u8,
187921 po2_elem_size,187920 po2_elem_size,
187922 elem_int: Memory.Size,
187923187921
187924 const OfIsSizes = struct { of: Memory.Size, is: Memory.Size };187922 const OfIsSizes = struct { of: Memory.Size, is: Memory.Size };
187925187923
...@@ -188178,12 +188176,8 @@ const Select = struct {...@@ -188178,12 +188176,8 @@ const Select = struct {
188178 .signed => false,188176 .signed => false,
188179 .unsigned => size.bitSize(cg.target) >= int_info.bits,188177 .unsigned => size.bitSize(cg.target) >= int_info.bits,
188180 } else false,188178 } else false,
188181 .elem_size_is => |size| size == ty.elemType2(zcu).abiSize(zcu),188179 .elem_size_is => |size| size == ty.indexableElem(zcu).abiSize(zcu),
188182 .po2_elem_size => std.math.isPowerOfTwo(ty.elemType2(zcu).abiSize(zcu)),188180 .po2_elem_size => std.math.isPowerOfTwo(ty.indexableElem(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,
188187 };188181 };
188188 }188182 }
188189 };188183 };
...@@ -189918,20 +189912,20 @@ const Select = struct {...@@ -189918,20 +189912,20 @@ const Select = struct {
189918 .dst0_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).abiSize(s.cg.pt.zcu)),189912 .dst0_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).abiSize(s.cg.pt.zcu)),
189919 .delta_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu))) -189913 .delta_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu))) -
189920 @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).abiSize(s.cg.pt.zcu)))),189914 @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))) -189915 .delta_elem_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).scalarType(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)))),189916 @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)))),
189923 .unaligned_size => @intCast(s.cg.unalignedSize(op.flags.base.ref.typeOf(s))),189917 .unaligned_size => @intCast(s.cg.unalignedSize(op.flags.base.ref.typeOf(s))),
189924 .unaligned_size_add_elem_size => {189918 .unaligned_size_add_elem_size => {
189925 const ty = op.flags.base.ref.typeOf(s);189919 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));
189927 },189921 },
189928 .unaligned_size_sub_elem_size => {189922 .unaligned_size_sub_elem_size => {
189929 const ty = op.flags.base.ref.typeOf(s);189923 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));
189931 },189925 },
189932 .unaligned_size_sub_2_elem_size => {189926 .unaligned_size_sub_2_elem_size => {
189933 const ty = op.flags.base.ref.typeOf(s);189927 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);
189935 },189929 },
189936 .bit_size => @intCast(s.cg.nonBoolScalarBitSize(op.flags.base.ref.typeOf(s))),189930 .bit_size => @intCast(s.cg.nonBoolScalarBitSize(op.flags.base.ref.typeOf(s))),
189937 .src0_bit_size => @intCast(s.cg.nonBoolScalarBitSize(Select.Operand.Ref.src0.typeOf(s))),189931 .src0_bit_size => @intCast(s.cg.nonBoolScalarBitSize(Select.Operand.Ref.src0.typeOf(s))),
...@@ -189944,10 +189938,10 @@ const Select = struct {...@@ -189944,10 +189938,10 @@ const Select = struct {
189944 op.flags.base.ref.typeOf(s).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu),189938 op.flags.base.ref.typeOf(s).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu),
189945 @divExact(op.flags.base.size.bitSize(s.cg.target), 8),189939 @divExact(op.flags.base.size.bitSize(s.cg.target), 8),
189946 )),189940 )),
189947 .elem_size => @intCast(op.flags.base.ref.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)),
189948 .src0_elem_size => @intCast(Select.Operand.Ref.src0.typeOf(s).elemType2(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)),
189949 .dst0_elem_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).elemType2(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)),
189950 .src0_elem_size_mul_src1 => @intCast(Select.Operand.Ref.src0.typeOf(s).elemType2(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) *
189951 Select.Operand.Ref.src1.valueOf(s).immediate),189945 Select.Operand.Ref.src1.valueOf(s).immediate),
189952 .vector_index => switch (op.flags.base.ref.typeOf(s).ptrInfo(s.cg.pt.zcu).flags.vector_index) {189946 .vector_index => switch (op.flags.base.ref.typeOf(s).ptrInfo(s.cg.pt.zcu).flags.vector_index) {
189953 .none => unreachable,189947 .none => unreachable,
...@@ -189956,7 +189950,7 @@ const Select = struct {...@@ -189956,7 +189950,7 @@ const Select = struct {
189956 .src1 => @intCast(Select.Operand.Ref.src1.valueOf(s).immediate),189950 .src1 => @intCast(Select.Operand.Ref.src1.valueOf(s).immediate),
189957 .src1_sub_bit_size => @as(SignedImm, @intCast(Select.Operand.Ref.src1.valueOf(s).immediate)) -189951 .src1_sub_bit_size => @as(SignedImm, @intCast(Select.Operand.Ref.src1.valueOf(s).immediate)) -
189958 @as(SignedImm, @intCast(s.cg.nonBoolScalarBitSize(op.flags.base.ref.typeOf(s)))),189952 @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))),
189960 .elem_mask => @as(u8, std.math.maxInt(u8)) >> @intCast(189954 .elem_mask => @as(u8, std.math.maxInt(u8)) >> @intCast(
189961 8 - ((s.cg.unalignedSize(op.flags.base.ref.typeOf(s)) - 1) %189955 8 - ((s.cg.unalignedSize(op.flags.base.ref.typeOf(s)) - 1) %
189962 @divExact(op.flags.base.size.bitSize(s.cg.target), 8) + 1 >>189956 @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(...@@ -339,7 +339,7 @@ fn classifySystemVStruct(
339 var field_it = loaded_struct.iterateRuntimeOrder(ip);339 var field_it = loaded_struct.iterateRuntimeOrder(ip);
340 while (field_it.next()) |field_index| {340 while (field_it.next()) |field_index| {
341 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);341 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);
343 byte_offset = std.mem.alignForward(343 byte_offset = std.mem.alignForward(
344 u64,344 u64,
345 byte_offset,345 byte_offset,
...@@ -355,7 +355,7 @@ fn classifySystemVStruct(...@@ -355,7 +355,7 @@ fn classifySystemVStruct(
355 .@"packed" => {},355 .@"packed" => {},
356 }356 }
357 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {357 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {
358 switch (field_loaded_union.flagsUnordered(ip).layout) {358 switch (field_loaded_union.layout) {
359 .auto => unreachable,359 .auto => unreachable,
360 .@"extern" => {360 .@"extern" => {
361 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target);361 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target);
...@@ -369,11 +369,11 @@ fn classifySystemVStruct(...@@ -369,11 +369,11 @@ fn classifySystemVStruct(
369 result_class.* = result_class.combineSystemV(field_class);369 result_class.* = result_class.combineSystemV(field_class);
370 byte_offset += field_ty.abiSize(zcu);370 byte_offset += field_ty.abiSize(zcu);
371 }371 }
372 const final_byte_offset = starting_byte_offset + loaded_struct.sizeUnordered(ip);372 const final_byte_offset = starting_byte_offset + loaded_struct.size;
373 std.debug.assert(final_byte_offset == std.mem.alignForward(373 std.debug.assert(final_byte_offset == std.mem.alignForward(
374 u64,374 u64,
375 byte_offset,375 byte_offset,
376 loaded_struct.flagsUnordered(ip).alignment.toByteUnits().?,376 loaded_struct.alignment.toByteUnits().?,
377 ));377 ));
378 return final_byte_offset;378 return final_byte_offset;
379}379}
...@@ -398,7 +398,7 @@ fn classifySystemVUnion(...@@ -398,7 +398,7 @@ fn classifySystemVUnion(
398 .@"packed" => {},398 .@"packed" => {},
399 }399 }
400 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {400 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {
401 switch (field_loaded_union.flagsUnordered(ip).layout) {401 switch (field_loaded_union.layout) {
402 .auto => unreachable,402 .auto => unreachable,
403 .@"extern" => {403 .@"extern" => {
404 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target);404 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target);
...@@ -411,7 +411,7 @@ fn classifySystemVUnion(...@@ -411,7 +411,7 @@ fn classifySystemVUnion(
411 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|411 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
412 result_class.* = result_class.combineSystemV(field_class);412 result_class.* = result_class.combineSystemV(field_class);
413 }413 }
414 return starting_byte_offset + loaded_union.sizeUnordered(ip);414 return starting_byte_offset + loaded_union.size;
415}415}
416416
417pub const zigcc = struct {417pub const zigcc = struct {
src/link.zig+40-13
...@@ -29,6 +29,7 @@ const codegen = @import("codegen.zig");...@@ -29,6 +29,7 @@ const codegen = @import("codegen.zig");
29pub const aarch64 = @import("link/aarch64.zig");29pub const aarch64 = @import("link/aarch64.zig");
30pub const LdScript = @import("link/LdScript.zig");30pub const LdScript = @import("link/LdScript.zig");
31pub const Queue = @import("link/Queue.zig");31pub const Queue = @import("link/Queue.zig");
32pub const ConstPool = @import("link/ConstPool.zig");
3233
33pub const Diags = struct {34pub const Diags = struct {
34 /// Stored here so that function definitions can distinguish between35 /// Stored here so that function definitions can distinguish between
...@@ -798,14 +799,27 @@ pub const File = struct {...@@ -798,14 +799,27 @@ pub const File = struct {
798 };799 };
799800
800 /// Never called when LLVM is codegenning the ZCU.801 /// 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 {
802 assert(base.comp.zcu.?.llvm_object == null);816 assert(base.comp.zcu.?.llvm_object == null);
803 switch (base.tag) {817 switch (base.tag) {
804 .lld => unreachable,818 .lld => unreachable,
805 else => {},819 else => {},
806 inline .elf => |tag| {820 inline .elf => |tag| {
807 dev.check(tag.devFeature());821 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);
809 },823 },
810 }824 }
811 }825 }
...@@ -1375,8 +1389,14 @@ pub const ZcuTask = union(enum) {...@@ -1375,8 +1389,14 @@ pub const ZcuTask = union(enum) {
1375 link_nav: InternPool.Nav.Index,1389 link_nav: InternPool.Nav.Index,
1376 /// Write the machine code for a function to the output file.1390 /// Write the machine code for a function to the output file.
1377 link_func: Zcu.CodegenTaskPool.Index,1391 link_func: Zcu.CodegenTaskPool.Index,
1378 link_type: InternPool.Index,1392 /// This struct/union/enum type has finished type resolution (successfully or otherwise), so the
1379 update_line_number: InternPool.TrackedInst.Index,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,
1380};1400};
13811401
1382pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {1402pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
...@@ -1537,7 +1557,10 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void...@@ -1537,7 +1557,10 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
1537 .link_func => |codegen_task| nav: {1557 .link_func => |codegen_task| nav: {
1538 timer.pause(io);1558 timer.pause(io);
1539 const func, var mir = codegen_task.wait(&zcu.codegen_task_pool, io) catch |err| switch (err) {1559 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 },
1541 };1564 };
1542 defer mir.deinit(zcu);1565 defer mir.deinit(zcu);
1543 timer.@"resume"(io);1566 timer.@"resume"(io);
...@@ -1563,21 +1586,25 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void...@@ -1563,21 +1586,25 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
1563 }1586 }
1564 break :nav ip.indexToKey(func).func.owner_nav;1587 break :nav ip.indexToKey(func).func.owner_nav;
1565 },1588 },
1566 .link_type => |ty| nav: {1589 .debug_update_container_type => |container_update| nav: {
1567 const name = Type.fromInterned(ty).containerTypeName(ip).toSlice(ip);1590 const name = Type.fromInterned(container_update.ty).containerTypeName(ip).toSlice(ip);
1568 const nav_prog_node = comp.link_prog_node.start(name, 0);1591 const ty_prog_node = comp.link_prog_node.start(name, 0);
1569 defer nav_prog_node.end();1592 defer ty_prog_node.end();
1570 if (zcu.llvm_object == null) {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 {
1571 if (comp.bin_file) |lf| {1598 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) {
1573 error.OutOfMemory => diags.setAllocFailure(),1600 error.OutOfMemory => diags.setAllocFailure(),
1574 error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),1601 error.TypeFailureReported => assert(zcu.failed_types.contains(container_update.ty)),
1575 };1602 };
1576 }1603 }
1577 }1604 }
1578 break :nav null;1605 break :nav null;
1579 },1606 },
1580 .update_line_number => |ti| nav: {1607 .debug_update_line_number => |ti| nav: {
1581 const nav_prog_node = comp.link_prog_node.start("Update line number", 0);1608 const nav_prog_node = comp.link_prog_node.start("Update line number", 0);
1582 defer nav_prog_node.end();1609 defer nav_prog_node.end();
1583 if (pt.zcu.llvm_object == null) {1610 if (pt.zcu.llvm_object == null) {
src/link/C.zig+1272-627
...@@ -1,3 +1,9 @@...@@ -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
1const std = @import("std");7const std = @import("std");
2const mem = std.mem;8const mem = std.mem;
3const assert = std.debug.assert;9const assert = std.debug.assert;
...@@ -5,7 +11,6 @@ const Allocator = std.mem.Allocator;...@@ -5,7 +11,6 @@ const Allocator = std.mem.Allocator;
5const fs = std.fs;11const fs = std.fs;
6const Path = std.Build.Cache.Path;12const Path = std.Build.Cache.Path;
713
8const C = @This();
9const build_options = @import("build_options");14const build_options = @import("build_options");
10const Zcu = @import("../Zcu.zig");15const Zcu = @import("../Zcu.zig");
11const Module = @import("../Package/Module.zig");16const Module = @import("../Package/Module.zig");
...@@ -19,40 +24,45 @@ const Type = @import("../Type.zig");...@@ -19,40 +24,45 @@ const Type = @import("../Type.zig");
19const Value = @import("../Value.zig");24const Value = @import("../Value.zig");
20const AnyMir = @import("../codegen.zig").AnyMir;25const AnyMir = @import("../codegen.zig").AnyMir;
2126
22pub const zig_h = "#include \"zig.h\"\n";
23
24base: link.File,27base: link.File,
25/// This linker backend does not try to incrementally link output C source code.28
26/// Instead, it tracks all declarations in this table, and iterates over it29/// All the string bytes of rendered C code, all squished into one array. `String` is used to refer
27/// in the flush function, stitching pre-rendered pieces of C code together.30/// to specific slices of this array, used for the rendered C code of an individual UAV/NAV/type.
28navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvBlock),31///
29/// All the string bytes of rendered C code, all squished into one array.32/// During code generation for functions, a separate buffer is used, and the contents of that buffer
30/// While in progress, a separate buffer is used, and then when finished, the33/// are copied into `string_bytes` when the function is emitted by `updateFunc`.
31/// buffer is copied into this one.
32string_bytes: std.ArrayList(u8),34string_bytes: std.ArrayList(u8),
33/// Tracks all the anonymous decls that are used by all the decls so they can35
34/// be rendered during flush().36/// Like with `string_bytes`, we concatenate all type dependencies into one array, and slice into it
35uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, AvBlock),37/// for specific groups of dependencies. These values are indices into `type_pool`, and thus also
36/// Sparse set of uavs that are overaligned. Underaligned anon decls are38/// into `types`. We store these instead of `InternPool.Index` because it lets us avoid some hash
37/// lowered the same as ABI-aligned anon decls. The keys here are a subset of39/// map lookups in `flush`.
38/// the keys of `uavs`.40type_dependencies: std.ArrayList(link.ConstPool.Index),
39aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),41/// For storing dependencies on "aligned" versions of types, we must associate each type with a
4042/// bitmask of required alignments. As with `type_dependencies`, we concatenate all such masks into
41exported_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, ExportedBlock),43/// one array.
42exported_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock),44align_dependency_masks: std.ArrayList(u64),
4345
44/// Optimization, `updateDecl` reuses this buffer rather than creating a new46/// All NAVs, regardless of whether they are functions or simple constants, are put in this map.
45/// one with every call.47navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, RenderedDecl),
46fwd_decl_buf: []u8,48/// All UAVs which may be referenced are in this map. The UAV alignment is not included in the
47/// Optimization, `updateDecl` reuses this buffer rather than creating a new49/// rendered C code stored here, because we don't know the alignment a UAV needs until `flush`.
48/// one with every call.50uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, RenderedDecl),
49code_header_buf: []u8,51/// Contains all types which are needed by some other rendered code. Does not contain any constants
50/// Optimization, `updateDecl` reuses this buffer rather than creating a new52/// other than types.
51/// one with every call.53type_pool: link.ConstPool,
52code_buf: []u8,54/// Indices are `link.ConstPool.Index` from `type_pool`. Contains rendered C code for every type
53/// Optimization, `flush` reuses this buffer rather than creating a new55/// which may be referenced. Logic in `flush` will perform the appropriate topological sort to emit
54/// one with every call.56/// these type definitions in an order which C allows.
55scratch_buf: []u32,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
57/// A reference into `string_bytes`.67/// A reference into `string_bytes`.
58const String = extern struct {68const String = extern struct {
...@@ -64,50 +74,320 @@ const String = extern struct {...@@ -64,50 +74,320 @@ const String = extern struct {
64 .len = 0,74 .len = 0,
65 };75 };
6676
67 fn concat(lhs: String, rhs: String) String {77 fn get(s: String, c: *C) []const u8 {
68 assert(lhs.start + lhs.len == rhs.start);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..];
69 return .{111 return .{
70 .start = lhs.start,112 .type = types_overlong[0..td.len],
71 .len = lhs.len + rhs.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],
72 };118 };
73 }119 }
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 };
74};130};
75131
76/// Per-declaration data.132const RenderedDecl = struct {
77pub const AvBlock = struct {133 fwd_decl: String,
78 fwd_decl: String = .empty,134 code: String,
79 code: String = .empty,135 ctype_deps: CTypeDependencies,
80 /// Each `Decl` stores a set of used `CType`s. In `flush()`, we iterate136 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
81 /// over each `Decl` and generate the definition for each used `CType` once.137 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
82 ctype_pool: codegen.CType.Pool = .empty,138 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
83 /// May contain string references to ctype_pool139 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
84 lazy_fns: codegen.LazyFnMap = .{},140
85141 const init: RenderedDecl = .{
86 fn deinit(ab: *AvBlock, gpa: Allocator) void {142 .fwd_decl = .empty,
87 ab.lazy_fns.deinit(gpa);143 .code = .empty,
88 ab.ctype_pool.deinit(gpa);144 .ctype_deps = .empty,
89 ab.* = undefined;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();
90 }169 }
91};170};
92171
93/// Per-exported-symbol data.172const RenderedType = struct {
94pub const ExportedBlock = struct {173 /// If this type lowers to an aggregate, this is a forward declaration of its struct/union tag.
95 fwd_decl: String = .empty,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,
96};202};
97203
98pub fn getString(this: C, s: String) []const u8 {204/// Only called by `link.ConstPool` due to `c.type_pool`, so `val` is always a type.
99 return this.string_bytes.items[s.start..][0..s.len];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 }
100}267}
101268
102pub fn addString(this: *C, s: []const u8) Allocator.Error!String {269/// Only called by `link.ConstPool` due to `c.type_pool`, so `val` is always a type.
103 const comp = this.base.comp;270pub fn updateConstIncomplete(
104 const gpa = comp.gpa;271 c: *C,
105 try this.string_bytes.appendSlice(gpa, s);272 pt: Zcu.PerThread,
106 return .{273 index: link.ConstPool.Index,
107 .start = @intCast(this.string_bytes.items.len - s.len),274 val: InternPool.Index,
108 .len = @intCast(s.len),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 };
109 };303 };
110}304}
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
112pub fn open(392pub fn open(
113 arena: Allocator,393 arena: Allocator,
...@@ -156,267 +436,622 @@ pub fn createEmpty(...@@ -156,267 +436,622 @@ pub fn createEmpty(
156 .file = file,436 .file = file,
157 .build_id = options.build_id,437 .build_id = options.build_id,
158 },438 },
159 .navs = .empty,
160 .string_bytes = .empty,439 .string_bytes = .empty,
440 .type_dependencies = .empty,
441 .align_dependency_masks = .empty,
442 .navs = .empty,
161 .uavs = .empty,443 .uavs = .empty,
162 .aligned_uavs = .empty,444 .type_pool = .empty,
445 .types = .empty,
446 .bigint_types = .empty,
163 .exported_navs = .empty,447 .exported_navs = .empty,
164 .exported_uavs = .empty,448 .exported_uavs = .empty,
165 .fwd_decl_buf = &.{},
166 .code_header_buf = &.{},
167 .code_buf = &.{},
168 .scratch_buf = &.{},
169 };449 };
170450
171 return c_file;451 return c_file;
172}452}
173453
174pub fn deinit(self: *C) void {454pub fn deinit(c: *C) void {
175 const gpa = self.base.comp.gpa;455 const gpa = c.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);
187456
188 self.exported_navs.deinit(gpa);457 for (c.navs.values()) |*r| r.deinit(gpa);
189 self.exported_uavs.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);472pub fn updateContainerType(
192 gpa.free(self.fwd_decl_buf);473 c: *C,
193 gpa.free(self.code_header_buf);474 pt: Zcu.PerThread,
194 gpa.free(self.code_buf);475 ty: InternPool.Index,
195 gpa.free(self.scratch_buf);476 success: bool,
477) link.File.UpdateContainerTypeError!void {
478 try c.type_pool.updateContainerType(pt, .{ .c = c }, ty, success);
196}479}
197480
198pub fn updateFunc(481pub fn updateFunc(
199 self: *C,482 c: *C,
200 pt: Zcu.PerThread,483 pt: Zcu.PerThread,
201 func_index: InternPool.Index,484 func_index: InternPool.Index,
202 mir: *AnyMir,485 mir: *AnyMir,
203) link.File.UpdateNavError!void {486) Allocator.Error!void {
204 const zcu = pt.zcu;487 const zcu = pt.zcu;
205 const gpa = zcu.gpa;488 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);491 const rendered_decl: *RenderedDecl = rd: {
209 if (gop.found_existing) gop.value_ptr.deinit(gpa);492 const gop = try c.navs.getOrPut(gpa, nav);
210 gop.value_ptr.* = .{493 if (gop.found_existing) gop.value_ptr.deinit(gpa);
211 .code = .empty,494 break :rd gop.value_ptr;
212 .fwd_decl = .empty,
213 .ctype_pool = mir.c.ctype_pool.move(),
214 .lazy_fns = mir.c.lazy_fns.move(),
215 };495 };
216 gop.value_ptr.fwd_decl = try self.addString(mir.c.fwd_decl);496 c.navs.lockPointers();
217 const code_header = try self.addString(mir.c.code_header);497 defer c.navs.unlockPointers();
218 const code = try self.addString(mir.c.code);498
219 gop.value_ptr.code = code_header.concat(code);499 rendered_decl.* = .{
220 try self.addUavsFromCodegen(&mir.c.uavs);500 .fwd_decl = try c.addString(&.{mir.c.fwd_decl}),
221}501 .code = try c.addString(&.{ mir.c.code_header, mir.c.code }),
222502 .ctype_deps = try c.addCTypeDependencies(pt, &mir.c.ctype_deps),
223fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) link.File.FlushError!void {503 .need_uavs = mir.c.need_uavs.move(),
224 const gpa = self.base.comp.gpa;504 .need_tag_name_funcs = mir.c.need_tag_name_funcs.move(),
225 const uav = self.uavs.keys()[i];505 .need_never_tail_funcs = mir.c.need_never_tail_funcs.move(),
226506 .need_never_inline_funcs = mir.c.need_never_inline_funcs.move(),
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,
266 };507 };
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);521 try c.type_pool.flushPending(pt, .{ .c = c });
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 };
276}522}
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 {
279 const tracy = trace(@src());529 const tracy = trace(@src());
280 defer tracy.end();530 defer tracy.end();
281531
282 const gpa = self.base.comp.gpa;532 const gpa = c.base.comp.gpa;
283 const zcu = pt.zcu;533 const zcu = pt.zcu;
284 const ip = &zcu.intern_pool;534 const ip = &zcu.intern_pool;
285535
286 const nav = ip.getNav(nav_index);536 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)) {
288 .func => return,538 .func => return,
289 .@"extern" => .none,539 .@"extern" => {},
290 .variable => |variable| variable.init,540 else => {
291 else => nav.status.fully_resolved.val,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;
292 };560 };
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);564 {
296 errdefer _ = self.navs.pop();565 var arena: std.heap.ArenaAllocator = .init(gpa);
297 if (!gop.found_existing) gop.value_ptr.* = .{};566 defer arena.deinit();
298 const ctype_pool = &gop.value_ptr.ctype_pool;
299 try ctype_pool.init(gpa);
300 ctype_pool.clearRetainingCapacity();
301567
302 var object: codegen.Object = .{568 var dg: codegen.DeclGen = .{
303 .dg = .{
304 .gpa = gpa,569 .gpa = gpa,
570 .arena = arena.allocator(),
305 .pt = pt,571 .pt = pt,
306 .mod = zcu.navFileScope(nav_index).mod.?,572 .mod = zcu.navFileScope(nav_index).mod.?,
307 .error_msg = null,573 .error_msg = null,
308 .pass = .{ .nav = nav_index },574 .owner_nav = nav_index.toOptional(),
309 .is_naked_fn = false,575 .is_naked_fn = false,
310 .expected_block = null,576 .expected_block = null,
311 .fwd_decl = undefined,577 .ctype_deps = .empty,
312 .ctype_pool = ctype_pool.*,578 .uavs = rendered_decl.need_uavs.move(),
313 .scratch = .initBuffer(self.scratch_buf),579 };
314 .uavs = .empty,580
315 },581 defer {
316 .code_header = undefined,582 rendered_decl.need_uavs = dg.uavs.move();
317 .code = undefined,583 dg.ctype_deps.deinit(gpa);
318 .indent_counter = 0,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,
319 };670 };
320 object.dg.fwd_decl = .initOwnedSlice(gpa, self.fwd_decl_buf);
321 object.code = .initOwnedSlice(gpa, self.code_buf);
322 defer {671 defer {
323 object.dg.uavs.deinit(gpa);672 rendered_decl.need_uavs = dg.uavs.move();
324 ctype_pool.* = object.dg.ctype_pool.move();673 dg.ctype_deps.deinit(gpa);
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();
330 }674 }
331675
332 codegen.genDecl(&object) catch |err| switch (err) {676 rendered_decl.fwd_decl = fwd_decl: {
333 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, object.dg.error_msg.?)) {677 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
334 error.CodegenFail => return,678 defer c.string_bytes = aw.toArrayList();
335 error.OutOfMemory => |e| return e,679 const start = aw.written().len;
336 },680 codegen.genDeclValueFwd(&dg, &aw.writer, .{
337 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,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 };
338 };716 };
339 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.written());717
340 gop.value_ptr.code = try self.addString(object.code.written());718 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
341 try self.addUavsFromCodegen(&object.dg.uavs);
342}719}
343720
344pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {721pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) error{}!void {
345 // The C backend does not have the ability to fix line numbers without re-generating722 // The C backend does not currently emit "#line" directives. Even if it did, it would not be
346 // the entire Decl.723 // capable of updating those line numbers without re-generating the entire declaration.
347 _ = self;724 _ = c;
348 _ = pt;725 _ = pt;
349 _ = ti_id;726 _ = ti_id;
350}727}
351728
352fn abiDefines(w: *std.Io.Writer, target: *const std.Target) !void {729pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!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
365 const tracy = trace(@src());730 const tracy = trace(@src());
366 defer tracy.end();731 defer tracy.end();
367732
368 const sub_prog_node = prog_node.start("Flush Module", 0);733 const sub_prog_node = prog_node.start("Flush Module", 0);
369 defer sub_prog_node.end();734 defer sub_prog_node.end();
370735
371 const comp = self.base.comp;736 const comp = c.base.comp;
372 const diags = &comp.link_diags;737 const diags = &comp.link_diags;
373 const gpa = comp.gpa;738 const gpa = comp.gpa;
374 const io = comp.io;739 const io = comp.io;
375 const zcu = self.base.comp.zcu.?;740 const zcu = c.base.comp.zcu.?;
376 const ip = &zcu.intern_pool;741 const ip = &zcu.intern_pool;
742 const target = zcu.getTarget();
377 const pt: Zcu.PerThread = .activate(zcu, tid);743 const pt: Zcu.PerThread = .activate(zcu, tid);
378 defer pt.deactivate();744 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.
380 {848 {
381 var i: usize = 0;849 var index: usize = 0;
382 while (i < self.uavs.count()) : (i += 1) {850 while (need_uavs.count() > index) : (index += 1) {
383 try self.updateUav(pt, i);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);
384 }861 }
385 }862 }
386863
387 // This code path happens exclusively with -ofmt=c. The flush logic for864 // Finally, C types may reference other C types.
388 // emit-h is in `flushEmitH` below.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 = .{884 if (errunion_index < need_errunion_types.count()) {
391 .ctype_pool = .empty,885 const payload_pool_index = need_errunion_types.keys()[errunion_index];
392 .ctype_global_from_decl_map = .empty,886 const rendered = &c.types.items[@intFromEnum(payload_pool_index)];
393 .ctypes = .empty,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,898 if (aligned_index < need_aligned_types.count()) {
396 .lazy_fns = .empty,899 const pool_index = need_aligned_types.keys()[aligned_index];
397 .lazy_fwd_decl = .empty,900 const rendered = &c.types.items[@intFromEnum(pool_index)];
398 .lazy_code = .empty,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,912 break;
401 .file_size = 0,913 }
402 };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 };
403 defer f.deinit(gpa);978 defer f.deinit(gpa);
404979
405 var abi_defines_aw: std.Io.Writer.Allocating = .init(gpa);980 // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers!
406 defer abi_defines_aw.deinit();981
407 abiDefines(&abi_defines_aw.writer, zcu.getTarget()) catch |err| switch (err) {982 try f.all_buffers.ensureUnusedCapacity(gpa, 3 + // ABI defines and `#include "zig.h"`
408 error.WriteFailed => return error.OutOfMemory,983 1 + // Big-int type definitions
409 };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.1013 // Big-int type definitions
412 try f.all_buffers.ensureUnusedCapacity(gpa, 5);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());1023 // CType definitions
415 f.appendBufAssumeCapacity(zig_h);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;1043 for (need_types.keys()) |pool_index| {
418 f.all_buffers.items.len += 1;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
420 var asm_aw: std.Io.Writer.Allocating = .init(gpa);1055 var asm_aw: std.Io.Writer.Allocating = .init(gpa);
421 defer asm_aw.deinit();1056 defer asm_aw.deinit();
422 codegen.genGlobalAsm(zcu, &asm_aw.writer) catch |err| switch (err) {1057 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...@@ -424,462 +1059,472 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P
424 };1059 };
425 f.appendBufAssumeCapacity(asm_aw.written());1060 f.appendBufAssumeCapacity(asm_aw.written());
4261061
427 const lazy_index = f.all_buffers.items.len;1062 var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
428 f.all_buffers.items.len += 1;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);1075 // UAV export block
431 try self.flushErrDecls(pt, &f);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.1080 // NAV export block
434 // `CType`s, forward decls, and non-functions first.1081 for (c.exported_navs.values()) |code| {
1082 f.appendBufAssumeCapacity(code.get(c));
1083 }
4351084
436 {1085 // UAV forward declarations
437 var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;1086 for (need_uavs.keys()) |val| {
438 defer export_names.deinit(gpa);1087 if (c.exported_uavs.contains(val)) continue; // the export was the declaration
439 try export_names.ensureTotalCapacity(gpa, @intCast(zcu.single_exports.count()));1088 const fwd_decl = c.uavs.getPtr(val).?.fwd_decl;
440 for (zcu.single_exports.values()) |export_index| {1089 f.appendBufAssumeCapacity(fwd_decl.get(c));
441 export_names.putAssumeCapacity(export_index.ptr(zcu).opts.name, {});1090 }
442 }1091
443 for (zcu.multi_exports.values()) |info| {1092 // NAV forward declarations
444 try export_names.ensureUnusedCapacity(gpa, info.len);1093 for (need_navs.keys()) |nav| {
445 for (zcu.all_exports.items[info.index..][0..info.len]) |@"export"| {1094 if (c.exported_navs.contains(nav)) continue; // the export was the declaration
446 export_names.putAssumeCapacity(@"export".opts.name, {});1095 if (ip.getNav(nav).getExtern(ip)) |e| {
447 }1096 if (export_names.contains(e.name)) continue;
448 }1097 }
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(1102 // Lazy declarations
451 pt,1103 var lazy_decls_aw: std.Io.Writer.Allocating = .init(gpa);
452 zcu.root_mod,1104 defer lazy_decls_aw.deinit();
453 &f,1105 {
454 av_block,1106 var lazy_dg: codegen.DeclGen = .{
455 self.exported_uavs.getPtr(uav),1107 .gpa = gpa,
456 export_names,1108 .arena = arena,
457 .none,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,
458 );1127 );
4591128 const slice_const_u8_sentinel_0_name = try std.fmt.allocPrint(
460 for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock(1129 arena,
461 pt,1130 "{f}",
462 zcu.navFileScope(nav).mod.?,1131 .{slice_const_u8_sentinel_0_cty.fmtTypeName(zcu)},
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,
471 );1132 );
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 }
472 }1168 }
4731169 f.appendBufAssumeCapacity(lazy_decls_aw.written());
474 {1170
475 // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.1171 // UAV definitions
476 // This ensures that every lazy CType.Index exactly matches the global CType.Index.1172 for (need_uavs.keys(), need_uavs.values()) |val, overalign| {
477 try f.ctype_pool.init(gpa);1173 const code = c.uavs.getPtr(val).?.code;
478 try self.flushCTypes(zcu, &f, .flush, &f.lazy_ctype_pool);1174 if (code.len == 0) continue;
4791175 if (!c.exported_uavs.contains(val)) {
480 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| {1176 f.appendBufAssumeCapacity("static ");
481 try self.flushCTypes(zcu, &f, .{ .uav = uav }, &av_block.ctype_pool);
482 }1177 }
4831178 if (overalign != .none) {
484 for (self.navs.keys(), self.navs.values()) |nav, av_block| {1179 // As long as `Alignment` isn't too big, it's reasonable to just generate all possible
485 try self.flushCTypes(zcu, &f, .{ .nav = nav }, &av_block.ctype_pool);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()]);
486 }1194 }
1195 f.appendBufAssumeCapacity(code.get(c));
487 }1196 }
4881197
489 f.all_buffers.items[ctypes_index] = f.ctypes.items;1198 // NAV definitions
490 f.file_size += f.ctypes.items.len;1199 for (need_navs.keys()) |nav| {
4911200 const code = c.navs.getPtr(nav).?.code;
492 f.all_buffers.items[lazy_index] = f.lazy_fwd_decl.items;1201 if (code.len == 0) continue;
493 f.file_size += f.lazy_fwd_decl.items.len;1202 if (!c.exported_navs.contains(nav)) {
4941203 const is_extern = ip.getNav(nav).getExtern(ip) != null;
495 // Now the code.1204 f.appendBufAssumeCapacity(if (is_extern) "zig_extern " else "static ");
496 try f.all_buffers.ensureUnusedCapacity(gpa, 1 + (self.uavs.count() + self.navs.count()) * 2);1205 }
497 f.appendBufAssumeCapacity(f.lazy_code.items);1206 f.appendBufAssumeCapacity(code.get(c));
498 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| f.appendCodeAssumeCapacity(1207 }
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));
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.?;
512 file.setLength(io, f.file_size) catch |err| return diags.fail("failed to allocate file: {t}", .{err});1211 file.setLength(io, f.file_size) catch |err| return diags.fail("failed to allocate file: {t}", .{err});
513 var fw = file.writer(io, &.{});1212 var fw = file.writer(io, &.{});
514 var w = &fw.interface;1213 var w = &fw.interface;
515 w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {1214 w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {
516 error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{1215 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.?),
518 }),1217 }),
519 };1218 };
520}1219}
5211220
522const Flush = struct {1221const 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
532 /// We collect a list of buffers to write, and write them all at once with pwritev 😎1222 /// We collect a list of buffers to write, and write them all at once with pwritev 😎
533 all_buffers: std.ArrayList([]const u8),1223 all_buffers: std.ArrayList([]const u8),
534 /// Keeps track of the total bytes of `all_buffers`.1224 /// Keeps track of the total bytes of `all_buffers`.
535 file_size: u64,1225 file_size: u64,
5361226
537 const LazyFns = std.AutoHashMapUnmanaged(codegen.LazyFnKey, void);
538
539 fn appendBufAssumeCapacity(f: *Flush, buf: []const u8) void {1227 fn appendBufAssumeCapacity(f: *Flush, buf: []const u8) void {
540 if (buf.len == 0) return;1228 if (buf.len == 0) return;
541 f.all_buffers.appendAssumeCapacity(buf);1229 f.all_buffers.appendAssumeCapacity(buf);
542 f.file_size += buf.len;1230 f.file_size += buf.len;
543 }1231 }
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
555 fn deinit(f: *Flush, gpa: Allocator) void {1233 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);
564 f.all_buffers.deinit(gpa);1234 f.all_buffers.deinit(gpa);
565 }1235 }
566};1236};
5671237
568const FlushDeclError = error{1238pub fn updateExports(
569 OutOfMemory,1239 c: *C,
570};1240 pt: Zcu.PerThread,
5711241 exported: Zcu.Exported,
572fn flushCTypes(1242 export_indices: []const Zcu.Export.Index,
573 self: *C,1243) Allocator.Error!void {
574 zcu: *Zcu,1244 const zcu = pt.zcu;
575 f: *Flush,1245 const gpa = zcu.gpa;
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}
6301246
631fn flushErrDecls(self: *C, pt: Zcu.PerThread, f: *Flush) FlushDeclError!void {1247 var arena: std.heap.ArenaAllocator = .init(gpa);
632 const gpa = self.base.comp.gpa;1248 defer arena.deinit();
6331249
634 var object: codegen.Object = .{1250 var dg: codegen.DeclGen = .{
635 .dg = .{1251 .gpa = gpa,
636 .gpa = gpa,1252 .arena = arena.allocator(),
637 .pt = pt,1253 .pt = pt,
638 .mod = pt.zcu.root_mod,1254 .mod = zcu.root_mod,
639 .error_msg = null,1255 .owner_nav = .none,
640 .pass = .flush,1256 .is_naked_fn = false,
641 .is_naked_fn = false,1257 .expected_block = null,
642 .expected_block = null,1258 .error_msg = null,
643 .fwd_decl = undefined,1259 .ctype_deps = .empty,
644 .ctype_pool = f.lazy_ctype_pool,1260 .uavs = .empty,
645 .scratch = .initBuffer(self.scratch_buf),
646 .uavs = .empty,
647 },
648 .code_header = undefined,
649 .code = undefined,
650 .indent_counter = 0,
651 };1261 };
652 object.dg.fwd_decl = .fromArrayList(gpa, &f.lazy_fwd_decl);
653 object.code = .fromArrayList(gpa, &f.lazy_code);
654 defer {1262 defer {
655 object.dg.uavs.deinit(gpa);1263 assert(dg.uavs.count() == 0);
656 f.lazy_ctype_pool = object.dg.ctype_pool.move();1264 dg.ctype_deps.deinit(gpa);
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();
662 }1265 }
6631266
664 codegen.genErrDecls(&object) catch |err| switch (err) {1267 const code: String = code: {
665 error.AnalysisFail => unreachable,1268 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
666 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,1269 defer c.string_bytes = aw.toArrayList();
667 };1270 const start = aw.written().len;
6681271 codegen.genExports(&dg, &aw.writer, exported, export_indices) catch |err| switch (err) {
669 try self.addUavsFromCodegen(&object.dg.uavs);1272 error.WriteFailed => return error.OutOfMemory,
670}1273 error.OutOfMemory => |e| return e,
6711274 };
672fn flushLazyFn(1275 break :code .{
673 self: *C,1276 .start = @intCast(start),
674 pt: Zcu.PerThread,1277 .len = @intCast(aw.written().len - start),
675 mod: *Module,1278 };
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,
699 };1279 };
700 object.dg.fwd_decl = .fromArrayList(gpa, &f.lazy_fwd_decl);1280 switch (exported) {
701 object.code = .fromArrayList(gpa, &f.lazy_code);1281 .nav => |nav| try c.exported_navs.put(gpa, nav, code),
702 defer {1282 .uav => |uav| try c.exported_uavs.put(gpa, uav, code),
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();
712 }1283 }
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 };
718}1284}
7191285
720fn flushLazyFns(1286pub fn deleteExport(
721 self: *C,1287 self: *C,
722 pt: Zcu.PerThread,1288 exported: Zcu.Exported,
723 mod: *Module,1289 _: InternPool.NullTerminatedString,
724 f: *Flush,1290) void {
725 lazy_ctype_pool: *const codegen.CType.Pool,1291 switch (exported) {
726 lazy_fns: codegen.LazyFnMap,1292 .nav => |nav| _ = self.exported_navs.swapRemove(nav),
727) FlushDeclError!void {1293 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),
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);
737 }1294 }
738}1295}
7391296
740fn flushAvBlock(1297fn mergeNeededCTypes(
741 self: *C,1298 c: *C,
742 pt: Zcu.PerThread,1299 need_types: *std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void),
743 mod: *Module,1300 need_errunion_types: *std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void),
744 f: *Flush,1301 need_aligned_types: *std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64),
745 av_block: *const AvBlock,1302 deps: *const CTypeDependencies,
746 exported_block: ?*const ExportedBlock,1303) Allocator.Error!void {
747 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),1304 const gpa = c.base.comp.gpa;
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}
7601305
761pub fn flushEmitH(zcu: *Zcu) !void {1306 const resolved = deps.get(c);
762 const tracy = trace(@src());
763 defer tracy.end();
7641307
765 if (true) return; // emit-h is regressed1308 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;1312 for (resolved.type) |index| need_types.putAssumeCapacity(index, {});
768 const io = zcu.comp.io;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 😎1315 for (resolved.errunion_type) |index| need_errunion_types.putAssumeCapacity(index, {});
771 const num_buffers = emit_h.decl_table.count() + 1;1316 for (resolved.errunion_type_fwd) |index| need_errunion_types.putAssumeCapacity(index, {});
772 var all_buffers = try std.array_list.Managed(std.posix.iovec_const).initCapacity(zcu.gpa, num_buffers);
773 defer all_buffers.deinit();
7741317
775 var file_size: u64 = zig_h.len;1318 for (resolved.aligned_type_fwd, resolved.aligned_type_masks) |ty_index, align_mask| {
776 if (zig_h.len != 0) {1319 const gop = need_aligned_types.getOrPutAssumeCapacity(ty_index);
777 all_buffers.appendAssumeCapacity(.{1320 if (!gop.found_existing) gop.value_ptr.* = 0;
778 .base = zig_h,1321 gop.value_ptr.* |= align_mask;
779 .len = zig_h.len,
780 });
781 }1322 }
1323}
7821324
783 for (emit_h.decl_table.keys()) |decl_index| {1325fn mergeNeededUavs(
784 const decl_emit_h = emit_h.declPtr(decl_index);1326 zcu: *const Zcu,
785 const buf = decl_emit_h.fwd_decl.items;1327 global: *std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
786 if (buf.len != 0) {1328 new: *const std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
787 all_buffers.appendAssumeCapacity(.{1329) Allocator.Error!void {
788 .base = buf.ptr,1330 const gpa = zcu.comp.gpa;
789 .len = buf.len,1331
790 });1332 try global.ensureUnusedCapacity(gpa, new.count());
791 file_size += buf.len;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 }
792 }1345 }
793 }1346 }
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);
805}1347}
8061348
807pub fn updateExports(1349fn addCTypeDependencies(
808 self: *C,1350 c: *C,
809 pt: Zcu.PerThread,1351 pt: Zcu.PerThread,
810 exported: Zcu.Exported,1352 deps: *const codegen.CType.Dependencies,
811 export_indices: []const Zcu.Export.Index,1353) Allocator.Error!CTypeDependencies {
812) !void {1354 const gpa = pt.zcu.comp.gpa;
813 const zcu = pt.zcu;1355
814 const gpa = zcu.gpa;1356 try c.bigint_types.ensureUnusedCapacity(gpa, deps.bigint.count());
815 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {1357 for (deps.bigint.keys()) |bigint| c.bigint_types.putAssumeCapacity(bigint, {});
816 .nav => |nav| .{1358
817 zcu.navFileScope(nav).mod.?,1359 const type_start = c.type_dependencies.items.len;
818 .{ .nav = nav },1360 const errunion_type_start = type_start + deps.type.count();
819 self.navs.getPtr(nav).?,1361 const type_fwd_start = errunion_type_start + deps.errunion_type.count();
820 (try self.exported_navs.getOrPut(gpa, nav)).value_ptr,1362 const errunion_type_fwd_start = type_fwd_start + deps.type_fwd.count();
821 },1363 const aligned_type_fwd_start = errunion_type_fwd_start + deps.errunion_type_fwd.count();
822 .uav => |uav| .{1364 try c.type_dependencies.appendNTimes(gpa, undefined, deps.type.count() +
823 zcu.root_mod,1365 deps.errunion_type.count() +
824 .{ .uav = uav },1366 deps.type_fwd.count() +
825 self.uavs.getPtr(uav).?,1367 deps.errunion_type_fwd.count() +
826 (try self.exported_uavs.getOrPut(gpa, uav)).value_ptr,1368 deps.aligned_type_fwd.count());
827 },1369
828 };1370 const align_mask_start = c.align_dependency_masks.items.len;
829 const ctype_pool = &decl_block.ctype_pool;1371 try c.align_dependency_masks.appendSlice(gpa, deps.aligned_type_fwd.values());
830 var dg: codegen.DeclGen = .{1372
831 .gpa = gpa,1373 for (deps.type.keys(), type_start..) |ty, i| {
832 .pt = pt,1374 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
833 .mod = mod,1375 c.type_dependencies.items[i] = pool_index;
834 .error_msg = null,1376 }
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);
8481377
849 self.fwd_decl_buf = dg.fwd_decl.toArrayList().allocatedSlice();1378 for (deps.errunion_type.keys(), errunion_type_start..) |ty, i| {
850 self.scratch_buf = dg.scratch.allocatedSlice();1379 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
1380 c.type_dependencies.items[i] = pool_index;
851 }1381 }
852 codegen.genExports(&dg, exported, export_indices) catch |err| switch (err) {1382
853 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,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),
854 };1406 };
855 exported_block.* = .{ .fwd_decl = try self.addString(dg.fwd_decl.written()) };
856}1407}
8571408
858pub fn deleteExport(1409fn updateNewUavs(c: *C, pt: Zcu.PerThread, old_uavs_len: usize) Allocator.Error!void {
859 self: *C,1410 const gpa = pt.zcu.comp.gpa;
860 exported: Zcu.Exported,1411 var index = old_uavs_len;
861 _: InternPool.NullTerminatedString,1412 while (index < c.uavs.count()) : (index += 1) {
862) void {1413 // `new_uavs` is UAVs discovered while lowering *this* UAV.
863 switch (exported) {1414 const new_uavs: []const InternPool.Index = new: {
864 .nav => |nav| _ = self.exported_navs.swapRemove(nav),1415 c.uavs.lockPointers();
865 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),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 }
866 }1430 }
867}1431}
8681432
869fn addUavsFromCodegen(c: *C, uavs: *const std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment)) Allocator.Error!void {1433const FlushTypes = struct {
870 const gpa = c.base.comp.gpa;1434 c: *C,
871 try c.uavs.ensureUnusedCapacity(gpa, uavs.count());1435 f: *Flush,
872 try c.aligned_uavs.ensureUnusedCapacity(gpa, uavs.count());1436
873 for (uavs.keys(), uavs.values()) |uav_val, uav_align| {1437 aligned_types: *const std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64),
874 {1438 aligned_type_strings: []const []const u8,
875 const gop = c.uavs.getOrPutAssumeCapacity(uav_val);1439
876 if (!gop.found_existing) gop.value_ptr.* = .{};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]);
877 }1468 }
878 if (uav_align != .none) {1469 ft.aligned_status.putAssumeCapacity(pool_index, {});
879 const gop = c.aligned_uavs.getOrPutAssumeCapacity(uav_val);1470 }
880 gop.value_ptr.* = if (gop.found_existing) max: {1471 fn doTypeFwd(ft: *FlushTypes, pool_index: link.ConstPool.Index) void {
881 break :max gop.value_ptr.*.maxStrict(uav_align);1472 const c = ft.c;
882 } else uav_align;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 }
883 }1485 }
884 }1486 }
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...@@ -1552,7 +1552,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
1552 const sec_si = try coff.navSection(zcu, nav.status.fully_resolved);1552 const sec_si = try coff.navSection(zcu, nav.status.fully_resolved);
1553 try coff.nodes.ensureUnusedCapacity(gpa, 1);1553 try coff.nodes.ensureUnusedCapacity(gpa, 1);
1554 const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{1554 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(),
1556 .moved = true,1556 .moved = true,
1557 });1557 });
1558 coff.nodes.appendAssumeCapacity(.{ .nav = nmi });1558 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,...@@ -25,9 +25,11 @@ format: DW.Format,
25endian: std.builtin.Endian,25endian: std.builtin.Endian,
26address_size: AddressSize,26address_size: AddressSize,
2727
28const_pool: link.ConstPool,
29
28mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),30mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),
29types: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),31/// Indices are `link.ConstPool.Index`.
30values: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),32values: std.ArrayList(struct { Unit.Index, Entry.Index }),
31navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),33navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),
32decls: std.AutoArrayHashMapUnmanaged(InternPool.TrackedInst.Index, Entry.Index),34decls: std.AutoArrayHashMapUnmanaged(InternPool.TrackedInst.Index, Entry.Index),
3335
...@@ -1034,15 +1036,14 @@ const Entry = struct {...@@ -1034,15 +1036,14 @@ const Entry = struct {
1034 });1036 });
1035 const zcu = dwarf.bin_file.comp.zcu.?;1037 const zcu = dwarf.bin_file.comp.zcu.?;
1036 const ip = &zcu.intern_pool;1038 const ip = &zcu.intern_pool;
1037 for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| {1039 for (0.., dwarf.values.items) |raw_index, unit_and_entry| {
1038 const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index|1040 const index: link.ConstPool.Index = @enumFromInt(raw_index);
1039 dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) catch unreachable1041 const val = index.val(&dwarf.const_pool);
1040 else1042 const val_unit, const val_entry = unit_and_entry;
1041 .main;1043 if (sec.getUnit(val_unit) == unit and unit.getEntry(val_entry) == entry)
1042 if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry)1044 log.err("missing Value({f}({d}))", .{
1043 log.err("missing Type({f}({d}))", .{1045 Value.fromInterned(val).fmtValue(.{ .tid = .main, .zcu = zcu }),
1044 Type.fromInterned(ty).fmt(.{ .tid = .main, .zcu = zcu }),1046 @intFromEnum(val),
1045 @intFromEnum(ty),
1046 });1047 });
1047 }1048 }
1048 for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| {1049 for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| {
...@@ -1520,7 +1521,6 @@ pub const WipNav = struct {...@@ -1520,7 +1521,6 @@ pub const WipNav = struct {
1520 debug_info: Writer.Allocating,1521 debug_info: Writer.Allocating,
1521 debug_line: Writer.Allocating,1522 debug_line: Writer.Allocating,
1522 debug_loclists: Writer.Allocating,1523 debug_loclists: Writer.Allocating,
1523 pending_lazy: PendingLazy,
15241524
1525 pub fn deinit(wip_nav: *WipNav) void {1525 pub fn deinit(wip_nav: *WipNav) void {
1526 const gpa = wip_nav.dwarf.gpa;1526 const gpa = wip_nav.dwarf.gpa;
...@@ -1529,8 +1529,6 @@ pub const WipNav = struct {...@@ -1529,8 +1529,6 @@ pub const WipNav = struct {
1529 wip_nav.debug_info.deinit();1529 wip_nav.debug_info.deinit();
1530 wip_nav.debug_line.deinit();1530 wip_nav.debug_line.deinit();
1531 wip_nav.debug_loclists.deinit();1531 wip_nav.debug_loclists.deinit();
1532 wip_nav.pending_lazy.types.deinit(gpa);
1533 wip_nav.pending_lazy.values.deinit(gpa);
1534 }1532 }
15351533
1536 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void {1534 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void {
...@@ -1603,7 +1601,7 @@ pub const WipNav = struct {...@@ -1603,7 +1601,7 @@ pub const WipNav = struct {
1603 const zcu = pt.zcu;1601 const zcu = pt.zcu;
1604 const ty = val.typeOf(zcu);1602 const ty = val.typeOf(zcu);
1605 const has_runtime_bits = ty.hasRuntimeBits(zcu);1603 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);
1607 try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state) switch (tag) {1605 try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state) switch (tag) {
1608 .comptime_arg => if (opt_name) |_| .comptime_arg_runtime_bits_comptime_state else .unnamed_comptime_arg_runtime_bits_comptime_state,1606 .comptime_arg => if (opt_name) |_| .comptime_arg_runtime_bits_comptime_state else .unnamed_comptime_arg_runtime_bits_comptime_state,
1609 .local_const => if (opt_name) |_| .local_const_runtime_bits_comptime_state else unreachable,1607 .local_const => if (opt_name) |_| .local_const_runtime_bits_comptime_state else unreachable,
...@@ -1945,6 +1943,12 @@ pub const WipNav = struct {...@@ -1945,6 +1943,12 @@ pub const WipNav = struct {
1945 try wip_nav.infoSectionOffset(.debug_str, StringSection.unit, try wip_nav.dwarf.debug_str.addString(wip_nav.dwarf, str), 0);1943 try wip_nav.infoSectionOffset(.debug_str, StringSection.unit, try wip_nav.dwarf.debug_str.addString(wip_nav.dwarf, str), 0);
1946 }1944 }
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
1948 const ExprLocCounter = struct {1952 const ExprLocCounter = struct {
1949 dw: Writer.Discarding,1953 dw: Writer.Discarding,
1950 section_offset_bytes: u32,1954 section_offset_bytes: u32,
...@@ -2054,74 +2058,16 @@ pub const WipNav = struct {...@@ -2054,74 +2058,16 @@ pub const WipNav = struct {
2054 try dfw.splatByteAll(0, @intFromEnum(wip_nav.dwarf.address_size));2058 try dfw.splatByteAll(0, @intFromEnum(wip_nav.dwarf.address_size));
2055 }2059 }
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
2072 fn refNav(2061 fn refNav(
2073 wip_nav: *WipNav,2062 wip_nav: *WipNav,
2074 nav_index: InternPool.Nav.Index,2063 nav_index: InternPool.Nav.Index,
2075 ) (UpdateError || Writer.Error)!void {2064 ) (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);
2077 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);2066 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
2078 }2067 }
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
2102 fn refType(wip_nav: *WipNav, ty: Type) (UpdateError || Writer.Error)!void {2069 fn refType(wip_nav: *WipNav, ty: Type) (UpdateError || Writer.Error)!void {
2103 const unit, const entry = try wip_nav.getTypeEntry(ty);2070 return wip_nav.refValue(ty.toValue());
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 };
2125 }2071 }
21262072
2127 fn refValue(wip_nav: *WipNav, value: Value) (UpdateError || Writer.Error)!void {2073 fn refValue(wip_nav: *WipNav, value: Value) (UpdateError || Writer.Error)!void {
...@@ -2129,6 +2075,15 @@ pub const WipNav = struct {...@@ -2129,6 +2075,15 @@ pub const WipNav = struct {
2129 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);2075 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
2130 }2076 }
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
2132 fn refForward(wip_nav: *WipNav) (Allocator.Error || Writer.Error)!u32 {2087 fn refForward(wip_nav: *WipNav) (Allocator.Error || Writer.Error)!u32 {
2133 const dwarf = wip_nav.dwarf;2088 const dwarf = wip_nav.dwarf;
2134 const diw = &wip_nav.debug_info.writer;2089 const diw = &wip_nav.debug_info.writer;
...@@ -2156,7 +2111,7 @@ pub const WipNav = struct {...@@ -2156,7 +2111,7 @@ pub const WipNav = struct {
2156 ) (UpdateError || Writer.Error)!void {2111 ) (UpdateError || Writer.Error)!void {
2157 const ty = val.typeOf(wip_nav.pt.zcu);2112 const ty = val.typeOf(wip_nav.pt.zcu);
2158 const diw = &wip_nav.debug_info.writer;2113 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);
2160 try diw.writeUleb128(size);2115 try diw.writeUleb128(size);
2161 if (size == 0) return;2116 if (size == 0) return;
2162 const old_end = wip_nav.debug_info.writer.end;2117 const old_end = wip_nav.debug_info.writer.end;
...@@ -2243,8 +2198,8 @@ pub const WipNav = struct {...@@ -2243,8 +2198,8 @@ pub const WipNav = struct {
2243 const zcu = wip_nav.pt.zcu;2198 const zcu = wip_nav.pt.zcu;
2244 const ip = &zcu.intern_pool;2199 const ip = &zcu.intern_pool;
2245 var big_int_space: Value.BigIntSpace = undefined;2200 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)2201 try wip_nav.bigIntConstValue(abbrev_code, .fromInterned(loaded_enum.int_tag_type), if (loaded_enum.field_values.len > 0)
2247 Value.fromInterned(loaded_enum.values.get(ip)[field_index]).toBigInt(&big_int_space, zcu)2202 Value.fromInterned(loaded_enum.field_values.get(ip)[field_index]).toBigInt(&big_int_space, zcu)
2248 else2203 else
2249 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());2204 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
2250 }2205 }
...@@ -2297,6 +2252,12 @@ pub const WipNav = struct {...@@ -2297,6 +2252,12 @@ pub const WipNav = struct {
2297 .generic_decl_const,2252 .generic_decl_const,
2298 .generic_decl_func,2253 .generic_decl_func,
2299 => true,2254 => 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
2300 else => |t| std.debug.panic("bad decl abbrev code: {t}", .{t}),2261 else => |t| std.debug.panic("bad decl abbrev code: {t}", .{t}),
2301 };2262 };
2302 if (parent_type.getCaptures(zcu).len == 0) {2263 if (parent_type.getCaptures(zcu).len == 0) {
...@@ -2331,22 +2292,6 @@ pub const WipNav = struct {...@@ -2331,22 +2292,6 @@ pub const WipNav = struct {
2331 try wip_nav.refType(parent_type.?);2292 try wip_nav.refType(parent_type.?);
2332 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);2293 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);
2333 }2294 }
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 }
2350};2295};
23512296
2352/// When allocating, the ideal_capacity is calculated by2297/// When allocating, the ideal_capacity is calculated by
...@@ -2372,8 +2317,9 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -2372,8 +2317,9 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
2372 },2317 },
2373 .endian = target.cpu.arch.endian(),2318 .endian = target.cpu.arch.endian(),
23742319
2320 .const_pool = .empty,
2321
2375 .mods = .empty,2322 .mods = .empty,
2376 .types = .empty,
2377 .values = .empty,2323 .values = .empty,
2378 .navs = .empty,2324 .navs = .empty,
2379 .decls = .empty,2325 .decls = .empty,
...@@ -2544,9 +2490,9 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {...@@ -2544,9 +2490,9 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
25442490
2545pub fn deinit(dwarf: *Dwarf) void {2491pub fn deinit(dwarf: *Dwarf) void {
2546 const gpa = dwarf.gpa;2492 const gpa = dwarf.gpa;
2493 dwarf.const_pool.deinit(gpa);
2547 for (dwarf.mods.values()) |*mod_info| mod_info.deinit(gpa);2494 for (dwarf.mods.values()) |*mod_info| mod_info.deinit(gpa);
2548 dwarf.mods.deinit(gpa);2495 dwarf.mods.deinit(gpa);
2549 dwarf.types.deinit(gpa);
2550 dwarf.values.deinit(gpa);2496 dwarf.values.deinit(gpa);
2551 dwarf.navs.deinit(gpa);2497 dwarf.navs.deinit(gpa);
2552 dwarf.decls.deinit(gpa);2498 dwarf.decls.deinit(gpa);
...@@ -2562,6 +2508,21 @@ pub fn deinit(dwarf: *Dwarf) void {...@@ -2562,6 +2508,21 @@ pub fn deinit(dwarf: *Dwarf) void {
2562 dwarf.* = undefined;2508 dwarf.* = undefined;
2563}2509}
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
2565fn getUnit(dwarf: *Dwarf, mod: *Module) !Unit.Index {2526fn getUnit(dwarf: *Dwarf, mod: *Module) !Unit.Index {
2566 const mod_gop = try dwarf.mods.getOrPut(dwarf.gpa, mod);2527 const mod_gop = try dwarf.mods.getOrPut(dwarf.gpa, mod);
2567 const unit: Unit.Index = @enumFromInt(mod_gop.index);2528 const unit: Unit.Index = @enumFromInt(mod_gop.index);
...@@ -2622,6 +2583,10 @@ fn getModInfo(dwarf: *Dwarf, unit: Unit.Index) *ModInfo {...@@ -2622,6 +2583,10 @@ fn getModInfo(dwarf: *Dwarf, unit: Unit.Index) *ModInfo {
2622 return &dwarf.mods.values()[@intFromEnum(unit)];2583 return &dwarf.mods.values()[@intFromEnum(unit)];
2623}2584}
26242585
2586fn getUnitModule(dwarf: *Dwarf, unit: Unit.Index) *Module {
2587 return dwarf.mods.keys()[@intFromEnum(unit)];
2588}
2589
2625pub fn initWipNav(2590pub fn initWipNav(
2626 dwarf: *Dwarf,2591 dwarf: *Dwarf,
2627 pt: Zcu.PerThread,2592 pt: Zcu.PerThread,
...@@ -2683,7 +2648,6 @@ fn initWipNavInner(...@@ -2683,7 +2648,6 @@ fn initWipNavInner(
2683 .debug_info = .init(dwarf.gpa),2648 .debug_info = .init(dwarf.gpa),
2684 .debug_line = .init(dwarf.gpa),2649 .debug_line = .init(dwarf.gpa),
2685 .debug_loclists = .init(dwarf.gpa),2650 .debug_loclists = .init(dwarf.gpa),
2686 .pending_lazy = .empty,
2687 };2651 };
2688 errdefer wip_nav.deinit();2652 errdefer wip_nav.deinit();
26892653
...@@ -2705,7 +2669,7 @@ fn initWipNavInner(...@@ -2705,7 +2669,7 @@ fn initWipNavInner(
2705 try wip_nav.refType(.fromInterned(if (maybe_func_type) |func_type| func_type.return_type else @"extern".ty));2669 try wip_nav.refType(.fromInterned(if (maybe_func_type) |func_type| func_type.return_type else @"extern".ty));
2706 if (maybe_func_type) |func_type| {2670 if (maybe_func_type) |func_type| {
2707 try wip_nav.infoAddrSym(sym_index, 0);2671 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)));
2709 if (func_type.param_types.len > 0 or func_type.is_var_args) {2673 if (func_type.param_types.len > 0 or func_type.is_var_args) {
2710 for (func_type.param_types.get(ip)) |param_type| {2674 for (func_type.param_types.get(ip)) |param_type| {
2711 try wip_nav.abbrevCode(.extern_param);2675 try wip_nav.abbrevCode(.extern_param);
...@@ -2733,7 +2697,7 @@ fn initWipNavInner(...@@ -2733,7 +2697,7 @@ fn initWipNavInner(
2733 try wip_nav.strp(@"extern".name.toSlice(ip));2697 try wip_nav.strp(@"extern".name.toSlice(ip));
2734 try wip_nav.refType(.fromInterned(func_type.return_type));2698 try wip_nav.refType(.fromInterned(func_type.return_type));
2735 try wip_nav.infoAddrSym(sym_index, 0);2699 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)));
2737 if (func_type.param_types.len > 0 or func_type.is_var_args) {2701 if (func_type.param_types.len > 0 or func_type.is_var_args) {
2738 for (func_type.param_types.get(ip)) |param_type| {2702 for (func_type.param_types.get(ip)) |param_type| {
2739 try wip_nav.abbrevCode(.extern_param);2703 try wip_nav.abbrevCode(.extern_param);
...@@ -2818,7 +2782,7 @@ fn initWipNavInner(...@@ -2818,7 +2782,7 @@ fn initWipNavInner(
2818 else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),2782 else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
2819 }.toByteUnits().?);2783 }.toByteUnits().?);
2820 try diw.writeByte(@intFromBool(decl.linkage != .normal));2784 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
2823 const dlw = &wip_nav.debug_line.writer;2787 const dlw = &wip_nav.debug_line.writer;
2824 try dlw.writeByte(DW.LNS.extended_op);2788 try dlw.writeByte(DW.LNS.extended_op);
...@@ -3050,7 +3014,7 @@ fn finishWipNavWriterError(...@@ -3050,7 +3014,7 @@ fn finishWipNavWriterError(
3050 }3014 }
3051 try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.written());3015 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 });
3054}3018}
30553019
3056pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {3020pub 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...@@ -3087,34 +3051,12 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3087 return;3051 return;
3088 }3052 }
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
3112 const tag: union(enum) {3054 const tag: union(enum) {
3113 done,3055 alias,
3114 decl_alias,3056 @"var",
3115 decl_var,3057 @"const",
3116 decl_const,3058 func: Type,
3117 decl_func_alias: InternPool.Nav.Index,3059 func_alias: InternPool.Nav.Index,
3118 } = switch (ip.indexToKey(nav_val.toIntern())) {3060 } = switch (ip.indexToKey(nav_val.toIntern())) {
3119 .int_type,3061 .int_type,
3120 .ptr_type,3062 .ptr_type,
...@@ -3128,242 +3070,49 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3128,242 +3070,49 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3128 .func_type,3070 .func_type,
3129 .error_set_type,3071 .error_set_type,
3130 .inferred_error_set_type,3072 .inferred_error_set_type,
3131 => .decl_alias,3073 => .alias,
3074
3132 .struct_type => tag: {3075 .struct_type => tag: {
3133 const loaded_struct = ip.loadStructType(nav_val.toIntern());3076 const loaded_struct = ip.loadStructType(nav_val.toIntern());
3134 if (loaded_struct.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;3077 if (nav_index.toOptional() == loaded_struct.name_nav) {
31353078 // This Nav's entry is populated by the type, not the actual Nav.
3136 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());3079 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3137 if (type_gop.found_existing) {3080 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3138 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;3081 return;
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 },
3227 }3082 }
3228 break :tag .done;3083 break :tag .alias;
3229 },3084 },
3230 .enum_type => tag: {3085 .enum_type => tag: {
3231 const loaded_enum = ip.loadEnumType(nav_val.toIntern());3086 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
3232 const type_zir_index = loaded_enum.zir_index.unwrap() orelse break :tag .decl_alias;3087 if (nav_index.toOptional() == loaded_enum.name_nav) {
3233 if (type_zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;3088 // This Nav's entry is populated by the type, not the actual Nav.
32343089 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3235 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());3090 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3236 if (type_gop.found_existing) {3091 return;
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));
3266 }3092 }
3267 if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));3093 break :tag .alias;
3268 break :tag .done;
3269 },3094 },
3270 .union_type => tag: {3095 .union_type => tag: {
3271 const loaded_union = ip.loadUnionType(nav_val.toIntern());3096 const loaded_union = ip.loadUnionType(nav_val.toIntern());
3272 if (loaded_union.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;3097 if (nav_index.toOptional() == loaded_union.name_nav) {
32733098 // This Nav's entry is populated by the type, not the actual Nav.
3274 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());3099 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3275 if (type_gop.found_existing) {3100 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3276 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;3101 return;
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().?);
3337 }3102 }
3338 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));3103 break :tag .alias;
3339 break :tag .done;
3340 },3104 },
3341 .opaque_type => tag: {3105 .opaque_type => tag: {
3342 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());3106 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
3343 if (loaded_opaque.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;3107 if (nav_index.toOptional() == loaded_opaque.name_nav) {
33443108 // This Nav's entry is populated by the type, not the actual Nav.
3345 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());3109 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3346 if (type_gop.found_existing) {3110 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3347 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;3111 return;
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.*;
3356 }3112 }
3357 wip_nav.entry = nav_gop.value_ptr.*;3113 break :tag .alias;
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;
3366 },3114 },
3115
3367 .undef,3116 .undef,
3368 .simple_value,3117 .simple_value,
3369 .int,3118 .int,
...@@ -3371,70 +3120,76 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3371,70 +3120,76 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3371 .error_union,3120 .error_union,
3372 .enum_literal,3121 .enum_literal,
3373 .enum_tag,3122 .enum_tag,
3374 .empty_enum_value,
3375 .float,3123 .float,
3376 .ptr,3124 .ptr,
3377 .slice,3125 .slice,
3378 .opt,3126 .opt,
3379 .aggregate,3127 .aggregate,
3380 .un,3128 .un,
3381 => .decl_const,3129 .bitpack,
3382 .variable => .decl_var,3130 => .@"const",
3131
3132 .variable => .@"var",
3133
3383 .@"extern" => unreachable,3134 .@"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;3136 .func => |func| tag: {
3399 const is_nullary = !func_type.is_var_args and for (0..func_type.param_types.len) |param_index| {3137 if (func.owner_nav != nav_index) break :tag .{ .func_alias = func.owner_nav };
3400 if (!func_type.paramIsComptime(std.math.cast(u5, param_index) orelse break false)) break false;3138 break :tag .{ .func = .fromInterned(func.ty) };
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;
3424 },3139 },
3140
3425 // memoization, not types3141 // memoization, not types
3426 .memoized_call => unreachable,3142 .memoized_call => unreachable,
3427 };3143 };
3428 if (tag != .done) {3144
3429 if (nav_gop.found_existing)3145 const unit = try dwarf.getUnit(file.mod.?);
3430 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()3146
3431 else3147 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
3432 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);3148 errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
3433 wip_nav.entry = nav_gop.value_ptr.*;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);
3434 }3170 }
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
3435 switch (tag) {3191 switch (tag) {
3436 .done => {},3192 .alias => {
3437 .decl_alias => {
3438 try wip_nav.declCommon(.{3193 try wip_nav.declCommon(.{
3439 .decl = .decl_alias,3194 .decl = .decl_alias,
3440 .generic_decl = .generic_decl_const,3195 .generic_decl = .generic_decl_const,
...@@ -3442,8 +3197,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3442,8 +3197,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3442 }, &nav, inst_info.file, &decl);3197 }, &nav, inst_info.file, &decl);
3443 try wip_nav.refType(nav_val.toType());3198 try wip_nav.refType(nav_val.toType());
3444 },3199 },
3445 .decl_var => {3200 .@"var" => {
3446 const diw = &wip_nav.debug_info.writer;
3447 try wip_nav.declCommon(.{3201 try wip_nav.declCommon(.{
3448 .decl = .decl_var,3202 .decl = .decl_var,
3449 .generic_decl = .generic_decl_var,3203 .generic_decl = .generic_decl_var,
...@@ -3460,11 +3214,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3460,11 +3214,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3460 nav_ty.abiAlignment(zcu).toByteUnits().?);3214 nav_ty.abiAlignment(zcu).toByteUnits().?);
3461 try diw.writeByte(@intFromBool(decl.linkage != .normal));3215 try diw.writeByte(@intFromBool(decl.linkage != .normal));
3462 },3216 },
3463 .decl_const => {3217 .@"const" => {
3464 const diw = &wip_nav.debug_info.writer;
3465 const nav_ty = nav_val.typeOf(zcu);3218 const nav_ty = nav_val.typeOf(zcu);
3466 const has_runtime_bits = nav_ty.hasRuntimeBits(zcu);3219 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);
3468 try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{3221 try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{
3469 .decl = .decl_const_runtime_bits_comptime_state,3222 .decl = .decl_const_runtime_bits_comptime_state,
3470 .generic_decl = .generic_decl_const,3223 .generic_decl = .generic_decl_const,
...@@ -3496,40 +3249,129 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3496,40 +3249,129 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3496 try wip_nav.abbrevCode(.is_const);3249 try wip_nav.abbrevCode(.is_const);
3497 try wip_nav.refType(nav_ty);3250 try wip_nav.refType(nav_ty);
3498 },3251 },
3499 .decl_func_alias => |owner_nav| {3252 .func => |func_ty| {
3500 try wip_nav.declCommon(.{3253 const func_type = ip.indexToKey(func_ty.toIntern()).func_type;
3501 .decl = .decl_alias,3254 const is_nullary = !func_type.is_var_args and for (0..func_type.param_types.len) |param_index| {
3502 .generic_decl = .generic_decl_const,3255 if (!func_type.paramIsComptime(std.math.cast(u5, param_index) orelse break false)) break false;
3503 .decl_instance = .decl_instance_alias,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,
3504 }, &nav, inst_info.file, &decl);3265 }, &nav, inst_info.file, &decl);
3505 try wip_nav.refNav(owner_nav);3266 try wip_nav.refType(.fromInterned(func_type.return_type));
3506 },3267 if (!is_nullary) {
3507 }3268 for (0..func_type.param_types.len) |param_index| {
3508 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());3269 if (std.math.cast(u5, param_index)) |small_param_index|
3509 try wip_nav.updateLazy(nav_src_loc);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 });
3510}3289}
35113290
3512fn updateLazyType(3291pub fn updateContainerType(
3513 dwarf: *Dwarf,3292 dwarf: *Dwarf,
3514 pt: Zcu.PerThread,3293 pt: Zcu.PerThread,
3515 src_loc: Zcu.LazySrcLoc,3294 ty: InternPool.Index,
3516 type_index: InternPool.Index,3295 success: bool,
3517 pending_lazy: *WipNav.PendingLazy,3296) !void {
3518) (UpdateError || Writer.Error)!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 {
3519 const zcu = pt.zcu;3307 const zcu = pt.zcu;
3520 const ip = &zcu.intern_pool;3308 const ip = &zcu.intern_pool;
3521 assert(ip.typeOf(type_index) == .type_type);3309
3522 const ty: Type = .fromInterned(type_index);3310 const unit: Unit.Index, const entry: Entry.Index = switch (ip.indexToKey(val)) {
3523 switch (type_index) {3311 else => .{ .main, try dwarf.addCommonEntry(.main) },
3524 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),3312 .func => |func| try dwarf.getNavEntry(func.owner_nav),
3525 else => log.debug("updateLazyType({f})", .{ty.fmt(pt)}),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 }),
3526 }3357 }
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
3528 var wip_nav: WipNav = .{3370 var wip_nav: WipNav = .{
3529 .dwarf = dwarf,3371 .dwarf = dwarf,
3530 .pt = pt,3372 .pt = pt,
3531 .unit = .main,3373 .unit = unit,
3532 .entry = dwarf.types.get(type_index).?,3374 .entry = entry,
3533 .any_children = false,3375 .any_children = false,
3534 .func = .none,3376 .func = .none,
3535 .func_sym_index = undefined,3377 .func_sym_index = undefined,
...@@ -3540,43 +3382,216 @@ fn updateLazyType(...@@ -3540,43 +3382,216 @@ fn updateLazyType(
3540 .debug_info = .init(dwarf.gpa),3382 .debug_info = .init(dwarf.gpa),
3541 .debug_line = .init(dwarf.gpa),3383 .debug_line = .init(dwarf.gpa),
3542 .debug_loclists = .init(dwarf.gpa),3384 .debug_loclists = .init(dwarf.gpa),
3543 .pending_lazy = pending_lazy.*,
3544 };3385 };
3545 defer {3386 defer wip_nav.deinit();
3546 pending_lazy.* = wip_nav.pending_lazy;3387
3547 wip_nav.pending_lazy = .empty;3388 switch (ip.indexToKey(value_index)) {
3548 wip_nav.deinit();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 },
3549 }3457 }
3550 const diw = &wip_nav.debug_info.writer;3458 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());
3551 const name = switch (type_index) {3459 try dwarf.debug_loclists.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_loclists.written());
3552 .generic_poison_type => "",3460}
3553 else => try std.fmt.allocPrint(dwarf.gpa, "{f}", .{ty.fmt(pt)}),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}),
3554 };3497 };
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 },
3562 .int_type => |int_type| {3575 .int_type => |int_type| {
3563 try wip_nav.abbrevCode(.numeric_type);3576 try wip_nav.abbrevCode(.numeric_type);
3564 try wip_nav.strp(name);3577 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3565 try diw.writeByte(switch (int_type.signedness) {3578 try diw.writeByte(switch (int_type.signedness) {
3566 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),3579 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
3567 });3580 });
3568 try diw.writeUleb128(int_type.bits);3581 try diw.writeUleb128(int_type.bits);
3569 try diw.writeUleb128(ty.abiSize(zcu));3582 try diw.writeUleb128(val.toType().abiSize(zcu));
3570 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);3583 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
3571 },3584 },
3572 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {3585 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
3573 .one, .many, .c => {3586 .one, .many, .c => {
3574 const ptr_child_type: Type = .fromInterned(ptr_type.child);3587 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);3588 try wip_nav.abbrevCode(switch (ptr_type.flags.alignment) {
3576 try wip_nav.strp(name);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)});
3577 if (ptr_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(ptr_type.sentinel));3593 if (ptr_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(ptr_type.sentinel));
3578 try diw.writeUleb128(ptr_type.flags.alignment.toByteUnits() orelse3594 if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a);
3579 ptr_child_type.abiAlignment(zcu).toByteUnits().?);
3580 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));3595 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));
3581 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(3596 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
3582 .debug_info,3597 .debug_info,
...@@ -3600,12 +3615,12 @@ fn updateLazyType(...@@ -3600,12 +3615,12 @@ fn updateLazyType(
3600 },3615 },
3601 .slice => {3616 .slice => {
3602 try wip_nav.abbrevCode(.generated_struct_type);3617 try wip_nav.abbrevCode(.generated_struct_type);
3603 try wip_nav.strp(name);3618 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3604 try diw.writeUleb128(ty.abiSize(zcu));3619 try diw.writeUleb128(val.toType().abiSize(zcu));
3605 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);3620 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
3606 try wip_nav.abbrevCode(.generated_field);3621 try wip_nav.abbrevCode(.generated_field);
3607 try wip_nav.strp("ptr");3622 try wip_nav.strp("ptr");
3608 const ptr_field_type = ty.slicePtrFieldType(zcu);3623 const ptr_field_type = val.toType().slicePtrFieldType(zcu);
3609 try wip_nav.refType(ptr_field_type);3624 try wip_nav.refType(ptr_field_type);
3610 try diw.writeUleb128(0);3625 try diw.writeUleb128(0);
3611 try wip_nav.abbrevCode(.generated_field);3626 try wip_nav.abbrevCode(.generated_field);
...@@ -3619,7 +3634,7 @@ fn updateLazyType(...@@ -3619,7 +3634,7 @@ fn updateLazyType(
3619 .array_type => |array_type| {3634 .array_type => |array_type| {
3620 const array_child_type: Type = .fromInterned(array_type.child);3635 const array_child_type: Type = .fromInterned(array_type.child);
3621 try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type);3636 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)});
3623 if (array_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(array_type.sentinel));3638 if (array_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(array_type.sentinel));
3624 try wip_nav.refType(array_child_type);3639 try wip_nav.refType(array_child_type);
3625 try wip_nav.abbrevCode(.array_len);3640 try wip_nav.abbrevCode(.array_len);
...@@ -3629,7 +3644,7 @@ fn updateLazyType(...@@ -3629,7 +3644,7 @@ fn updateLazyType(
3629 },3644 },
3630 .vector_type => |vector_type| {3645 .vector_type => |vector_type| {
3631 try wip_nav.abbrevCode(.vector_type);3646 try wip_nav.abbrevCode(.vector_type);
3632 try wip_nav.strp(name);3647 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3633 try wip_nav.refType(.fromInterned(vector_type.child));3648 try wip_nav.refType(.fromInterned(vector_type.child));
3634 try wip_nav.abbrevCode(.array_len);3649 try wip_nav.abbrevCode(.array_len);
3635 try wip_nav.refType(.usize);3650 try wip_nav.refType(.usize);
...@@ -3640,9 +3655,9 @@ fn updateLazyType(...@@ -3640,9 +3655,9 @@ fn updateLazyType(
3640 const opt_child_type: Type = .fromInterned(opt_child_type_index);3655 const opt_child_type: Type = .fromInterned(opt_child_type_index);
3641 const opt_repr = optRepr(opt_child_type, zcu);3656 const opt_repr = optRepr(opt_child_type, zcu);
3642 try wip_nav.abbrevCode(.generated_union_type);3657 try wip_nav.abbrevCode(.generated_union_type);
3643 try wip_nav.strp(name);3658 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3644 try diw.writeUleb128(ty.abiSize(zcu));3659 try diw.writeUleb128(val.toType().abiSize(zcu));
3645 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);3660 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
3646 switch (opt_repr) {3661 switch (opt_repr) {
3647 .opv_null => {3662 .opv_null => {
3648 try wip_nav.abbrevCode(.generated_field);3663 try wip_nav.abbrevCode(.generated_field);
...@@ -3720,12 +3735,12 @@ fn updateLazyType(...@@ -3720,12 +3735,12 @@ fn updateLazyType(
3720 };3735 };
37213736
3722 try wip_nav.abbrevCode(.generated_union_type);3737 try wip_nav.abbrevCode(.generated_union_type);
3723 try wip_nav.strp(name);3738 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3724 if (error_union_type.error_set_type != .generic_poison_type and3739 if (error_union_type.error_set_type != .generic_poison_type and
3725 error_union_type.payload_type != .generic_poison_type)3740 error_union_type.payload_type != .generic_poison_type)
3726 {3741 {
3727 try diw.writeUleb128(ty.abiSize(zcu));3742 try diw.writeUleb128(val.toType().abiSize(zcu));
3728 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);3743 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
3729 } else {3744 } else {
3730 try diw.writeUleb128(0);3745 try diw.writeUleb128(0);
3731 try diw.writeUleb128(1);3746 try diw.writeUleb128(1);
...@@ -3791,20 +3806,24 @@ fn updateLazyType(...@@ -3791,20 +3806,24 @@ fn updateLazyType(
3791 .bool,3806 .bool,
3792 => {3807 => {
3793 try wip_nav.abbrevCode(.numeric_type);3808 try wip_nav.abbrevCode(.numeric_type);
3794 try wip_nav.strp(name);3809 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3795 try diw.writeByte(if (type_index == .bool_type)3810 try diw.writeByte(if (value_index == .bool_type)
3796 DW.ATE.boolean3811 DW.ATE.boolean
3797 else if (ty.isRuntimeFloat())3812 else if (val.toType().isRuntimeFloat())
3798 DW.ATE.float3813 DW.ATE.float
3799 else if (ty.isSignedInt(zcu))3814 else if (val.toType().isSignedInt(zcu))
3800 DW.ATE.signed3815 DW.ATE.signed
3801 else if (ty.isUnsignedInt(zcu))3816 else if (val.toType().isUnsignedInt(zcu))
3802 DW.ATE.unsigned3817 DW.ATE.unsigned
3803 else3818 else
3804 unreachable);3819 unreachable);
3805 try diw.writeUleb128(ty.bitSize(zcu));3820 try diw.writeUleb128(val.toType().bitSize(zcu));
3806 try diw.writeUleb128(ty.abiSize(zcu));3821 try diw.writeUleb128(val.toType().abiSize(zcu));
3807 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);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");
3808 },3827 },
3809 .anyopaque,3828 .anyopaque,
3810 .void,3829 .void,
...@@ -3815,37 +3834,29 @@ fn updateLazyType(...@@ -3815,37 +3834,29 @@ fn updateLazyType(
3815 .null,3834 .null,
3816 .undefined,3835 .undefined,
3817 .enum_literal,3836 .enum_literal,
3818 .generic_poison,
3819 => {3837 => {
3820 try wip_nav.abbrevCode(.void_type);3838 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)});
3822 },3840 },
3823 .anyerror => return, // delay until flush3841 .anyerror => unreachable, // already did early return above
3824 .adhoc_inferred_error_set => unreachable,3842 .adhoc_inferred_error_set => unreachable,
3825 },3843 },
3826 .struct_type,
3827 .union_type,
3828 .opaque_type,
3829 => unreachable,
3830 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {3844 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
3831 try wip_nav.abbrevCode(.generated_empty_struct_type);3845 try wip_nav.abbrevCode(.generated_empty_struct_type);
3832 try wip_nav.strp(name);3846 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3833 try diw.writeByte(@intFromBool(false));3847 try diw.writeByte(@intFromBool(false));
3834 } else {3848 } else {
3835 try wip_nav.abbrevCode(.generated_struct_type);3849 try wip_nav.abbrevCode(.generated_struct_type);
3836 try wip_nav.strp(name);3850 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3837 try diw.writeUleb128(ty.abiSize(zcu));3851 try diw.writeUleb128(val.toType().abiSize(zcu));
3838 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);3852 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
3839 var field_byte_offset: u64 = 0;3853 var field_byte_offset: u64 = 0;
3840 for (0..tuple_type.types.len) |field_index| {3854 for (0..tuple_type.types.len) |field_index| {
3841 const comptime_value = tuple_type.values.get(ip)[field_index];3855 const comptime_value = tuple_type.values.get(ip)[field_index];
3842 const field_type: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);3856 const field_type: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);
3843 const has_runtime_bits, const has_comptime_state = switch (comptime_value) {3857 const has_runtime_bits, const has_comptime_state = switch (comptime_value) {
3844 .none => .{ false, false },3858 .none => .{ false, false },
3845 else => .{3859 else => .{ field_type.hasRuntimeBits(zcu), field_type.comptimeOnly(zcu) },
3846 field_type.hasRuntimeBits(zcu),
3847 field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null,
3848 },
3849 };3860 };
3850 try wip_nav.abbrevCode(if (has_comptime_state)3861 try wip_nav.abbrevCode(if (has_comptime_state)
3851 .struct_field_comptime_comptime_state3862 .struct_field_comptime_comptime_state
...@@ -3875,25 +3886,284 @@ fn updateLazyType(...@@ -3875,25 +3886,284 @@ fn updateLazyType(
3875 }3886 }
3876 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));3887 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3877 },3888 },
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 },
3878 .enum_type => {4093 .enum_type => {
3879 const loaded_enum = ip.loadEnumType(type_index);4094 const loaded_enum = ip.loadEnumType(value_index);
3880 try wip_nav.abbrevCode(if (loaded_enum.names.len == 0) .generated_empty_enum_type else .generated_enum_type);4095 if (loaded_enum.zir_index.unwrap()) |zir_index| {
3881 try wip_nav.strp(name);4096 assert(loaded_enum.owner_union == .none);
3882 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));4097 const file = zir_index.resolveFile(ip);
3883 for (0..loaded_enum.names.len) |field_index| {4098 if (loaded_enum.name_nav.unwrap()) |nav_index| {
3884 try wip_nav.enumConstValue(loaded_enum, .{4099 const nav = ip.getNav(nav_index);
3885 .sdata = .signed_enum_field,4100 const decl_inst = nav.srcInst(ip).resolve(ip).?;
3886 .udata = .unsigned_enum_field,4101 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3887 .block = .big_enum_field,4102 try wip_nav.declCommon(if (loaded_enum.field_names.len > 0) .{
3888 }, field_index);4103 .decl = .decl_enum,
3889 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));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));
3890 }4160 }
3891 if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));4161 try diw.writeByte(@intFromBool(true));
3892 },4162 },
3893 .func_type => |func_type| {4163 .func_type => |func_type| {
3894 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;4164 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
3895 try wip_nav.abbrevCode(if (is_nullary) .nullary_func_type else .func_type);4165 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)});
3897 const cc: DW.CC = cc: {4167 const cc: DW.CC = cc: {
3898 if (zcu.getTarget().cCallingConvention()) |cc| {4168 if (zcu.getTarget().cCallingConvention()) |cc| {
3899 if (@as(std.builtin.CallingConvention.Tag, cc) == func_type.cc) {4169 if (@as(std.builtin.CallingConvention.Tag, cc) == func_type.cc) {
...@@ -3975,7 +4245,7 @@ fn updateLazyType(...@@ -3975,7 +4245,7 @@ fn updateLazyType(
3975 },4245 },
3976 .error_set_type => |error_set_type| {4246 .error_set_type => |error_set_type| {
3977 try wip_nav.abbrevCode(if (error_set_type.names.len == 0) .generated_empty_enum_type else .generated_enum_type);4247 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)});
3979 try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{4249 try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{
3980 .signedness = .unsigned,4250 .signedness = .unsigned,
3981 .bits = zcu.errorSetBits(),4251 .bits = zcu.errorSetBits(),
...@@ -3990,100 +4260,28 @@ fn updateLazyType(...@@ -3990,100 +4260,28 @@ fn updateLazyType(
3990 },4260 },
3991 .inferred_error_set_type => |func| {4261 .inferred_error_set_type => |func| {
3992 try wip_nav.abbrevCode(.inferred_error_set_type);4262 try wip_nav.abbrevCode(.inferred_error_set_type);
3993 try wip_nav.strp(name);4263 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3994 try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {4264 try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {
3995 .none => .anyerror_type,4265 .none => .anyerror_type,
3996 else => |ies| ies,4266 else => |ies| ies,
3997 }));4267 }));
3998 },4268 },
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
4080 .undef => |ty| {4270 .undef => |ty| {
4081 try wip_nav.abbrevCode(.undefined_comptime_value);4271 try wip_nav.abbrevCode(.undefined_comptime_value);
4082 try wip_nav.refType(.fromInterned(ty));4272 try wip_nav.refType(.fromInterned(ty));
4083 },4273 },
4084 .simple_value => unreachable, // opv state4274 .simple_value => |simple_value| switch (simple_value) {
4085 .variable, .@"extern" => unreachable, // not a value4275 .void => unreachable, // opv state
4086 .func => unreachable, // already handled4276 .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
4087 .int => |int| {4285 .int => |int| {
4088 try wip_nav.bigIntConstValue(.{4286 try wip_nav.bigIntConstValue(.{
4089 .sdata = .sdata_comptime_value,4287 .sdata = .sdata_comptime_value,
...@@ -4092,6 +4290,15 @@ fn updateLazyValue(...@@ -4092,6 +4290,15 @@ fn updateLazyValue(
4092 }, .fromInterned(int.ty), Value.fromInterned(value_index).toBigInt(&big_int_space, zcu));4290 }, .fromInterned(int.ty), Value.fromInterned(value_index).toBigInt(&big_int_space, zcu));
4093 try wip_nav.refType(.fromInterned(int.ty));4291 try wip_nav.refType(.fromInterned(int.ty));
4094 },4292 },
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 },
4095 .err => |err| {4302 .err => |err| {
4096 try wip_nav.abbrevCode(.udata_comptime_value);4303 try wip_nav.abbrevCode(.udata_comptime_value);
4097 try wip_nav.refType(.fromInterned(err.ty));4304 try wip_nav.refType(.fromInterned(err.ty));
...@@ -4117,7 +4324,7 @@ fn updateLazyValue(...@@ -4117,7 +4324,7 @@ fn updateLazyValue(
4117 .payload => |payload_val| {4324 .payload => |payload_val| {
4118 const payload_type: Type = .fromInterned(ip.typeOf(payload_val));4325 const payload_type: Type = .fromInterned(ip.typeOf(payload_val));
4119 const has_runtime_bits = payload_type.hasRuntimeBits(zcu);4326 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);
4121 try wip_nav.abbrevCode(if (has_comptime_state)4328 try wip_nav.abbrevCode(if (has_comptime_state)
4122 .comptime_value_field_comptime_state4329 .comptime_value_field_comptime_state
4123 else if (has_runtime_bits)4330 else if (has_runtime_bits)
...@@ -4153,7 +4360,6 @@ fn updateLazyValue(...@@ -4153,7 +4360,6 @@ fn updateLazyValue(
4153 }, .fromInterned(int.ty), Value.fromInterned(value_index).toBigInt(&big_int_space, zcu));4360 }, .fromInterned(int.ty), Value.fromInterned(value_index).toBigInt(&big_int_space, zcu));
4154 try wip_nav.refType(.fromInterned(enum_tag.ty));4361 try wip_nav.refType(.fromInterned(enum_tag.ty));
4155 },4362 },
4156 .empty_enum_value => unreachable,
4157 .float => |float| {4363 .float => |float| {
4158 switch (float.storage) {4364 switch (float.storage) {
4159 .f16 => |f16_val| {4365 .f16 => |f16_val| {
...@@ -4194,11 +4400,11 @@ fn updateLazyValue(...@@ -4194,11 +4400,11 @@ fn updateLazyValue(
4194 var byte_offset = ptr.byte_offset;4400 var byte_offset = ptr.byte_offset;
4195 const base_unit, const base_entry = while (true) {4401 const base_unit, const base_entry = while (true) {
4196 const base_ptr, const access: Access = base_ptr_access: switch (base_addr) {4402 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),
4198 .comptime_alloc, .comptime_field => unreachable,4404 .comptime_alloc, .comptime_field => unreachable,
4199 .uav => |uav| {4405 .uav => |uav| {
4200 const uav_ty: Type = .fromInterned(ip.typeOf(uav.val));4406 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) {
4202 try wip_nav.abbrevCode(if (zero_bit_accesses.items.len > 0)4408 try wip_nav.abbrevCode(if (zero_bit_accesses.items.len > 0)
4203 .aggregate_udata_comptime_value4409 .aggregate_udata_comptime_value
4204 else4410 else
...@@ -4311,22 +4517,12 @@ fn updateLazyValue(...@@ -4311,22 +4517,12 @@ fn updateLazyValue(
4311 switch (optRepr(opt_child_type, zcu)) {4517 switch (optRepr(opt_child_type, zcu)) {
4312 .opv_null => try diw.writeUleb128(0),4518 .opv_null => try diw.writeUleb128(0),
4313 .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)),4519 .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)),
4314 .error_set => try wip_nav.blockValue(src_loc, .fromInterned(value_index)),4520 .error_set, .pointer => 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)),
4325 }4521 }
4326 }4522 }
4327 if (opt.val != .none) child_field: {4523 if (opt.val != .none) child_field: {
4328 const has_runtime_bits = opt_child_type.hasRuntimeBits(zcu);4524 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);
4330 try wip_nav.abbrevCode(if (has_comptime_state)4526 try wip_nav.abbrevCode(if (has_comptime_state)
4331 .comptime_value_field_comptime_state4527 .comptime_value_field_comptime_state
4332 else if (has_runtime_bits)4528 else if (has_runtime_bits)
...@@ -4349,17 +4545,17 @@ fn updateLazyValue(...@@ -4349,17 +4545,17 @@ fn updateLazyValue(
4349 const loaded_struct_type = ip.loadStructType(aggregate.ty);4545 const loaded_struct_type = ip.loadStructType(aggregate.ty);
4350 assert(loaded_struct_type.layout == .auto);4546 assert(loaded_struct_type.layout == .auto);
4351 for (0..loaded_struct_type.field_types.len) |field_index| {4547 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;
4353 const field_type: Type = .fromInterned(loaded_struct_type.field_types.get(ip)[field_index]);4549 const field_type: Type = .fromInterned(loaded_struct_type.field_types.get(ip)[field_index]);
4354 const has_runtime_bits = field_type.hasRuntimeBits(zcu);4550 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);
4356 try wip_nav.abbrevCode(if (has_comptime_state)4552 try wip_nav.abbrevCode(if (has_comptime_state)
4357 .comptime_value_field_comptime_state4553 .comptime_value_field_comptime_state
4358 else if (has_runtime_bits)4554 else if (has_runtime_bits)
4359 .comptime_value_field_runtime_bits4555 .comptime_value_field_runtime_bits
4360 else4556 else
4361 continue);4557 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));
4363 const field_value: Value = .fromInterned(switch (aggregate.storage) {4559 const field_value: Value = .fromInterned(switch (aggregate.storage) {
4364 .bytes => unreachable,4560 .bytes => unreachable,
4365 .elems => |elems| elems[field_index],4561 .elems => |elems| elems[field_index],
...@@ -4375,7 +4571,7 @@ fn updateLazyValue(...@@ -4375,7 +4571,7 @@ fn updateLazyValue(
4375 if (tuple_type.values.get(ip)[field_index] != .none) continue;4571 if (tuple_type.values.get(ip)[field_index] != .none) continue;
4376 const field_type: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);4572 const field_type: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);
4377 const has_runtime_bits = field_type.hasRuntimeBits(zcu);4573 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);
4379 try wip_nav.abbrevCode(if (has_comptime_state)4575 try wip_nav.abbrevCode(if (has_comptime_state)
4380 .comptime_value_field_comptime_state4576 .comptime_value_field_comptime_state
4381 else if (has_runtime_bits)4577 else if (has_runtime_bits)
...@@ -4400,7 +4596,7 @@ fn updateLazyValue(...@@ -4400,7 +4596,7 @@ fn updateLazyValue(
4400 inline .array_type, .vector_type => |sequence_type| {4596 inline .array_type, .vector_type => |sequence_type| {
4401 const child_type: Type = .fromInterned(sequence_type.child);4597 const child_type: Type = .fromInterned(sequence_type.child);
4402 const has_runtime_bits = child_type.hasRuntimeBits(zcu);4598 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);
4404 for (switch (aggregate.storage) {4600 for (switch (aggregate.storage) {
4405 .bytes => unreachable,4601 .bytes => unreachable,
4406 .elems => |elems| elems,4602 .elems => |elems| elems,
...@@ -4427,12 +4623,12 @@ fn updateLazyValue(...@@ -4427,12 +4623,12 @@ fn updateLazyValue(
4427 try wip_nav.refType(.fromInterned(un.ty));4623 try wip_nav.refType(.fromInterned(un.ty));
4428 field: {4624 field: {
4429 const loaded_union_type = ip.loadUnionType(un.ty);4625 const loaded_union_type = ip.loadUnionType(un.ty);
4430 assert(loaded_union_type.flagsUnordered(ip).layout == .auto);4626 assert(loaded_union_type.layout == .auto);
4431 const field_index = zcu.unionTagFieldIndex(loaded_union_type, Value.fromInterned(un.tag)).?;4627 const field_index = zcu.unionTagFieldIndex(loaded_union_type, Value.fromInterned(un.tag)).?;
4432 const field_ty: Type = .fromInterned(loaded_union_type.field_types.get(ip)[field_index]);4628 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];
4434 const has_runtime_bits = field_ty.hasRuntimeBits(zcu);4630 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);
4436 try wip_nav.abbrevCode(if (has_comptime_state)4632 try wip_nav.abbrevCode(if (has_comptime_state)
4437 .comptime_value_field_comptime_state4633 .comptime_value_field_comptime_state
4438 else if (has_runtime_bits)4634 else if (has_runtime_bits)
...@@ -4449,7 +4645,8 @@ fn updateLazyValue(...@@ -4449,7 +4645,8 @@ fn updateLazyValue(
4449 },4645 },
4450 .memoized_call => unreachable, // not a value4646 .memoized_call => unreachable, // not a value
4451 }4647 }
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());
4453}4650}
44544651
4455fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, error_set, pointer } {4652fn 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...@@ -4464,312 +4661,6 @@ fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, err
4464 };4661 };
4465}4662}
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
4773pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index) UpdateError!void {4664pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index) UpdateError!void {
4774 const comp = dwarf.bin_file.comp;4665 const comp = dwarf.bin_file.comp;
4775 const io = comp.io;4666 const io = comp.io;
...@@ -4832,14 +4723,15 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro...@@ -4832,14 +4723,15 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro
4832 const comp = dwarf.bin_file.comp;4723 const comp = dwarf.bin_file.comp;
4833 const io = comp.io;4724 const io = comp.io;
48344725
4726 // Update `anyerror` based on the finished global error set.
4835 {4727 {
4836 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type);4728 const index = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, .anyerror_type);
4837 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main);4729 const unit, const entry = dwarf.values.items[@intFromEnum(index)];
4838 var wip_nav: WipNav = .{4730 var wip_nav: WipNav = .{
4839 .dwarf = dwarf,4731 .dwarf = dwarf,
4840 .pt = pt,4732 .pt = pt,
4841 .unit = .main,4733 .unit = unit,
4842 .entry = type_gop.value_ptr.*,4734 .entry = entry,
4843 .any_children = false,4735 .any_children = false,
4844 .func = .none,4736 .func = .none,
4845 .func_sym_index = undefined,4737 .func_sym_index = undefined,
...@@ -4850,7 +4742,6 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro...@@ -4850,7 +4742,6 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro
4850 .debug_info = .init(dwarf.gpa),4742 .debug_info = .init(dwarf.gpa),
4851 .debug_line = .init(dwarf.gpa),4743 .debug_line = .init(dwarf.gpa),
4852 .debug_loclists = .init(dwarf.gpa),4744 .debug_loclists = .init(dwarf.gpa),
4853 .pending_lazy = .empty,
4854 };4745 };
4855 defer wip_nav.deinit();4746 defer wip_nav.deinit();
4856 const diw = &wip_nav.debug_info.writer;4747 const diw = &wip_nav.debug_info.writer;
...@@ -4868,7 +4759,7 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro...@@ -4868,7 +4759,7 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro
4868 }4759 }
4869 if (global_error_set_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));4760 if (global_error_set_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4870 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());4761 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 });
4872 }4763 }
48734764
4874 for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {4765 for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
...@@ -5316,6 +5207,8 @@ const AbbrevCode = enum {...@@ -5316,6 +5207,8 @@ const AbbrevCode = enum {
5316 inferred_error_set_type,5207 inferred_error_set_type,
5317 ptr_type,5208 ptr_type,
5318 ptr_sentinel_type,5209 ptr_sentinel_type,
5210 ptr_aligned_type,
5211 ptr_aligned_sentinel_type,
5319 is_const,5212 is_const,
5320 is_volatile,5213 is_volatile,
5321 array_type,5214 array_type,
...@@ -5952,12 +5845,29 @@ const AbbrevCode = enum {...@@ -5952,12 +5845,29 @@ const AbbrevCode = enum {
5952 .tag = .pointer_type,5845 .tag = .pointer_type,
5953 .attrs = &.{5846 .attrs = &.{
5954 .{ .name, .strp },5847 .{ .name, .strp },
5955 .{ .alignment, .udata },
5956 .{ .address_class, .data1 },5848 .{ .address_class, .data1 },
5957 .{ .type, .ref_addr },5849 .{ .type, .ref_addr },
5958 },5850 },
5959 },5851 },
5960 .ptr_sentinel_type = .{5852 .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 = .{
5961 .tag = .pointer_type,5871 .tag = .pointer_type,
5962 .attrs = &.{5872 .attrs = &.{
5963 .{ .name, .strp },5873 .{ .name, .strp },
src/link/Elf.zig+2-12
...@@ -1711,23 +1711,13 @@ pub fn updateContainerType(...@@ -1711,23 +1711,13 @@ pub fn updateContainerType(
1711 self: *Elf,1711 self: *Elf,
1712 pt: Zcu.PerThread,1712 pt: Zcu.PerThread,
1713 ty: InternPool.Index,1713 ty: InternPool.Index,
1714 success: bool,
1714) link.File.UpdateContainerTypeError!void {1715) link.File.UpdateContainerTypeError!void {
1715 if (build_options.skip_non_native and builtin.object_format != .elf) {1716 if (build_options.skip_non_native and builtin.object_format != .elf) {
1716 @panic("Attempted to compile for object format that was disabled by build configuration");1717 @panic("Attempted to compile for object format that was disabled by build configuration");
1717 }1718 }
1718 const zcu = pt.zcu;1719 return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) {
1719 const gpa = zcu.gpa;
1720 return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) {
1721 error.OutOfMemory => return error.OutOfMemory,1720 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 },
1731 };1721 };
1732}1722}
17331723
src/link/Elf/Object.zig+1-1
...@@ -775,7 +775,7 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO...@@ -775,7 +775,7 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO
775775
776 const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);776 const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);
777 if (!gop.found_existing) {777 if (!gop.found_existing) {
778 gop.value_ptr.* = .{};778 gop.value_ptr.* = .empty;
779 }779 }
780 try gop.value_ptr.append(elf_file.base.comp.gpa, self.index);780 try gop.value_ptr.append(elf_file.base.comp.gpa, self.index);
781 }781 }
src/link/Elf/ZigObject.zig+6-5
...@@ -84,7 +84,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -84,7 +84,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
84 const ptr_size = elf_file.ptrWidthBytes();84 const ptr_size = elf_file.ptrWidthBytes();
8585
86 try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); // null input section86 try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); // null input section
87 try self.relocs.append(gpa, .{}); // null relocs section87 try self.relocs.append(gpa, .empty); // null relocs section
88 try self.strtab.buffer.append(gpa, 0);88 try self.strtab.buffer.append(gpa, 0);
8989
90 {90 {
...@@ -546,7 +546,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index {...@@ -546,7 +546,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index {
546 atom_ptr.name_offset = name_off;546 atom_ptr.name_offset = name_off;
547547
548 const relocs_index: u32 = @intCast(self.relocs.items.len);548 const relocs_index: u32 = @intCast(self.relocs.items.len);
549 self.relocs.addOneAssumeCapacity().* = .{};549 self.relocs.addOneAssumeCapacity().* = .empty;
550 atom_ptr.relocs_section_index = relocs_index;550 atom_ptr.relocs_section_index = relocs_index;
551551
552 return index;552 return index;
...@@ -730,7 +730,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O...@@ -730,7 +730,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O
730730
731 const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);731 const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);
732 if (!gop.found_existing) {732 if (!gop.found_existing) {
733 gop.value_ptr.* = .{};733 gop.value_ptr.* = .empty;
734 }734 }
735 try gop.value_ptr.append(elf_file.base.comp.gpa, self.index);735 try gop.value_ptr.append(elf_file.base.comp.gpa, self.index);
736 }736 }
...@@ -1479,7 +1479,7 @@ fn updateTlv(...@@ -1479,7 +1479,7 @@ fn updateTlv(
14791479
1480 log.debug("updateTlv {f}({d})", .{ nav.fqn.fmt(ip), nav_index });1480 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
1484 const sym = self.symbol(sym_index);1484 const sym = self.symbol(sym_index);
1485 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];1485 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
...@@ -1719,11 +1719,12 @@ pub fn updateContainerType(...@@ -1719,11 +1719,12 @@ pub fn updateContainerType(
1719 self: *ZigObject,1719 self: *ZigObject,
1720 pt: Zcu.PerThread,1720 pt: Zcu.PerThread,
1721 ty: InternPool.Index,1721 ty: InternPool.Index,
1722 success: bool,
1722) !void {1723) !void {
1723 const tracy = trace(@src());1724 const tracy = trace(@src());
1724 defer tracy.end();1725 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);
1727}1728}
17281729
1729fn updateLazySymbol(1730fn updateLazySymbol(
src/link/Elf2.zig+1-1
...@@ -2906,7 +2906,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)...@@ -2906,7 +2906,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
2906 try elf.nodes.ensureUnusedCapacity(gpa, 1);2906 try elf.nodes.ensureUnusedCapacity(gpa, 1);
2907 const sec_si = elf.navSection(ip, nav.status.fully_resolved);2907 const sec_si = elf.navSection(ip, nav.status.fully_resolved);
2908 const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{2908 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(),
2910 .moved = true,2910 .moved = true,
2911 });2911 });
2912 elf.nodes.appendAssumeCapacity(.{ .nav = nmi });2912 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 {...@@ -561,7 +561,7 @@ fn reportUndefSymbol(self: Atom, rel: Relocation, macho_file: *MachO) !bool {
561 defer macho_file.undefs_mutex.unlock(io);561 defer macho_file.undefs_mutex.unlock(io);
562 const gop = try macho_file.undefs.getOrPut(gpa, file.getGlobals()[rel.target]);562 const gop = try macho_file.undefs.getOrPut(gpa, file.getGlobals()[rel.target]);
563 if (!gop.found_existing) {563 if (!gop.found_existing) {
564 gop.value_ptr.* = .{ .refs = .{} };564 gop.value_ptr.* = .{ .refs = .empty };
565 }565 }
566 try gop.value_ptr.refs.append(gpa, .{ .index = self.atom_index, .file = self.file });566 try gop.value_ptr.refs.append(gpa, .{ .index = self.atom_index, .file = self.file });
567 return true;567 return true;
src/link/MachO/ZigObject.zig+7-7
...@@ -3,7 +3,7 @@ data: std.ArrayList(u8) = .empty,...@@ -3,7 +3,7 @@ data: std.ArrayList(u8) = .empty,
3basename: []const u8,3basename: []const u8,
4index: File.Index,4index: File.Index,
55
6symtab: std.MultiArrayList(Nlist) = .{},6symtab: std.MultiArrayList(Nlist) = .empty,
7strtab: StringTable = .{},7strtab: StringTable = .{},
88
9symbols: std.ArrayList(Symbol) = .empty,9symbols: std.ArrayList(Symbol) = .empty,
...@@ -29,7 +29,7 @@ uavs: UavTable = .{},...@@ -29,7 +29,7 @@ uavs: UavTable = .{},
29tlv_initializers: TlvInitializerTable = .{},29tlv_initializers: TlvInitializerTable = .{},
3030
31/// A table of relocations.31/// A table of relocations.
32relocs: RelocationTable = .{},32relocs: RelocationTable = .empty,
3333
34dwarf: ?Dwarf = null,34dwarf: ?Dwarf = null,
3535
...@@ -150,7 +150,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name: MachO.String, macho_fil...@@ -150,7 +150,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name: MachO.String, macho_fil
150 atom.name = name;150 atom.name = name;
151151
152 const relocs_index = @as(u32, @intCast(self.relocs.items.len));152 const relocs_index = @as(u32, @intCast(self.relocs.items.len));
153 self.relocs.addOneAssumeCapacity().* = .{};153 self.relocs.addOneAssumeCapacity().* = .empty;
154 atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);154 atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
155155
156 return index;156 return index;
...@@ -925,7 +925,7 @@ pub fn updateNav(...@@ -925,7 +925,7 @@ pub fn updateNav(
925925
926 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);926 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
927 if (isThreadlocal(macho_file, nav_index))927 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)
929 else929 else
930 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);930 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
931931
...@@ -1030,13 +1030,13 @@ fn updateNavCode(...@@ -1030,13 +1030,13 @@ fn updateNavCode(
1030fn updateTlv(1030fn updateTlv(
1031 self: *ZigObject,1031 self: *ZigObject,
1032 macho_file: *MachO,1032 macho_file: *MachO,
1033 pt: Zcu.PerThread,1033 zcu: *Zcu,
1034 nav_index: InternPool.Nav.Index,1034 nav_index: InternPool.Nav.Index,
1035 sym_index: Symbol.Index,1035 sym_index: Symbol.Index,
1036 sect_index: u8,1036 sect_index: u8,
1037 code: []const u8,1037 code: []const u8,
1038) !void {1038) !void {
1039 const ip = &pt.zcu.intern_pool;1039 const ip = &zcu.intern_pool;
1040 const nav = ip.getNav(nav_index);1040 const nav = ip.getNav(nav_index);
10411041
1042 log.debug("updateTlv {f} (0x{x})", .{ nav.fqn.fmt(ip), nav_index });1042 log.debug("updateTlv {f} (0x{x})", .{ nav.fqn.fmt(ip), nav_index });
...@@ -1045,7 +1045,7 @@ fn updateTlv(...@@ -1045,7 +1045,7 @@ fn updateTlv(
1045 const init_sym_index = try self.createTlvInitializer(1045 const init_sym_index = try self.createTlvInitializer(
1046 macho_file,1046 macho_file,
1047 nav.fqn.toSlice(ip),1047 nav.fqn.toSlice(ip),
1048 pt.navAlignment(nav_index),1048 zcu.navAlignment(nav_index),
1049 sect_index,1049 sect_index,
1050 code,1050 code,
1051 );1051 );
src/link/MachO/file.zig+1-1
...@@ -258,7 +258,7 @@ pub const File = union(enum) {...@@ -258,7 +258,7 @@ pub const File = union(enum) {
258258
259 const gop = try macho_file.dupes.getOrPut(gpa, file.getGlobals()[i]);259 const gop = try macho_file.dupes.getOrPut(gpa, file.getGlobals()[i]);
260 if (!gop.found_existing) {260 if (!gop.found_existing) {
261 gop.value_ptr.* = .{};261 gop.value_ptr.* = .empty;
262 }262 }
263 try gop.value_ptr.append(gpa, file.getIndex());263 try gop.value_ptr.append(gpa, file.getIndex());
264 }264 }
src/link/Wasm.zig+4-4
...@@ -78,7 +78,7 @@ export_table: bool,...@@ -78,7 +78,7 @@ export_table: bool,
78/// Output name of the file78/// Output name of the file
79name: []const u8,79name: []const u8,
80/// List of relocatable files to be linked into the final binary.80/// List of relocatable files to be linked into the final binary.
81objects: std.ArrayList(Object) = .{},81objects: std.ArrayList(Object) = .empty,
8282
83func_types: std.AutoArrayHashMapUnmanaged(FunctionType, void) = .empty,83func_types: std.AutoArrayHashMapUnmanaged(FunctionType, void) = .empty,
84/// Provides a mapping of both imports and provided functions to symbol name.84/// Provides a mapping of both imports and provided functions to symbol name.
...@@ -278,7 +278,7 @@ any_tls_relocs: bool = false,...@@ -278,7 +278,7 @@ any_tls_relocs: bool = false,
278any_passive_inits: bool = false,278any_passive_inits: bool = false,
279279
280/// All MIR instructions for all Zcu functions.280/// All MIR instructions for all Zcu functions.
281mir_instructions: std.MultiArrayList(Mir.Inst) = .{},281mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,
282/// Corresponds to `mir_instructions`.282/// Corresponds to `mir_instructions`.
283mir_extra: std.ArrayList(u32) = .empty,283mir_extra: std.ArrayList(u32) = .empty,
284/// All local types for all Zcu functions.284/// All local types for all Zcu functions.
...@@ -4226,7 +4226,7 @@ fn convertZcuFnType(...@@ -4226,7 +4226,7 @@ fn convertZcuFnType(
42264226
4227 if (CodeGen.firstParamSRet(cc, return_type, zcu, target)) {4227 if (CodeGen.firstParamSRet(cc, return_type, zcu, target)) {
4228 try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle4228 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)) {
4230 if (cc == .wasm_mvp) {4230 if (cc == .wasm_mvp) {
4231 switch (abi.classifyType(return_type, zcu)) {4231 switch (abi.classifyType(return_type, zcu)) {
4232 .direct => |scalar_ty| {4232 .direct => |scalar_ty| {
...@@ -4245,7 +4245,7 @@ fn convertZcuFnType(...@@ -4245,7 +4245,7 @@ fn convertZcuFnType(
4245 // param types4245 // param types
4246 for (params) |param_type_ip| {4246 for (params) |param_type_ip| {
4247 const param_type = Zcu.Type.fromInterned(param_type_ip);4247 const param_type = Zcu.Type.fromInterned(param_type_ip);
4248 if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue;4248 if (!param_type.hasRuntimeBits(zcu)) continue;
42494249
4250 switch (cc) {4250 switch (cc) {
4251 .wasm_mvp => {4251 .wasm_mvp => {
src/link/Wasm/Flush.zig+3-3
...@@ -154,7 +154,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -154,7 +154,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
154 .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, target),154 .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, target),
155 .table_index = @intCast(wasm.tag_name_offs.items.len),155 .table_index = @intCast(wasm.tag_name_offs.items.len),
156 } };156 } };
157 const tag_names = ip.loadEnumType(data.ip_index).names;157 const tag_names = ip.loadEnumType(data.ip_index).field_names;
158 for (tag_names.get(ip)) |tag_name| {158 for (tag_names.get(ip)) |tag_name| {
159 const slice = tag_name.toSlice(ip);159 const slice = tag_name.toSlice(ip);
160 try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len));160 try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len));
...@@ -1869,7 +1869,7 @@ fn emitTagNameFunction(...@@ -1869,7 +1869,7 @@ fn emitTagNameFunction(
1869 const zcu = comp.zcu.?;1869 const zcu = comp.zcu.?;
1870 const ip = &zcu.intern_pool;1870 const ip = &zcu.intern_pool;
1871 const enum_type = ip.loadEnumType(enum_type_ip);1871 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
1874 const slice_abi_size = 8;1874 const slice_abi_size = 8;
1875 const encoded_alignment = @ctz(@as(u32, 4));1875 const encoded_alignment = @ctz(@as(u32, 4));
...@@ -1908,7 +1908,7 @@ fn emitTagNameFunction(...@@ -1908,7 +1908,7 @@ fn emitTagNameFunction(
1908 return;1908 return;
1909 }1909 }
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);
1912 const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {1912 const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {
1913 0...32 => .i32,1913 0...32 => .i32,
1914 33...64 => .i64,1914 33...64 => .i64,
src/link/tapi/parse.zig+1-1
...@@ -530,7 +530,7 @@ const Parser = struct {...@@ -530,7 +530,7 @@ const Parser = struct {
530 fn leaf_value(self: *Parser) ParseError!*Node {530 fn leaf_value(self: *Parser) ParseError!*Node {
531 const node = try self.allocator.create(Node.Value);531 const node = try self.allocator.create(Node.Value);
532 errdefer self.allocator.destroy(node);532 errdefer self.allocator.destroy(node);
533 node.* = .{ .string_value = .{} };533 node.* = .{ .string_value = .empty };
534 node.base.tree = self.tree;534 node.base.tree = self.tree;
535 node.base.start = self.token_it.pos;535 node.base.start = self.token_it.pos;
536 errdefer node.string_value.deinit(self.allocator);536 errdefer node.string_value.deinit(self.allocator);
src/main.zig+9-9
...@@ -979,7 +979,7 @@ fn buildOutputType(...@@ -979,7 +979,7 @@ fn buildOutputType(
979 .dirs = undefined,979 .dirs = undefined,
980 .object_format = null,980 .object_format = null,
981 .dynamic_linker = null,981 .dynamic_linker = null,
982 .modules = .{},982 .modules = .empty,
983 .opts = .{983 .opts = .{
984 .is_test = switch (arg_mode) {984 .is_test = switch (arg_mode) {
985 .zig_test, .zig_test_obj => true,985 .zig_test, .zig_test_obj => true,
...@@ -1006,18 +1006,18 @@ fn buildOutputType(...@@ -1006,18 +1006,18 @@ fn buildOutputType(
1006 .windows_libs = .empty,1006 .windows_libs = .empty,
1007 .link_inputs = .empty,1007 .link_inputs = .empty,
10081008
1009 .c_source_files = .{},1009 .c_source_files = .empty,
1010 .rc_source_files = .{},1010 .rc_source_files = .empty,
10111011
1012 .llvm_m_args = .{},1012 .llvm_m_args = .empty,
1013 .sysroot = null,1013 .sysroot = null,
1014 .lib_directories = .{}, // populated by createModule()1014 .lib_directories = .empty, // populated by createModule()
1015 .lib_dir_args = .{}, // populated from CLI arg parsing1015 .lib_dir_args = .empty, // populated from CLI arg parsing
1016 .libc_installation = null,1016 .libc_installation = null,
1017 .want_native_include_dirs = false,1017 .want_native_include_dirs = false,
1018 .frameworks = .{},1018 .frameworks = .empty,
1019 .framework_dirs = .{},1019 .framework_dirs = .empty,
1020 .rpath_list = .{},1020 .rpath_list = .empty,
1021 .each_lib_rpath = null,1021 .each_lib_rpath = null,
1022 .libc_paths_file = EnvVar.ZIG_LIBC.get(environ_map),1022 .libc_paths_file = EnvVar.ZIG_LIBC.get(environ_map),
1023 .native_system_include_paths = &.{},1023 .native_system_include_paths = &.{},
src/mutable_value.zig+18-26
...@@ -18,7 +18,7 @@ pub const MutableValue = union(enum) {...@@ -18,7 +18,7 @@ pub const MutableValue = union(enum) {
18 opt_payload: SubValue,18 opt_payload: SubValue,
19 /// An aggregate consisting of a single repeated value.19 /// An aggregate consisting of a single repeated value.
20 repeated: SubValue,20 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).
22 bytes: Bytes,22 bytes: Bytes,
23 /// An aggregate with arbitrary sub-values.23 /// An aggregate with arbitrary sub-values.
24 aggregate: Aggregate,24 aggregate: Aggregate,
...@@ -97,8 +97,8 @@ pub const MutableValue = union(enum) {...@@ -97,8 +97,8 @@ pub const MutableValue = union(enum) {
97 /// * Non-error error unions use `eu_payload`97 /// * Non-error error unions use `eu_payload`
98 /// * Non-null optionals use `eu_payload98 /// * Non-null optionals use `eu_payload
99 /// * Slices use `slice`99 /// * Slices use `slice`
100 /// * Unions use `un`100 /// * Unions use `un` (excluding packed unions)
101 /// * Aggregates use `repeated` or `bytes` or `aggregate`101 /// * Aggregates use `repeated` or `bytes` or `aggregate` (excluding packed structs)
102 /// If `!allow_bytes`, the `bytes` representation will not be used.102 /// If `!allow_bytes`, the `bytes` representation will not be used.
103 /// If `!allow_repeated`, the `repeated` representation will not be used.103 /// If `!allow_repeated`, the `repeated` representation will not be used.
104 pub fn unintern(104 pub fn unintern(
...@@ -209,6 +209,7 @@ pub const MutableValue = union(enum) {...@@ -209,6 +209,7 @@ pub const MutableValue = union(enum) {
209 .undef => |ty_ip| switch (Type.fromInterned(ty_ip).zigTypeTag(zcu)) {209 .undef => |ty_ip| switch (Type.fromInterned(ty_ip).zigTypeTag(zcu)) {
210 .@"struct", .array, .vector => |type_tag| {210 .@"struct", .array, .vector => |type_tag| {
211 const ty = Type.fromInterned(ty_ip);211 const ty = Type.fromInterned(ty_ip);
212 if (type_tag == .@"struct" and ty.containerLayout(zcu) == .@"packed") return;
212 const opt_sent = ty.sentinel(zcu);213 const opt_sent = ty.sentinel(zcu);
213 if (type_tag == .@"struct" or opt_sent != null or !allow_repeated) {214 if (type_tag == .@"struct" or opt_sent != null or !allow_repeated) {
214 const len_no_sent = ip.aggregateTypeLen(ty_ip);215 const len_no_sent = ip.aggregateTypeLen(ty_ip);
...@@ -241,15 +242,18 @@ pub const MutableValue = union(enum) {...@@ -241,15 +242,18 @@ pub const MutableValue = union(enum) {
241 } };242 } };
242 }243 }
243 },244 },
244 .@"union" => {245 .@"union" => switch (Type.fromInterned(ty_ip).containerLayout(zcu)) {
245 const payload = try arena.create(MutableValue);246 .auto, .@"packed" => {},
246 const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(pt);247 .@"extern" => {
247 payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) };248 const payload = try arena.create(MutableValue);
248 mv.* = .{ .un = .{249 const backing_ty = try Type.fromInterned(ty_ip).externUnionBackingType(pt);
249 .ty = ty_ip,250 payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) };
250 .tag = .none,251 mv.* = .{ .un = .{
251 .payload = payload,252 .ty = ty_ip,
252 } };253 .tag = .none,
254 .payload = payload,
255 } };
256 },
253 },257 },
254 .pointer => {258 .pointer => {
255 const ptr_ty = ip.indexToKey(ty_ip).ptr_type;259 const ptr_ty = ip.indexToKey(ty_ip).ptr_type;
...@@ -415,16 +419,7 @@ pub const MutableValue = union(enum) {...@@ -415,16 +419,7 @@ pub const MutableValue = union(enum) {
415 } else if (!is_struct and is_trivial_int and Type.fromInterned(a.ty).childType(zcu).toIntern() == .u8_type) {419 } else if (!is_struct and is_trivial_int and Type.fromInterned(a.ty).childType(zcu).toIntern() == .u8_type) {
416 // See if we can switch to `bytes` repr420 // See if we can switch to `bytes` repr
417 for (a.elems) |e| {421 for (a.elems) |e| {
418 switch (e) {422 if (!e.isTrivialInt(zcu)) break;
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 }
428 } else {423 } else {
429 const bytes = try arena.alloc(u8, a.elems.len);424 const bytes = try arena.alloc(u8, a.elems.len);
430 for (a.elems, bytes) |elem_val, *b| {425 for (a.elems, bytes) |elem_val, *b| {
...@@ -494,10 +489,7 @@ pub const MutableValue = union(enum) {...@@ -494,10 +489,7 @@ pub const MutableValue = union(enum) {
494 else => false,489 else => false,
495 .interned => |ip_index| switch (zcu.intern_pool.indexToKey(ip_index)) {490 .interned => |ip_index| switch (zcu.intern_pool.indexToKey(ip_index)) {
496 else => false,491 else => false,
497 .int => |int| switch (int.storage) {492 .int => true,
498 .u64, .i64, .big_int => true,
499 .lazy_align, .lazy_size => false,
500 },
501 },493 },
502 };494 };
503 }495 }
src/print_value.zig+79-42
...@@ -25,10 +25,7 @@ pub fn formatSema(ctx: FormatContext, writer: *Writer) Writer.Error!void {...@@ -25,10 +25,7 @@ pub fn formatSema(ctx: FormatContext, writer: *Writer) Writer.Error!void {
25 const sema = ctx.opt_sema.?;25 const sema = ctx.opt_sema.?;
26 return print(ctx.val, writer, ctx.depth, ctx.pt, sema) catch |err| switch (err) {26 return print(ctx.val, writer, ctx.depth, ctx.pt, sema) catch |err| switch (err) {
27 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function27 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
28 error.ComptimeBreak, error.ComptimeReturn => unreachable,28 error.WriteFailed => |e| return e,
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,
32 };29 };
33}30}
3431
...@@ -36,9 +33,7 @@ pub fn format(ctx: FormatContext, writer: *Writer) Writer.Error!void {...@@ -36,9 +33,7 @@ pub fn format(ctx: FormatContext, writer: *Writer) Writer.Error!void {
36 std.debug.assert(ctx.opt_sema == null);33 std.debug.assert(ctx.opt_sema == null);
37 return print(ctx.val, writer, ctx.depth, ctx.pt, null) catch |err| switch (err) {34 return print(ctx.val, writer, ctx.depth, ctx.pt, null) catch |err| switch (err) {
38 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function35 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
39 error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable,36 error.WriteFailed => |e| return e,
40 error.Canceled => @panic("TODO"), // pls stop returning this error mlugg
41 else => |e| return e,
42 };37 };
43}38}
4439
...@@ -48,7 +43,7 @@ pub fn print(...@@ -48,7 +43,7 @@ pub fn print(
48 level: u8,43 level: u8,
49 pt: Zcu.PerThread,44 pt: Zcu.PerThread,
50 opt_sema: ?*Sema,45 opt_sema: ?*Sema,
51) (Writer.Error || Zcu.CompileError)!void {46) (Writer.Error || Allocator.Error)!void {
52 const zcu = pt.zcu;47 const zcu = pt.zcu;
53 const ip = &zcu.intern_pool;48 const ip = &zcu.intern_pool;
54 switch (ip.indexToKey(val.toIntern())) {49 switch (ip.indexToKey(val.toIntern())) {
...@@ -72,8 +67,12 @@ pub fn print(...@@ -72,8 +67,12 @@ pub fn print(
72 .undef => try writer.writeAll("undefined"),67 .undef => try writer.writeAll("undefined"),
73 .simple_value => |simple_value| switch (simple_value) {68 .simple_value => |simple_value| switch (simple_value) {
74 .void => try writer.writeAll("{}"),69 .void => try writer.writeAll("{}"),
75 .empty_tuple => try writer.writeAll(".{}"),70
76 else => try writer.writeAll(@tagName(simple_value)),71 .null,
72 .true,
73 .false,
74 .@"unreachable",
75 => try writer.writeAll(@tagName(simple_value)),
77 },76 },
78 .variable => try writer.writeAll("(variable)"),77 .variable => try writer.writeAll("(variable)"),
79 .@"extern" => |e| try writer.print("(extern '{f}')", .{e.name.fmt(ip)}),78 .@"extern" => |e| try writer.print("(extern '{f}')", .{e.name.fmt(ip)}),
...@@ -81,14 +80,6 @@ pub fn print(...@@ -81,14 +80,6 @@ pub fn print(
81 .int => |int| switch (int.storage) {80 .int => |int| switch (int.storage) {
82 inline .u64, .i64 => |x| try writer.print("{d}", .{x}),81 inline .u64, .i64 => |x| try writer.print("{d}", .{x}),
83 .big_int => |x| try writer.print("{d}", .{x}),82 .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)}),
92 },83 },
93 .err => |err| try writer.print("error.{f}", .{84 .err => |err| try writer.print("error.{f}", .{
94 err.name.fmt(ip),85 err.name.fmt(ip),
...@@ -104,8 +95,8 @@ pub fn print(...@@ -104,8 +95,8 @@ pub fn print(
104 }),95 }),
105 .enum_tag => |enum_tag| {96 .enum_tag => |enum_tag| {
106 const enum_type = ip.loadEnumType(val.typeOf(zcu).toIntern());97 const enum_type = ip.loadEnumType(val.typeOf(zcu).toIntern());
107 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {98 if (enum_type.tagValueIndex(ip, enum_tag.int)) |tag_index| {
108 return writer.print(".{f}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});99 return writer.print(".{f}", .{enum_type.field_names.get(ip)[tag_index].fmt(ip)});
109 }100 }
110 if (level == 0) {101 if (level == 0) {
111 return writer.writeAll("@enumFromInt(...)");102 return writer.writeAll("@enumFromInt(...)");
...@@ -114,7 +105,6 @@ pub fn print(...@@ -114,7 +105,6 @@ pub fn print(
114 try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema);105 try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema);
115 try writer.writeAll(")");106 try writer.writeAll(")");
116 },107 },
117 .empty_enum_value => try writer.writeAll("(empty enum value)"),
118 .float => |float| switch (float.storage) {108 .float => |float| switch (float.storage) {
119 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),109 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),
120 },110 },
...@@ -123,7 +113,7 @@ pub fn print(...@@ -123,7 +113,7 @@ pub fn print(
123 if (slice.len == .zero_usize) {113 if (slice.len == .zero_usize) {
124 return writer.writeAll("&.{}");114 return writer.writeAll("&.{}");
125 }115 }
126 try print(.fromInterned(slice.ptr), writer, level - 1, pt, opt_sema);116 try print(.fromInterned(slice.ptr), writer, level, pt, opt_sema);
127 } else {117 } else {
128 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {118 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
129 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,119 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
...@@ -167,7 +157,7 @@ pub fn print(...@@ -167,7 +157,7 @@ pub fn print(
167 return;157 return;
168 }158 }
169 if (un.tag == .none) {159 if (un.tag == .none) {
170 const backing_ty = try val.typeOf(zcu).unionBackingType(pt);160 const backing_ty = try val.typeOf(zcu).externUnionBackingType(pt);
171 try writer.print("@bitCast(@as({f}, ", .{backing_ty.fmt(pt)});161 try writer.print("@bitCast(@as({f}, ", .{backing_ty.fmt(pt)});
172 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);162 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
173 try writer.writeAll("))");163 try writer.writeAll("))");
...@@ -179,6 +169,35 @@ pub fn print(...@@ -179,6 +169,35 @@ pub fn print(
179 try writer.writeAll(" }");169 try writer.writeAll(" }");
180 }170 }
181 },171 },
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 },
182 .memoized_call => unreachable,201 .memoized_call => unreachable,
183 }202 }
184}203}
...@@ -191,7 +210,7 @@ fn printAggregate(...@@ -191,7 +210,7 @@ fn printAggregate(
191 level: u8,210 level: u8,
192 pt: Zcu.PerThread,211 pt: Zcu.PerThread,
193 opt_sema: ?*Sema,212 opt_sema: ?*Sema,
194) (Writer.Error || Zcu.CompileError)!void {213) (Writer.Error || Allocator.Error)!void {
195 if (level == 0) {214 if (level == 0) {
196 if (is_ref) try writer.writeByte('&');215 if (is_ref) try writer.writeByte('&');
197 return writer.writeAll(".{ ... }");216 return writer.writeAll(".{ ... }");
...@@ -256,17 +275,26 @@ fn printAggregate(...@@ -256,17 +275,26 @@ fn printAggregate(
256 const len = ty.arrayLen(zcu);275 const len = ty.arrayLen(zcu);
257276
258 if (is_ref) try writer.writeByte('&');277 if (is_ref) try writer.writeByte('&');
259 try writer.writeAll(".{ ");278 switch (len) {
260279 0 => try writer.writeAll(".{}"),
261 const max_len = @min(len, max_aggregate_items);280 1 => {
262 for (0..max_len) |i| {281 try writer.writeAll(".{");
263 if (i != 0) try writer.writeAll(", ");282 try print(try val.fieldValue(pt, 0), writer, level - 1, pt, opt_sema);
264 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);283 try writer.writeByte('}');
265 }284 },
266 if (len > max_aggregate_items) {285 else => {
267 try writer.writeAll(", ...");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 },
268 }297 }
269 return writer.writeAll(" }");
270}298}
271299
272fn printPtr(300fn printPtr(
...@@ -277,7 +305,7 @@ fn printPtr(...@@ -277,7 +305,7 @@ fn printPtr(
277 level: u8,305 level: u8,
278 pt: Zcu.PerThread,306 pt: Zcu.PerThread,
279 opt_sema: ?*Sema,307 opt_sema: ?*Sema,
280) (Writer.Error || Zcu.CompileError)!void {308) (Writer.Error || Allocator.Error)!void {
281 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {309 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
282 .undef => return writer.writeAll("undefined"),310 .undef => return writer.writeAll("undefined"),
283 .ptr => |ptr| ptr,311 .ptr => |ptr| ptr,
...@@ -302,10 +330,7 @@ fn printPtr(...@@ -302,10 +330,7 @@ fn printPtr(
302330
303 var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa);331 var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa);
304 defer arena.deinit();332 defer arena.deinit();
305 const derivation = if (opt_sema) |sema|333 const derivation = try ptr_val.pointerDerivation(arena.allocator(), pt, opt_sema);
306 try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, true, sema)
307 else
308 try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, false, null);
309334
310 _ = try printPtrDerivation(derivation, writer, pt, want_kind, .{ .print_val = .{335 _ = try printPtrDerivation(derivation, writer, pt, want_kind, .{ .print_val = .{
311 .level = level,336 .level = level,
...@@ -442,18 +467,30 @@ pub fn printPtrDerivation(...@@ -442,18 +467,30 @@ pub fn printPtrDerivation(
442 .uav_ptr => |uav| {467 .uav_ptr => |uav| {
443 const ty = Value.fromInterned(uav.val).typeOf(zcu);468 const ty = Value.fromInterned(uav.val).typeOf(zcu);
444 try writer.print("@as({f}, ", .{ty.fmt(pt)});469 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 }
446 try writer.writeByte(')');475 try writer.writeByte(')');
447 },476 },
448 .comptime_alloc_ptr => |info| {477 .comptime_alloc_ptr => |info| {
449 try writer.print("@as({f}, ", .{info.val.typeOf(zcu).fmt(pt)});478 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 }
451 try writer.writeByte(')');484 try writer.writeByte(')');
452 },485 },
453 .comptime_field_ptr => |val| {486 .comptime_field_ptr => |val| {
454 const ty = val.typeOf(zcu);487 const ty = val.typeOf(zcu);
455 try writer.print("@as({f}, ", .{ty.fmt(pt)});488 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 }
457 try writer.writeByte(')');494 try writer.writeByte(')');
458 },495 },
459 else => unreachable,496 else => unreachable,
src/print_zir.zig+115-426
...@@ -548,10 +548,10 @@ const Writer = struct {...@@ -548,10 +548,10 @@ const Writer = struct {
548 .shl_with_overflow,548 .shl_with_overflow,
549 => try self.writeOverflowArithmetic(stream, extended),549 => try self.writeOverflowArithmetic(stream, extended),
550550
551 .struct_decl => try self.writeStructDecl(stream, extended),551 .struct_decl => try self.writeStructDecl(stream, inst),
552 .union_decl => try self.writeUnionDecl(stream, extended),552 .union_decl => try self.writeUnionDecl(stream, inst),
553 .enum_decl => try self.writeEnumDecl(stream, extended),553 .enum_decl => try self.writeEnumDecl(stream, inst),
554 .opaque_decl => try self.writeOpaqueDecl(stream, extended),554 .opaque_decl => try self.writeOpaqueDecl(stream, inst),
555555
556 .tuple_decl => try self.writeTupleDecl(stream, extended),556 .tuple_decl => try self.writeTupleDecl(stream, extended),
557557
...@@ -1427,187 +1427,57 @@ const Writer = struct {...@@ -1427,187 +1427,57 @@ const Writer = struct {
1427 try self.writeSrcNode(stream, inst_data.src_node);1427 try self.writeSrcNode(stream, inst_data.src_node);
1428 }1428 }
14291429
1430 fn writeStructDecl(self: *Writer, stream: *std.Io.Writer, extended: Zir.Inst.Extended.InstData) !void {1430 fn writeStructDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1431 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);1431 const struct_decl = self.code.getStructDecl(inst);
1432
1433 const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand);
14341432
1435 const prev_parent_decl_node = self.parent_decl_node;1433 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;
1437 defer self.parent_decl_node = prev_parent_decl_node;1435 defer self.parent_decl_node = prev_parent_decl_node;
14381436
1439 const fields_hash: std.zig.SrcHash = @bitCast([4]u32{1437 const fields_hash = self.code.getAssociatedSrcHash(inst).?;
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
1446 try stream.print("hash({x}) ", .{&fields_hash});1438 try stream.print("hash({x}) ", .{&fields_hash});
14471439
1448 var extra_index: usize = extra.end;1440 try stream.print("{s}, ", .{@tagName(struct_decl.name_strategy)});
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;
14671441
1468 try self.writeFlag(stream, "known_non_opv, ", small.known_non_opv);1442 if (struct_decl.backing_int_type_body) |backing_int_type_body| {
1469 try self.writeFlag(stream, "known_comptime_only, ", small.known_comptime_only);1443 assert(struct_decl.layout == .@"packed");
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;
1479 try stream.writeAll("packed(");1444 try stream.writeAll("packed(");
1480 if (backing_int_body_len == 0) {1445 try self.writeBracedDecl(stream, backing_int_type_body);
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 }
1491 try stream.writeAll("), ");1446 try stream.writeAll("), ");
1492 } else {1447 } else {
1493 try stream.print("{s}, ", .{@tagName(small.layout)});1448 try stream.print("{s}, ", .{@tagName(struct_decl.layout)});
1494 }1449 }
14951450
1496 if (decls_len == 0) {1451 try self.writeCaptures(stream, struct_decl.captures, struct_decl.capture_names);
1497 try stream.writeAll("{}, ");1452 try stream.writeAll(", ");
1498 } else {1453 try self.writeBracedDecl(stream, struct_decl.decls);
1499 try stream.writeAll("{\n");1454 try stream.writeAll(", ");
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 }
15071455
1508 if (fields_len == 0) {1456 if (struct_decl.field_names.len == 0) {
1509 try stream.writeAll("{}, {}) ");1457 try stream.writeAll("{}) ");
1510 } else {1458 } 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
1569 try stream.writeAll("{\n");1459 try stream.writeAll("{\n");
1570 self.indent += 2;1460 self.indent += 2;
15711461
1572 for (fields, 0..) |field, i| {1462 var it = struct_decl.iterateFields();
1463 while (it.next()) |field| {
1573 try stream.splatByteAll(' ', self.indent);1464 try stream.splatByteAll(' ', self.indent);
1574 try self.writeFlag(stream, "comptime ", field.is_comptime);1465 try self.writeFlag(stream, "comptime ", field.is_comptime);
1575 if (field.name != .empty) {1466 const field_name = self.code.nullTerminatedString(field.name);
1576 const field_name = self.code.nullTerminatedString(field.name);1467 try stream.print("{f}: ", .{std.zig.fmtIdP(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 }
15921468
1593 if (field.align_len > 0) {1469 self.indent += 2;
1594 const body = self.code.bodySlice(extra_index, field.align_len);1470 try self.writeBracedDecl(stream, field.type_body);
1595 extra_index += body.len;1471 if (field.align_body) |body| {
1596 self.indent += 2;
1597 try stream.writeAll(" align(");1472 try stream.writeAll(" align(");
1598 try self.writeBracedDecl(stream, body);1473 try self.writeBracedDecl(stream, body);
1599 try stream.writeAll(")");1474 try stream.writeByte(')');
1600 self.indent -= 2;
1601 }1475 }
16021476 if (field.default_body) |body| {
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;
1607 try stream.writeAll(" = ");1477 try stream.writeAll(" = ");
1608 try self.writeBracedDecl(stream, body);1478 try self.writeBracedDecl(stream, body);
1609 self.indent -= 2;
1610 }1479 }
1480 self.indent -= 2;
16111481
1612 try stream.writeAll(",\n");1482 try stream.writeAll(",\n");
1613 }1483 }
...@@ -1619,266 +1489,119 @@ const Writer = struct {...@@ -1619,266 +1489,119 @@ const Writer = struct {
1619 try self.writeSrcNode(stream, .zero);1489 try self.writeSrcNode(stream, .zero);
1620 }1490 }
16211491
1622 fn writeUnionDecl(self: *Writer, stream: *std.Io.Writer, extended: Zir.Inst.Extended.InstData) !void {1492 fn writeUnionDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1623 const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));1493 const union_decl = self.code.getUnionDecl(inst);
1624
1625 const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand);
16261494
1627 const prev_parent_decl_node = self.parent_decl_node;1495 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;
1629 defer self.parent_decl_node = prev_parent_decl_node;1497 defer self.parent_decl_node = prev_parent_decl_node;
16301498
1631 const fields_hash: std.zig.SrcHash = @bitCast([4]u32{1499 const fields_hash = self.code.getAssociatedSrcHash(inst).?;
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
1638 try stream.print("hash({x}) ", .{&fields_hash});1500 try stream.print("hash({x}) ", .{&fields_hash});
16391501
1640 var extra_index: usize = extra.end;1502 try stream.print("{s}, ", .{@tagName(union_decl.name_strategy)});
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;
16711503
1672 try stream.print("{s}, {s}, ", .{1504 switch (union_decl.kind) {
1673 @tagName(small.name_strategy), @tagName(small.layout),1505 .auto => try stream.writeAll("auto, "),
1674 });1506 .@"extern" => try stream.writeAll("extern, "),
1675 try self.writeFlag(stream, "autoenum, ", small.auto_enum_tag);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);
1678 try stream.writeAll(", ");1529 try stream.writeAll(", ");
16791530
1680 if (decls_len == 0) {1531 if (union_decl.field_names.len == 0) {
1681 try stream.writeAll("{}");1532 try stream.writeAll("}) ");
1682 } else {1533 } else {
1683 try stream.writeAll("{\n");1534 try stream.writeAll("{\n");
1684 self.indent += 2;1535 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);1537 var it = union_decl.iterateFields();
1705 extra_index += body.len;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);1543 self.indent += 2;
1708 try stream.writeAll(", {\n");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;1559 try stream.writeAll(",\n");
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;
1723 }1560 }
1724 const has_type = @as(u1, @truncate(cur_bit_bag)) != 0;1561 self.indent -= 2;
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
1739 try stream.splatByteAll(' ', self.indent);1562 try stream.splatByteAll(' ', self.indent);
1740 try stream.print("{f}", .{std.zig.fmtIdP(field_name)});1563 try stream.writeAll("}) ");
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");
1765 }1564 }
1766
1767 self.indent -= 2;
1768 try stream.splatByteAll(' ', self.indent);
1769 try stream.writeAll("}) ");
1770 try self.writeSrcNode(stream, .zero);1565 try self.writeSrcNode(stream, .zero);
1771 }1566 }
17721567
1773 fn writeEnumDecl(self: *Writer, stream: *std.Io.Writer, extended: Zir.Inst.Extended.InstData) !void {1568 fn writeEnumDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1774 const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));1569 const enum_decl = self.code.getEnumDecl(inst);
1775
1776 const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand);
17771570
1778 const prev_parent_decl_node = self.parent_decl_node;1571 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;
1780 defer self.parent_decl_node = prev_parent_decl_node;1573 defer self.parent_decl_node = prev_parent_decl_node;
17811574
1782 const fields_hash: std.zig.SrcHash = @bitCast([4]u32{1575 const fields_hash = self.code.getAssociatedSrcHash(inst).?;
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
1789 try stream.print("hash({x}) ", .{&fields_hash});1576 try stream.print("hash({x}) ", .{&fields_hash});
17901577
1791 var extra_index: usize = extra.end;1578 try stream.print("{s}, ", .{@tagName(enum_decl.name_strategy)});
17921579 try self.writeFlag(stream, "nonexhaustive, ", enum_decl.nonexhaustive);
1793 const tag_type_ref = if (small.has_tag_type) blk: {1580 if (enum_decl.tag_type_body) |tag_type_body| {
1794 const tag_type_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));1581 try stream.writeAll("tag(");
1795 extra_index += 1;1582 try self.writeBracedDecl(stream, tag_type_body);
1796 break :blk tag_type_ref;1583 try stream.writeAll("), ");
1797 } else .none;1584 }
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);
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);
1827 try stream.writeAll(", ");1589 try stream.writeAll(", ");
18281590
1829 if (decls_len == 0) {1591 if (enum_decl.field_names.len == 0) {
1830 try stream.writeAll("{}, ");1592 try stream.writeAll("{}) ");
1831 } else {1593 } else {
1832 try stream.writeAll("{\n");1594 try stream.writeAll("{\n");
1833 self.indent += 2;1595 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| {
1873 try stream.splatByteAll(' ', self.indent);1599 try stream.splatByteAll(' ', self.indent);
1600 const field_name = self.code.nullTerminatedString(field.name);
1874 try stream.print("{f}", .{std.zig.fmtIdP(field_name)});1601 try stream.print("{f}", .{std.zig.fmtIdP(field_name)});
18751602 if (field.value_body) |body| {
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
1880 try stream.writeAll(" = ");1603 try stream.writeAll(" = ");
1881 try self.writeInstRef(stream, tag_value_ref);1604 try self.writeBracedDecl(stream, body);
1882 }1605 }
1883 try stream.writeAll(",\n");1606 try stream.writeAll(",\n");
1884 }1607 }
...@@ -1889,47 +1612,18 @@ const Writer = struct {...@@ -1889,47 +1612,18 @@ const Writer = struct {
1889 try self.writeSrcNode(stream, .zero);1612 try self.writeSrcNode(stream, .zero);
1890 }1613 }
18911614
1892 fn writeOpaqueDecl(1615 fn writeOpaqueDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1893 self: *Writer,1616 const opaque_decl = self.code.getOpaqueDecl(inst);
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);
18991617
1900 const prev_parent_decl_node = self.parent_decl_node;1618 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;
1902 defer self.parent_decl_node = prev_parent_decl_node;1620 defer self.parent_decl_node = prev_parent_decl_node;
19031621
1904 var extra_index: usize = extra.end;1622 try stream.print("{s}, ", .{@tagName(opaque_decl.name_strategy)});
19051623 try self.writeCaptures(stream, opaque_decl.captures, opaque_decl.capture_names);
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);
1921 try stream.writeAll(", ");1624 try stream.writeAll(", ");
19221625 try self.writeBracedDecl(stream, opaque_decl.decls);
1923 if (decls_len == 0) {1626 try stream.writeAll(") ");
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 }
1933 try self.writeSrcNode(stream, .zero);1627 try self.writeSrcNode(stream, .zero);
1934 }1628 }
19351629
...@@ -2588,14 +2282,11 @@ const Writer = struct {...@@ -2588,14 +2282,11 @@ const Writer = struct {
2588 return stream.print("%{d}", .{@intFromEnum(inst)});2282 return stream.print("%{d}", .{@intFromEnum(inst)});
2589 }2283 }
25902284
2591 fn writeCaptures(self: *Writer, stream: *std.Io.Writer, extra_index: usize, captures_len: u32) !usize {2285 fn writeCaptures(self: *Writer, stream: *std.Io.Writer, captures: []const Zir.Inst.Capture, capture_names: []const Zir.NullTerminatedString) !void {
2592 if (captures_len == 0) {2286 if (captures.len == 0) {
2593 try stream.writeAll("{}");2287 assert(capture_names.len == 0);
2594 return extra_index;2288 return stream.writeAll("{}");
2595 }2289 }
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]);
2599 for (captures, capture_names) |capture, name| {2290 for (captures, capture_names) |capture, name| {
2600 try stream.writeAll("{ ");2291 try stream.writeAll("{ ");
2601 if (name != .empty) {2292 if (name != .empty) {
...@@ -2604,8 +2295,6 @@ const Writer = struct {...@@ -2604,8 +2295,6 @@ const Writer = struct {
2604 }2295 }
2605 try self.writeCapture(stream, capture);2296 try self.writeCapture(stream, capture);
2606 }2297 }
2607
2608 return extra_index + 2 * captures_len;
2609 }2298 }
26102299
2611 fn writeCapture(self: *Writer, stream: *std.Io.Writer, capture: Zir.Inst.Capture) !void {2300 fn writeCapture(self: *Writer, stream: *std.Io.Writer, capture: Zir.Inst.Capture) !void {
stage1/zig.h+9-1
...@@ -151,6 +151,14 @@...@@ -151,6 +151,14 @@
151#define zig_has_attribute(attribute) 0151#define zig_has_attribute(attribute) 0
152#endif152#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
154#if __STDC_VERSION__ >= 202311L162#if __STDC_VERSION__ >= 202311L
155#define zig_threadlocal thread_local163#define zig_threadlocal thread_local
156#elif __STDC_VERSION__ >= 201112L164#elif __STDC_VERSION__ >= 201112L
...@@ -259,7 +267,7 @@...@@ -259,7 +267,7 @@
259#endif267#endif
260268
261#if zig_has_attribute(packed) || defined(zig_tinyc)269#if zig_has_attribute(packed) || defined(zig_tinyc)
262#define zig_packed(definition) __attribute__((packed)) definition270#define zig_packed(definition) definition __attribute__((packed))
263#elif defined(zig_msvc)271#elif defined(zig_msvc)
264#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())272#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())
265#else273#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 {...@@ -24,7 +24,6 @@ test {
24 _ = @import("behavior/duplicated_test_names.zig");24 _ = @import("behavior/duplicated_test_names.zig");
25 _ = @import("behavior/defer.zig");25 _ = @import("behavior/defer.zig");
26 _ = @import("behavior/destructure.zig");26 _ = @import("behavior/destructure.zig");
27 _ = @import("behavior/empty_union.zig");
28 _ = @import("behavior/enum.zig");27 _ = @import("behavior/enum.zig");
29 _ = @import("behavior/error.zig");28 _ = @import("behavior/error.zig");
30 _ = @import("behavior/eval.zig");29 _ = @import("behavior/eval.zig");
test/behavior/align.zig+47-10
...@@ -18,6 +18,7 @@ test "global variable alignment" {...@@ -18,6 +18,7 @@ test "global variable alignment" {
18test "large alignment of local constant" {18test "large alignment of local constant" {
19 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;19 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
20 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // flaky20 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
22 const x: f32 align(128) = 12.34;23 const x: f32 align(128) = 12.34;
23 try std.testing.expect(@intFromPtr(&x) % 128 == 0);24 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" {...@@ -30,13 +31,41 @@ test "slicing array of length 1 can not assume runtime index is always zero" {
30 var runtime_index: usize = 1;31 var runtime_index: usize = 1;
31 _ = &runtime_index;32 _ = &runtime_index;
32 const slice = @as(*align(4) [1]u8, &foo)[runtime_index..];33 const slice = @as(*align(4) [1]u8, &foo)[runtime_index..];
33 try expect(@TypeOf(slice) == []u8);34 try expect(@TypeOf(slice) == []align(1) u8);
34 try expect(slice.len == 0);35 try expect(slice.len == 0);
35 try expect(@as(u2, @truncate(@intFromPtr(slice.ptr) - 1)) == 0);36 try expect(@as(u2, @truncate(@intFromPtr(slice.ptr) - 1)) == 0);
36}37}
3738
38test "default alignment allows unspecified in type syntax" {39test "implicitly-aligned pointer is coercible to equivalent explicitly-aligned pointer" {
39 try expect(*u32 == *align(@alignOf(u32)) u32);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();
40}69}
4170
42test "implicitly decreasing pointer alignment" {71test "implicitly decreasing pointer alignment" {
...@@ -307,11 +336,15 @@ test "runtime-known array index has best alignment possible" {...@@ -307,11 +336,15 @@ test "runtime-known array index has best alignment possible" {
307 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;336 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
308337
309 // take full advantage of over-alignment338 // 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 };
311 comptime assert(@TypeOf(&array[0]) == *align(4) u8);340 comptime assert(@TypeOf(&array[0]) == *align(4) u8);
312 comptime assert(@TypeOf(&array[1]) == *u8);341 comptime assert(@TypeOf(&array[1]) == *align(1) u8);
313 comptime assert(@TypeOf(&array[2]) == *align(2) u8);342 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
316 // because align is too small but we still figure out to use 2349 // because align is too small but we still figure out to use 2
317 var bigger align(2) = [_]u64{ 1, 2, 3, 4 };350 var bigger align(2) = [_]u64{ 1, 2, 3, 4 };
...@@ -332,10 +365,14 @@ test "runtime-known array index has best alignment possible" {...@@ -332,10 +365,14 @@ test "runtime-known array index has best alignment possible" {
332 try testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);365 try testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);
333366
334 // has to use ABI alignment because index known at runtime only367 // has to use ABI alignment because index known at runtime only
335 try testIndex2(&array, 0, *u8);368 try testIndex2(&array, 0, *align(1) u8);
336 try testIndex2(&array, 1, *u8);369 try testIndex2(&array, 1, *align(1) u8);
337 try testIndex2(&array, 2, *u8);370 try testIndex2(&array, 2, *align(1) u8);
338 try testIndex2(&array, 3, *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);
339}376}
340fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) !void {377fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) !void {
341 comptime assert(@TypeOf(&smaller[index]) == T);378 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" {...@@ -39,3 +39,8 @@ test "correct alignment for elements and slices of aligned array" {
39 try expect(@alignOf(@TypeOf(&buf[start..end])) == @alignOf(*u8));39 try expect(@alignOf(@TypeOf(&buf[start..end])) == @alignOf(*u8));
40 try expect(@alignOf(@TypeOf(&buf[start])) == @alignOf(*u8));40 try expect(@alignOf(@TypeOf(&buf[start])) == @alignOf(*u8));
41}41}
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" {...@@ -539,28 +539,6 @@ test "sentinel element count towards the ABI size calculation" {
539 try comptime S.doTheTest();539 try comptime S.doTheTest();
540}540}
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
564test "type coercion of anon struct literal to array" {542test "type coercion of anon struct literal to array" {
565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;543 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
566 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;544 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" {...@@ -350,9 +350,6 @@ test "comptime @bitCast packed struct to int and back" {
350 iint_neg2: i3 = -2,350 iint_neg2: i3 = -2,
351 float: f32 = 3.14,351 float: f32 = 3.14,
352 @"enum": enum(u2) { A, B = 1, C, D } = .B,352 @"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 },
356 };353 };
357 const Int = @typeInfo(S).@"struct".backing_integer.?;354 const Int = @typeInfo(S).@"struct".backing_integer.?;
358355
...@@ -511,35 +508,6 @@ test "@bitCast of packed struct of bools all false" {...@@ -511,35 +508,6 @@ test "@bitCast of packed struct of bools all false" {
511 try expect(@as(u8, @as(u4, @bitCast(p))) == 0);508 try expect(@as(u8, @as(u4, @bitCast(p))) == 0);
512}509}
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
543test "@bitCast of extern struct containing pointer" {511test "@bitCast of extern struct containing pointer" {
544 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;512 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
545 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO513 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" {...@@ -551,19 +551,18 @@ test "generic function pointer can be called" {
551551
552test "value returned from comptime function is comptime known" {552test "value returned from comptime function is comptime known" {
553 const S = struct {553 const S = struct {
554 fn fields(comptime T: type) switch (@typeInfo(T)) {554 fn fieldCount(comptime T: type) switch (@typeInfo(T)) {
555 .@"struct" => []const std.builtin.Type.StructField,555 .@"struct" => comptime_int,
556 else => unreachable,556 else => unreachable,
557 } {557 } {
558 return switch (@typeInfo(T)) {558 return switch (@typeInfo(T)) {
559 .@"struct" => |info| info.fields,559 .@"struct" => |info| info.fields.len,
560 else => unreachable,560 else => unreachable,
561 };561 };
562 }562 }
563 };563 };
564 const fields_list = S.fields(@TypeOf(.{}));564 const fields_len = S.fieldCount(@TypeOf(.{}));
565 if (fields_list.len != 0)565 comptime assert(fields_len == 0);
566 @compileError("Argument count mismatch");
567}566}
568567
569test "registers get overwritten when ignoring return" {568test "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" {...@@ -823,15 +823,6 @@ test "enum with one member and u1 tag type @intFromEnum" {
823 try expect(@intFromEnum(Enum.Test) == 0);823 try expect(@intFromEnum(Enum.Test) == 0);
824}824}
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
835test "enum with one member default to u0 tag type" {826test "enum with one member default to u0 tag type" {
836 const E0 = enum { X };827 const E0 = enum { X };
837 comptime assert(Tag(E0) == u0);828 comptime assert(Tag(E0) == u0);
...@@ -1274,13 +1265,6 @@ fn getLazyInitialized(param: enum(u8) {...@@ -1274,13 +1265,6 @@ fn getLazyInitialized(param: enum(u8) {
1274 return @intFromEnum(param);1265 return @intFromEnum(param);
1275}1266}
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
1284test "matching captures causes enum equivalence" {1268test "matching captures causes enum equivalence" {
1285 const S = struct {1269 const S = struct {
1286 fn Nonexhaustive(comptime I: type) type {1270 fn Nonexhaustive(comptime I: type) type {
...@@ -1347,3 +1331,41 @@ test "comptime @enumFromInt with signed arithmetic" {...@@ -1347,3 +1331,41 @@ test "comptime @enumFromInt with signed arithmetic" {
1347 comptime assert(x == .bar);1331 comptime assert(x == .bar);
1348 comptime assert(@intFromEnum(x) == 0);1332 comptime assert(@intFromEnum(x) == 0);
1349}1333}
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" {...@@ -1109,3 +1109,36 @@ test "'if' ignores error via local while 'else' ignores error directly" {
1109 try S.testOne(false);1109 try S.testOne(false);
1110 try S.testOne(true);1110 try S.testOne(true);
1111}1111}
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 {...@@ -719,13 +719,6 @@ fn testVarInsideInlineLoop(args: anytype) !void {
719 }719 }
720}720}
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
729test "array concatenation of function calls" {722test "array concatenation of function calls" {
730 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;723 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
731 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO724 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...@@ -1081,120 +1074,6 @@ test "comptime break operand passing through runtime switch converted to runtime
1081 try comptime S.doTheTest('b');1074 try comptime S.doTheTest('b');
1082}1075}
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
1198test "equality of pointers to comptime const" {1077test "equality of pointers to comptime const" {
1199 const a: i32 = undefined;1078 const a: i32 = undefined;
1200 comptime assert(&a == &a);1079 comptime assert(&a == &a);
test/behavior/generics.zig+1-4
...@@ -339,7 +339,7 @@ test "generic instantiation of tagged union with only one field" {...@@ -339,7 +339,7 @@ test "generic instantiation of tagged union with only one field" {
339 try expect(S.foo(.{ .s = "ab" }) == 2);339 try expect(S.foo(.{ .s = "ab" }) == 2);
340}340}
341341
342test "nested generic function" {342test "generic parameter type is function type" {
343 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;343 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
344344
345 const S = struct {345 const S = struct {
...@@ -349,10 +349,7 @@ test "nested generic function" {...@@ -349,10 +349,7 @@ test "nested generic function" {
349 fn bar(a: u32) anyerror!void {349 fn bar(a: u32) anyerror!void {
350 try expect(a == 123);350 try expect(a == 123);
351 }351 }
352
353 fn g(_: *const fn (anytype) void) void {}
354 };352 };
355 try expect(@typeInfo(@TypeOf(S.g)).@"fn".is_generic);
356 try S.foo(u32, S.bar, 123);353 try S.foo(u32, S.bar, 123);
357}354}
358355
test/behavior/packed-struct.zig+1-99
...@@ -438,27 +438,6 @@ test "nested packed struct field pointers" {...@@ -438,27 +438,6 @@ test "nested packed struct field pointers" {
438 try expectEqual(6, ptr_p1_b.*);438 try expectEqual(6, ptr_p1_b.*);
439}439}
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
462test "@intFromPtr on a packed struct field" {441test "@intFromPtr on a packed struct field" {
463 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
464 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -601,19 +580,6 @@ test "packed struct fields modification" {...@@ -601,19 +580,6 @@ test "packed struct fields modification" {
601 try expect(@as(u16, @bitCast(Small.p)) == 0x1313);580 try expect(@as(u16, @bitCast(Small.p)) == 0x1313);
602}581}
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
617test "nested packed struct field access test" {583test "nested packed struct field access test" {
618 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO584 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
619 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO packed structs larger than 64 bits585 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" {...@@ -854,7 +820,7 @@ test "packed struct passed to callconv(.c) function" {
854 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;820 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
855821
856 const S = struct {822 const S = struct {
857 const Packed = packed struct {823 const Packed = packed struct(u64) {
858 a: u16,824 a: u16,
859 b: bool = true,825 b: bool = true,
860 c: bool = true,826 c: bool = true,
...@@ -1042,48 +1008,6 @@ test "packed struct acts as a namespace" {...@@ -1042,48 +1008,6 @@ test "packed struct acts as a namespace" {
1042 try expect(foo == .fizz);1008 try expect(foo == .fizz);
1043}1009}
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
1087test "assignment to non-byte-aligned field in packed struct" {1011test "assignment to non-byte-aligned field in packed struct" {
1088 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1012 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1089 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1013 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1227,13 +1151,6 @@ test "2-byte packed struct argument in C calling convention" {...@@ -1227,13 +1151,6 @@ test "2-byte packed struct argument in C calling convention" {
1227 }1151 }
1228}1152}
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
1237test "packed struct equality" {1154test "packed struct equality" {
1238 const Foo = packed struct {1155 const Foo = packed struct {
1239 a: u4,1156 a: u4,
...@@ -1297,21 +1214,6 @@ test "assign packed struct initialized with RLS to packed struct literal field"...@@ -1297,21 +1214,6 @@ test "assign packed struct initialized with RLS to packed struct literal field"
1297 try expect(outer.x == x);1214 try expect(outer.x == x);
1298}1215}
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
1315test "packed struct store of comparison result" {1217test "packed struct store of comparison result" {
1316 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1218 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1317 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1219 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/packed-union.zig+18-8
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const assert = std.debug.assert;3const assert = std.debug.assert;
4const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;5const expectEqual = std.testing.expectEqual;
56
6test "flags in packed union" {7test "flags in packed union" {
...@@ -178,14 +179,23 @@ test "assigning to non-active field at comptime" {...@@ -178,14 +179,23 @@ test "assigning to non-active field at comptime" {
178 }179 }
179}180}
180181
181test "comptime packed union of pointers" {182test "packed union with explicit backing integer" {
182 const U = packed union {183 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
183 a: *const u32,184 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
184 b: *const [1]u32,185 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
185 };
186186
187 const x: u32 = 123;187 const U = packed union(i32) {
188 const u: U = .{ .a = &x };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 });
191}201}
test/behavior/sizeof_and_typeof.zig+1-41
...@@ -11,13 +11,6 @@ test "@sizeOf and @TypeOf" {...@@ -11,13 +11,6 @@ test "@sizeOf and @TypeOf" {
11const x: u16 = 13;11const x: u16 = 13;
12const z: @TypeOf(x) = 19;12const 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
21test "@TypeOf() with multiple arguments" {14test "@TypeOf() with multiple arguments" {
22 {15 {
23 var var_1: u32 = undefined;16 var var_1: u32 = undefined;
...@@ -127,21 +120,6 @@ test "@bitOffsetOf" {...@@ -127,21 +120,6 @@ test "@bitOffsetOf" {
127 try expect(@offsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));120 try expect(@offsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
128}121}
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
145test "@TypeOf() has no runtime side effects" {123test "@TypeOf() has no runtime side effects" {
146 const S = struct {124 const S = struct {
147 fn foo(comptime T: type, ptr: *T) T {125 fn foo(comptime T: type, ptr: *T) T {
...@@ -265,10 +243,6 @@ test "lazy size cast to float" {...@@ -265,10 +243,6 @@ test "lazy size cast to float" {
265 }243 }
266}244}
267245
268test "bitSizeOf comptime_int" {
269 try expect(@bitSizeOf(comptime_int) == 0);
270}
271
272test "runtime instructions inside typeof in comptime only scope" {246test "runtime instructions inside typeof in comptime only scope" {
273 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
274 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO248 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" {...@@ -336,20 +310,6 @@ test "peer type resolution with @TypeOf doesn't trigger dependency loop check" {
336 try std.testing.expect(t.next == null);310 try std.testing.expect(t.next == null);
337}311}
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
353const FILE = extern struct {313const FILE = extern struct {
354 dummy_field: u8,314 dummy_field: u8,
355};315};
...@@ -391,7 +351,7 @@ test "Extern function calls in @TypeOf" {...@@ -391,7 +351,7 @@ test "Extern function calls in @TypeOf" {
391351
392 extern fn s_do_thing([*c]const @This(), b: c_int) c_short;352 extern fn s_do_thing([*c]const @This(), b: c_int) c_short;
393 };353 };
394 const E = struct {354 const E = extern struct {
395 export fn s_do_thing(a: [*c]const @This(), b: c_int) c_short {355 export fn s_do_thing(a: [*c]const @This(), b: c_int) c_short {
396 _ = a;356 _ = a;
397 _ = b;357 _ = b;
test/behavior/slice.zig+1-1
...@@ -160,7 +160,7 @@ test "slice of type" {...@@ -160,7 +160,7 @@ test "slice of type" {
160160
161test "pass a slice of types to a function" {161test "pass a slice of types to a function" {
162 const S = struct {162 const S = struct {
163 fn checkTypesSlice(types_slice: []const type) !void {163 fn checkTypesSlice(comptime types_slice: []const type) !void {
164 try expect(types_slice.len == 2);164 try expect(types_slice.len == 2);
165 try expect(types_slice[0] == anyerror);165 try expect(types_slice[0] == anyerror);
166 try expect(types_slice[1] == bool);166 try expect(types_slice[1] == bool);
test/behavior/struct.zig+73-1
...@@ -2177,7 +2177,7 @@ test "avoid unused field function body compile error" {...@@ -2177,7 +2177,7 @@ test "avoid unused field function body compile error" {
21772177
2178test "pass a pointer to a comptime-only struct field to a function" {2178test "pass a pointer to a comptime-only struct field to a function" {
2179 const S = struct {2179 const S = struct {
2180 fn checkField(field_ptr: *const type) !void {2180 fn checkField(comptime field_ptr: *const type) !void {
2181 try expect(field_ptr.* == u42);2181 try expect(field_ptr.* == u42);
2182 }2182 }
2183 };2183 };
...@@ -2233,3 +2233,75 @@ test "overaligned extern struct fields" {...@@ -2233,3 +2233,75 @@ test "overaligned extern struct fields" {
2233 try expect(std.mem.isAligned(@intFromPtr(&e.c), @alignOf(u32)));2233 try expect(std.mem.isAligned(@intFromPtr(&e.c), @alignOf(u32)));
2234 try expect(std.mem.isAligned(@intFromPtr(&e.d), @alignOf(B)));2234 try expect(std.mem.isAligned(@intFromPtr(&e.d), @alignOf(B)));
2235}2235}
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 {...@@ -8,7 +8,7 @@ const Node = struct {
88
9const NodeAligned = struct {9const NodeAligned = struct {
10 payload: i32,10 payload: i32,
11 children: []align(@alignOf(NodeAligned)) NodeAligned,11 children: []align(1) NodeAligned,
12};12};
1313
14test "struct contains slice of itself" {14test "struct contains slice of itself" {
test/behavior/switch.zig+5-6
...@@ -645,7 +645,7 @@ test "switch prong pointer capture alignment" {...@@ -645,7 +645,7 @@ test "switch prong pointer capture alignment" {
645 }645 }
646646
647 switch (u) {647 switch (u) {
648 .a, .c => |*p| comptime assert(@TypeOf(p) == *const u8),648 .a, .c => |*p| comptime assert(@TypeOf(p) == *align(1) const u8),
649 .b => |*p| {649 .b => |*p| {
650 _ = p;650 _ = p;
651 return error.TestFailed;651 return error.TestFailed;
...@@ -1141,24 +1141,23 @@ test "decl literals as switch cases" {...@@ -1141,24 +1141,23 @@ test "decl literals as switch cases" {
1141 try comptime E.doTheTest(.foo);1141 try comptime E.doTheTest(.foo);
1142}1142}
11431143
1144// TODO audit after #15909 and/or #19855 are decided/implemented1144// TODO audit after #15909 and/or #19855 are decided/implemented.
1145// When we do that, consider adding an 'error{}' case if possible.
1145test "switch with uninstantiable union fields" {1146test "switch with uninstantiable union fields" {
1146 const U = union(enum) {1147 const U = union(enum) {
1147 ok: void,1148 ok: void,
1148 a: noreturn,1149 a: noreturn,
1149 b: noreturn,1150 b: noreturn,
1150 c: error{},
11511151
1152 fn doTheTest(u: @This()) void {1152 fn doTheTest(u: @This()) void {
1153 switch (u) {1153 switch (u) {
1154 .ok => {},1154 .ok => {},
1155 .a => comptime unreachable,1155 .a => comptime unreachable,
1156 .b => comptime unreachable,1156 .b => comptime unreachable,
1157 .c => comptime unreachable,
1158 }1157 }
1159 switch (u) {1158 switch (u) {
1160 .ok => {},1159 .ok => {},
1161 .a, .b, .c => comptime unreachable,1160 .a, .b => comptime unreachable,
1162 }1161 }
1163 switch (u) {1162 switch (u) {
1164 .ok => {},1163 .ok => {},
...@@ -1166,7 +1165,7 @@ test "switch with uninstantiable union fields" {...@@ -1166,7 +1165,7 @@ test "switch with uninstantiable union fields" {
1166 }1165 }
1167 switch (u) {1166 switch (u) {
1168 .a => comptime unreachable,1167 .a => comptime unreachable,
1169 .ok, .b, .c => {},1168 .ok, .b => {},
1170 }1169 }
1171 }1170 }
1172 };1171 };
test/behavior/tuple.zig+11
...@@ -592,3 +592,14 @@ test "array of tuples that end with a zero-bit field followed by padding" {...@@ -592,3 +592,14 @@ test "array of tuples that end with a zero-bit field followed by padding" {
592 try expect(S.foo[1][1] == 4);592 try expect(S.foo[1][1] == 4);
593 try expect(S.foo[1][2] == {});593 try expect(S.foo[1][2] == {});
594}594}
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" {...@@ -22,13 +22,13 @@ test "tuple declaration type info" {
22 try expect(info.fields[0].type == u32);22 try expect(info.fields[0].type == u32);
23 try expect(info.fields[0].defaultValue() == 1);23 try expect(info.fields[0].defaultValue() == 1);
24 try expect(info.fields[0].is_comptime);24 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
27 try expectEqualStrings(info.fields[1].name, "1");27 try expectEqualStrings(info.fields[1].name, "1");
28 try expect(info.fields[1].type == []const u8);28 try expect(info.fields[1].type == []const u8);
29 try expect(info.fields[1].defaultValue() == null);29 try expect(info.fields[1].defaultValue() == null);
30 try expect(!info.fields[1].is_comptime);30 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);
32 }32 }
33}33}
3434
test/behavior/type.zig+2-2
...@@ -278,13 +278,13 @@ test "Type.Union from regular enum" {...@@ -278,13 +278,13 @@ test "Type.Union from regular enum" {
278test "Type.Union from empty regular enum" {278test "Type.Union from empty regular enum" {
279 const E = enum {};279 const E = enum {};
280 const U = @Union(.auto, E, &.{}, &.{}, &.{});280 const U = @Union(.auto, E, &.{}, &.{}, &.{});
281 try testing.expectEqual(@sizeOf(U), 0);281 try testing.expectEqual(@typeInfo(U).@"union".fields.len, 0);
282}282}
283283
284test "Type.Union from empty Type.Enum" {284test "Type.Union from empty Type.Enum" {
285 const E = @Enum(u0, .exhaustive, &.{}, &.{});285 const E = @Enum(u0, .exhaustive, &.{}, &.{});
286 const U = @Union(.auto, E, &.{}, &.{}, &.{});286 const U = @Union(.auto, E, &.{}, &.{}, &.{});
287 try testing.expectEqual(@sizeOf(U), 0);287 try testing.expectEqual(@typeInfo(U).@"union".fields.len, 0);
288}288}
289289
290test "Type.Fn" {290test "Type.Fn" {
test/behavior/type_info.zig+8-8
...@@ -82,7 +82,7 @@ fn testPointer() !void {...@@ -82,7 +82,7 @@ fn testPointer() !void {
82 try expect(u32_ptr_info.pointer.size == .one);82 try expect(u32_ptr_info.pointer.size == .one);
83 try expect(u32_ptr_info.pointer.is_const == false);83 try expect(u32_ptr_info.pointer.is_const == false);
84 try expect(u32_ptr_info.pointer.is_volatile == false);84 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);
86 try expect(u32_ptr_info.pointer.child == u32);86 try expect(u32_ptr_info.pointer.child == u32);
87 try expect(u32_ptr_info.pointer.sentinel() == null);87 try expect(u32_ptr_info.pointer.sentinel() == null);
88}88}
...@@ -99,7 +99,7 @@ fn testUnknownLenPtr() !void {...@@ -99,7 +99,7 @@ fn testUnknownLenPtr() !void {
99 try expect(u32_ptr_info.pointer.is_const == true);99 try expect(u32_ptr_info.pointer.is_const == true);
100 try expect(u32_ptr_info.pointer.is_volatile == true);100 try expect(u32_ptr_info.pointer.is_volatile == true);
101 try expect(u32_ptr_info.pointer.sentinel() == null);101 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);
103 try expect(u32_ptr_info.pointer.child == f64);103 try expect(u32_ptr_info.pointer.child == f64);
104}104}
105105
...@@ -130,7 +130,7 @@ fn testSlice() !void {...@@ -130,7 +130,7 @@ fn testSlice() !void {
130 try expect(u32_slice_info.pointer.size == .slice);130 try expect(u32_slice_info.pointer.size == .slice);
131 try expect(u32_slice_info.pointer.is_const == false);131 try expect(u32_slice_info.pointer.is_const == false);
132 try expect(u32_slice_info.pointer.is_volatile == false);132 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);
134 try expect(u32_slice_info.pointer.child == u32);134 try expect(u32_slice_info.pointer.child == u32);
135}135}
136136
...@@ -266,9 +266,9 @@ fn testUnion() !void {...@@ -266,9 +266,9 @@ fn testUnion() !void {
266 try expect(notag_union_info.@"union".tag_type == null);266 try expect(notag_union_info.@"union".tag_type == null);
267 try expect(notag_union_info.@"union".layout == .auto);267 try expect(notag_union_info.@"union".layout == .auto);
268 try expect(notag_union_info.@"union".fields.len == 2);268 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);
270 try expect(notag_union_info.@"union".fields[1].type == u32);270 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
273 const TestExternUnion = extern union {273 const TestExternUnion = extern union {
274 foo: *anyopaque,274 foo: *anyopaque,
...@@ -292,7 +292,7 @@ fn testStruct() !void {...@@ -292,7 +292,7 @@ fn testStruct() !void {
292 const unpacked_struct_info = @typeInfo(TestStruct);292 const unpacked_struct_info = @typeInfo(TestStruct);
293 try expect(unpacked_struct_info.@"struct".is_tuple == false);293 try expect(unpacked_struct_info.@"struct".is_tuple == false);
294 try expect(unpacked_struct_info.@"struct".backing_integer == null);294 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);
296 try expect(unpacked_struct_info.@"struct".fields[0].defaultValue().? == 4);296 try expect(unpacked_struct_info.@"struct".fields[0].defaultValue().? == 4);
297 try expect(mem.eql(u8, "foobar", unpacked_struct_info.@"struct".fields[1].defaultValue().?));297 try expect(mem.eql(u8, "foobar", unpacked_struct_info.@"struct".fields[1].defaultValue().?));
298}298}
...@@ -314,11 +314,11 @@ fn testPackedStruct() !void {...@@ -314,11 +314,11 @@ fn testPackedStruct() !void {
314 try expect(struct_info.@"struct".layout == .@"packed");314 try expect(struct_info.@"struct".layout == .@"packed");
315 try expect(struct_info.@"struct".backing_integer == u128);315 try expect(struct_info.@"struct".backing_integer == u128);
316 try expect(struct_info.@"struct".fields.len == 4);316 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);
318 try expect(struct_info.@"struct".fields[2].type == f32);318 try expect(struct_info.@"struct".fields[2].type == f32);
319 try expect(struct_info.@"struct".fields[2].defaultValue() == null);319 try expect(struct_info.@"struct".fields[2].defaultValue() == null);
320 try expect(struct_info.@"struct".fields[3].defaultValue().? == 4);320 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);
322 try expect(struct_info.@"struct".decls.len == 1);322 try expect(struct_info.@"struct".decls.len == 1);
323}323}
324324
test/behavior/union.zig+20-53
...@@ -148,6 +148,7 @@ const err = @as(anyerror!Agg, Agg{...@@ -148,6 +148,7 @@ const err = @as(anyerror!Agg, Agg{
148const array = [_]Value{ v1, v2, v1, v2 };148const array = [_]Value{ v1, v2, v1, v2 };
149149
150test "unions embedded in aggregate types" {150test "unions embedded in aggregate types" {
151 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
151 switch (array[1]) {152 switch (array[1]) {
152 Value.Array => |arr| try expect(arr[4] == 3),153 Value.Array => |arr| try expect(arr[4] == 3),
153 else => unreachable,154 else => unreachable,
...@@ -217,26 +218,6 @@ test "union with specified enum tag" {...@@ -217,26 +218,6 @@ test "union with specified enum tag" {
217 try comptime doTest();218 try comptime doTest();
218}219}
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
240fn doTest() error{TestUnexpectedResult}!void {221fn doTest() error{TestUnexpectedResult}!void {
241 try expect((try bar(Payload{ .A = 1234 })) == -10);222 try expect((try bar(Payload{ .A = 1234 })) == -10);
242}223}
...@@ -359,12 +340,12 @@ test "simple union(enum(u32))" {...@@ -359,12 +340,12 @@ test "simple union(enum(u32))" {
359 try expect(@intFromEnum(@as(Tag(MultipleChoice), x)) == 60);340 try expect(@intFromEnum(@as(Tag(MultipleChoice), x)) == 60);
360}341}
361342
362const PackedPtrOrInt = packed union {
363 ptr: *u8,
364 int: usize,
365};
366test "packed union size" {343test "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));
368}349}
369350
370const ZeroBits = union {351const ZeroBits = union {
...@@ -703,25 +684,23 @@ test "union with only 1 field casted to its enum type which has enum value speci...@@ -703,25 +684,23 @@ test "union with only 1 field casted to its enum type which has enum value speci
703 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO684 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
704685
705 const Literal = union(enum) {686 const Literal = union(enum) {
706 Number: f64,687 number: f64,
707 Bool: bool,688 bool: bool,
708 };689 };
709690
710 const ExprTag = enum(comptime_int) {691 const ExprTag = enum(u32) { literal = 33 };
711 Literal = 33,692 const Expr = union(ExprTag) { literal: Literal };
712 };
713693
714 const Expr = union(ExprTag) {694 comptime assert(Tag(ExprTag) == u32);
715 Literal: Literal,
716 };
717695
718 var e = Expr{ .Literal = Literal{ .Bool = true } };696 var e: Expr = undefined;
719 _ = &e;697 e = .{ .literal = .{ .bool = true } };
720 comptime assert(Tag(ExprTag) == comptime_int);698
721 const t = comptime @as(ExprTag, e);699 const t: ExprTag = e;
722 try expect(t == Expr.Literal);700 comptime assert(t == Expr.literal);
723 try expect(@intFromEnum(t) == 33);
724 comptime assert(@intFromEnum(t) == 33);701 comptime assert(@intFromEnum(t) == 33);
702 try expect(t == Expr.literal);
703 try expect(@intFromEnum(t) == 33);
725}704}
726705
727test "@intFromEnum works on unions" {706test "@intFromEnum works on unions" {
...@@ -893,15 +872,6 @@ test "union no tag with struct member" {...@@ -893,15 +872,6 @@ test "union no tag with struct member" {
893 u.foo();872 u.foo();
894}873}
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
905test "extern union doesn't trigger field check at comptime" {875test "extern union doesn't trigger field check at comptime" {
906 const U = extern union {876 const U = extern union {
907 x: u32,877 x: u32,
...@@ -1031,7 +1001,7 @@ test "containers with single-field enums" {...@@ -1031,7 +1001,7 @@ test "containers with single-field enums" {
1031 try comptime S.doTheTest();1001 try comptime S.doTheTest();
1032}1002}
10331003
1034test "@unionInit on union with tag but no fields" {1004test "@unionInit on union with u8 tag but no fields" {
1035 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1005 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1036 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1006 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10371007
...@@ -1047,10 +1017,6 @@ test "@unionInit on union with tag but no fields" {...@@ -1047,10 +1017,6 @@ test "@unionInit on union with tag but no fields" {
1047 }1017 }
1048 };1018 };
10491019
1050 comptime {
1051 assert(@sizeOf(Data) == 1);
1052 }
1053
1054 fn doTheTest() !void {1020 fn doTheTest() !void {
1055 var data: Data = .{ .no_op = {} };1021 var data: Data = .{ .no_op = {} };
1056 _ = &data;1022 _ = &data;
...@@ -2057,6 +2023,7 @@ test "runtime union init, most-aligned field != largest" {...@@ -2057,6 +2023,7 @@ test "runtime union init, most-aligned field != largest" {
2057 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2023 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2058 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2024 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2059 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;2025 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
2061 const U = union(enum) {2028 const U = union(enum) {
2062 x: u128,2029 x: u128,
test/c_abi/main.zig+2-2
...@@ -718,7 +718,7 @@ export fn zig_med_struct_ints(s: MedStructInts) void {...@@ -718,7 +718,7 @@ export fn zig_med_struct_ints(s: MedStructInts) void {
718 expect(s.z == 3) catch @panic("test failure");718 expect(s.z == 3) catch @panic("test failure");
719}719}
720720
721const SmallPackedStruct = packed struct {721const SmallPackedStruct = packed struct(u8) {
722 a: u2,722 a: u2,
723 b: u2,723 b: u2,
724 c: u2,724 c: u2,
...@@ -744,7 +744,7 @@ test "C ABI small packed struct" {...@@ -744,7 +744,7 @@ test "C ABI small packed struct" {
744 try expect(s2.d == 3);744 try expect(s2.d == 3);
745}745}
746746
747const BigPackedStruct = packed struct {747const BigPackedStruct = packed struct(u128) {
748 a: u64,748 a: u64,
749 b: u64,749 b: u64,
750};750};
test/cases/compile_errors/@import_zon_bad_type.zig+4-4
...@@ -116,13 +116,13 @@ export fn testMutablePointer() void {...@@ -116,13 +116,13 @@ export fn testMutablePointer() void {
116// tmp.zig:85:26: note: ZON does not allow nested optionals116// tmp.zig:85:26: note: ZON does not allow nested optionals
117// tmp.zig:90:29: error: type '*i32' is not available in ZON117// tmp.zig:90:29: error: type '*i32' is not available in ZON
118// tmp.zig:90:29: note: ZON does not allow mutable pointers118// 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
121// neg_inf.zon:1:1: error: expected type '?u8'119// neg_inf.zon:1:1: error: expected type '?u8'
122// tmp.zig:57:28: note: imported here120// 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
123// neg_inf.zon:1:1: error: expected type 'tmp.E'123// neg_inf.zon:1:1: error: expected type 'tmp.E'
124// tmp.zig:63:26: note: imported here124// 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
127// neg_inf.zon:1:1: error: expected type 'tmp.EU'125// neg_inf.zon:1:1: error: expected type 'tmp.EU'
128// tmp.zig:75:27: note: imported here126// 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 {...@@ -58,25 +58,25 @@ export fn testVector() void {
58// error58// error
59// imports=zon/vec2.zon59// imports=zon/vec2.zon
60//60//
61// vec2.zon:1:2: error: expected type '?f32'
62// tmp.zig:2:29: note: imported here
63// vec2.zon:1:2: error: expected type '*const ?f32'61// vec2.zon:1:2: error: expected type '*const ?f32'
64// tmp.zig:7:36: note: imported here62// tmp.zig:7:36: note: imported here
65// vec2.zon:1:2: error: expected type '?*const f32'63// vec2.zon:1:2: error: expected type '?*const f32'
66// tmp.zig:12:36: note: imported here64// 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
67// vec2.zon:1:2: error: expected type '?bool'73// vec2.zon:1:2: error: expected type '?bool'
68// tmp.zig:17:30: note: imported here74// tmp.zig:17:30: note: imported here
75// vec2.zon:1:2: error: expected type '?f32'
76// tmp.zig:2:29: note: imported here
69// vec2.zon:1:2: error: expected type '?i32'77// vec2.zon:1:2: error: expected type '?i32'
70// tmp.zig:22:29: note: imported here78// tmp.zig:22:29: note: imported here
71// vec2.zon:1:2: error: expected type '?tmp.Enum'79// vec2.zon:1:2: error: expected type '?tmp.Enum'
72// tmp.zig:28:30: note: imported here80// 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
77// vec2.zon:1:2: error: expected type '?tmp.Union'81// vec2.zon:1:2: error: expected type '?tmp.Union'
78// tmp.zig:44:31: note: imported here82// 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 {...@@ -13,7 +13,7 @@ export fn testTuple() void {
13// error13// error
14// imports=zon/nan.zon14// imports=zon/nan.zon
15//15//
16//nan.zon:1:1: error: expected type '?tmp.Struct'16// nan.zon:1:1: error: expected type '?struct { bool }'
17//tmp.zig:3:32: note: imported here17// tmp.zig:9:31: note: imported here
18//nan.zon:1:1: error: expected type '?struct { bool }'18// nan.zon:1:1: error: expected type '?tmp.Struct'
19//tmp.zig:9:31: note: imported here19// 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 {...@@ -12,16 +12,14 @@ const U = union {
12 b: [1 << 32]u8,12 b: [1 << 32]u8,
13};13};
1414
15const V = union {
16 a: u32,
17 b: T,
18};
19
20comptime {15comptime {
21 _ = S;16 _ = @as(S, undefined);
22 _ = T;17}
23 _ = U;18comptime {
24 _ = V;19 _ = @as(T, undefined);
20}
21comptime {
22 _ = @as(U, undefined);
25}23}
2624
27// error25// error
test/cases/compile_errors/alignOf_bad_type.zig+8-2
...@@ -1,7 +1,13 @@...@@ -1,7 +1,13 @@
1export fn entry() usize {1export fn entry0() usize {
2 return @alignOf(noreturn);2 return @alignOf(noreturn);
3}3}
4const S = struct { a: u32, b: noreturn };
5export fn entry1() usize {
6 return @alignOf(S);
7}
48
5// error9// error
6//10//
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 {...@@ -30,11 +30,11 @@ export fn g() void {
30}30}
3131
32export fn h() void {32export fn h() void {
33 _ = struct { field: i32 align(0) };33 _ = @as(struct { field: i32 align(0) }, undefined);
34}34}
3535
36export fn i() void {36export fn i() void {
37 _ = union { field: i32 align(0) };37 _ = @as(union { field: i32 align(0) }, undefined);
38}38}
3939
40export fn j() void {40export fn j() void {
...@@ -54,7 +54,7 @@ export fn k() void {...@@ -54,7 +54,7 @@ export fn k() void {
54// :20:30: error: alignment must be >= 154// :20:30: error: alignment must be >= 1
55// :25:16: error: alignment must be >= 155// :25:16: error: alignment must be >= 1
56// :29:17: error: alignment must be >= 156// :29:17: error: alignment must be >= 1
57// :33:35: error: alignment must be >= 157// :33:39: error: alignment must be >= 1
58// :37:34: error: alignment must be >= 158// :37:38: error: alignment must be >= 1
59// :41:51: error: alignment must be >= 159// :41:51: error: alignment must be >= 1
60// :45:25: error: alignment must be >= 160// :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 {...@@ -16,7 +16,11 @@ export fn entry3() void {
16// error16// error
17//17//
18// :3:23: error: bit-pointer cannot refer to value of type 'tmp.entry1.S'18// :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 types19// :3:23: note: non-packed structs do not have a bit-packed representation
20// :2:22: note: struct declared here
20// :8:36: error: bit-pointer cannot refer to value of type 'tmp.entry2.S'21// :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 types22// :8:36: note: non-packed structs do not have a bit-packed representation
23// :7:15: note: struct declared here
22// :13:23: error: bit-pointer cannot refer to value of type 'tmp.entry3.E'24// :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 {...@@ -8,4 +8,6 @@ pub export fn entry() void {
88
9// error9// error
10//10//
11// :1:27: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 111// :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 {...@@ -40,13 +40,13 @@ export fn entry() void {
4040
41// error41// error
42//42//
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'
44// :6:20: error: expected type 'f16', found 'i13'45// :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'
46// :6:20: error: expected type 'f32', found 'i26'47// :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'
48// :6:20: error: expected type 'f64', found 'i55'49// :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'
50// :6:20: error: expected type 'f80', found 'i66'51// :6:20: error: expected type 'f80', found 'i66'
51// :6:20: error: expected type 'f128', found 'u114'52// :6:20: error: expected type 'f80', found 'u65'
52// :6:20: error: expected type 'f128', found 'i115'
test/cases/compile_errors/comptime_var_referenced_by_type.zig+1-1
...@@ -21,6 +21,6 @@ comptime {...@@ -21,6 +21,6 @@ comptime {
21// error21// error
22//22//
23// :7:16: error: captured value contains reference to comptime var23// :7:16: error: captured value contains reference to comptime var
24// :7:16: note: 'wrapper' points to '@as(*const tmp.Wrapper, @ptrCast(&v0)).*', where24// :7:16: note: 'wrapper' points to 'v0', where
25// :16:5: note: 'v0.ptr' points to comptime var declared here25// :16:5: note: 'v0.ptr' points to comptime var declared here
26// :17:29: note: called at comptime here26// :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 {...@@ -7,4 +7,4 @@ export fn entry() usize {
77
8// error8// error
9//9//
10// :1:11: error: struct 'tmp.A' depends on itself10// :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 {...@@ -26,9 +26,11 @@ export fn d() void {
2626
27// error27// error
28//28//
29// :3:8: error: opaque types have unknown size and therefore cannot be directly embedded in structs29// :3:8: error: cannot directly embed opaque type 'tmp.O' in struct
30// :3:8: note: opaque types have unknown size
30// :1:11: note: opaque declared here31// :1:11: note: opaque declared here
31// :7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions32// :7:10: error: cannot directly embed opaque type 'tmp.O' in union
33// :7:10: note: opaque types have unknown size
32// :1:11: note: opaque declared here34// :1:11: note: opaque declared here
33// :18:24: error: cannot cast to opaque type 'tmp.O'35// :18:24: error: cannot cast to opaque type 'tmp.O'
34// :1:11: note: opaque declared here36// :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 @@...@@ -1,15 +1,11 @@
1pub const Foo = enum(c_int) {1pub const Foo = enum(c_int) {
2 A = Foo.B,2 a = 10,
3 C = D,3 b = @intFromEnum(Foo.a) - 1,
4
5 pub const B = 0;
6};4};
7export fn entry() void {5export fn entry() void {
8 const s: Foo = Foo.E;6 _ = @as(Foo, .a);
9 _ = s;
10}7}
11const D = 1;
128
13// error9// error
14//10//
15// :1:5: error: dependency loop detected11// :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;...@@ -10,4 +10,4 @@ const D = 1;
1010
11// error11// error
12//12//
13// :1:5: error: dependency loop detected13// :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 {...@@ -12,5 +12,5 @@ export fn entry() void {
1212
13// error13// error
14//14//
15// :6:9: error: enum tag value 60 already taken15// :6:9: error: enum tag value '60' for field 'E' already taken
16// :4:9: note: other occurrence here16// :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 {...@@ -26,5 +26,6 @@ pub fn main() Error!void {
26// error26// error
27// target=x86_64-linux27// target=x86_64-linux
28//28//
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'
30// :23:29: note: 'error.InvalidDirection' not a member of destination error set30// :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 {...@@ -11,6 +11,6 @@ comptime {
11//11//
12// :3:5: error: unable to export type 'type'12// :3:5: error: unable to export type 'type'
13// :7:5: error: unable to export type 'tmp.E'13// :7:5: error: unable to export type 'tmp.E'
14// :7:5: note: enum tag type 'u1' is not extern compatible14// :1:11: note: integer tag type of enum is inferred
15// :7:5: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible15// :1:11: note: consider explicitly specifying the integer tag type
16// :1:11: note: enum declared here16// :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 {...@@ -10,6 +10,6 @@ export fn entry() void {
10// error10// error
11//11//
12// :3:8: error: extern structs cannot contain fields of type 'tmp.E'12// :3:8: error: extern structs cannot contain fields of type 'tmp.E'
13// :3:8: note: enum tag type 'u31' is not extern compatible13// :1:15: note: enum tag type 'u31' is not extern compatible
14// :3:8: note: only integers with 0 or power of two bits are extern compatible14// :1:15: note: only integers with 0 or power of two bits are extern compatible
15// :1:15: note: enum declared here15// :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 {...@@ -11,5 +11,5 @@ comptime {
11// error11// error
12// target=x86_64-linux12// target=x86_64-linux
13//13//
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'
15// :8:41: note: pointer alignment '1' cannot cast into pointer alignment '2'15// :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 {...@@ -7,6 +7,6 @@ export fn entry(foo: Foo) void {
7// target=x86_64-linux7// target=x86_64-linux
8//8//
9// :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv'9// :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 compatible10// :1:13: note: integer tag type of enum is inferred
11// :2:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible11// :1:13: note: consider explicitly specifying the integer tag type
12// :1:13: note: enum declared here12// :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 {...@@ -11,5 +11,5 @@ export fn entry(foo: Foo) void {
11// target=x86_64-linux11// target=x86_64-linux
12//12//
13// :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv'13// :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 compatible14// :6:17: note: struct with automatic layout has no guaranteed in-memory representation
15// :1:13: note: struct declared here15// :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 {...@@ -11,5 +11,5 @@ export fn entry(foo: Foo) void {
11// target=x86_64-linux11// target=x86_64-linux
12//12//
13// :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv'13// :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 compatible14// :6:17: note: union with automatic layout has no guaranteed in-memory representation
15// :1:13: note: union declared here15// :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 {...@@ -11,6 +11,6 @@ export fn bar() void {
1111
12// error12// error
13//13//
14// :1:30: error: opaque return type 'anyopaque' not allowed
14// :1:30: error: opaque return type 'tmp.MyOpaque' not allowed15// :1:30: error: opaque return type 'tmp.MyOpaque' not allowed
15// :4:18: note: opaque declared here16// :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 {...@@ -6,4 +6,4 @@ export fn foo() void {
66
7// error7// error
8//8//
9// :3:27: error: indexing into empty array is not allowed9// :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 {...@@ -8,4 +8,4 @@ export fn foo() void {
88
9// error9// error
10//10//
11// :5:27: error: indexing into empty array is not allowed11// :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 {...@@ -13,4 +13,8 @@ export fn entry() usize {
1313
14// error14// error
15//15//
16// :1:11: error: struct 'tmp.A' depends on itself16// 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 {...@@ -10,4 +10,4 @@ export fn entry() usize {
1010
11// error11// error
12//12//
13// :1:13: error: struct 'tmp.Foo' depends on itself13// :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 {...@@ -10,4 +10,4 @@ export fn entry() usize {
1010
11// error11// error
12//12//
13// :1:13: error: union 'tmp.Foo' depends on itself13// :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 @@...@@ -1,16 +1,18 @@
1comptime {1const S = struct {
2 const S = struct {2 const Foo = struct {
3 const Foo = struct {3 y: Bar,
4 y: Bar,
5 };
6 const Bar = struct {
7 y: if (@sizeOf(Foo) == 0) u64 else void,
8 };
9 };4 };
105 const Bar = struct {
6 y: if (@sizeOf(Foo) == 0) u64 else void,
7 };
8};
9comptime {
11 _ = @sizeOf(S.Foo) + 1;10 _ = @sizeOf(S.Foo) + 1;
12}11}
1312
14// error13// error
15//14//
16// :6:21: error: struct layout depends on it having runtime bits15// 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 {...@@ -2,10 +2,10 @@ const stroo = extern struct {
2 moo: ?[*c]u8,2 moo: ?[*c]u8,
3};3};
4export fn testf(fluff: *stroo) void {4export fn testf(fluff: *stroo) void {
5 _ = fluff;5 _ = fluff.*;
6}6}
77
8// error8// error
9//9//
10// :2:10: error: extern structs cannot contain fields of type '?[*c]u8'10// :2:10: error: extern structs cannot contain fields of type '?[*c]u8'
11// :2:10: note: only pointer like optionals are extern compatible11// :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 {...@@ -26,11 +26,6 @@ comptime {
26 _ = x - y;26 _ = x - y;
27}27}
2828
29comptime {
30 const x: [*]u0 = @ptrFromInt(1);
31 _ = x + 1;
32}
33
34comptime {29comptime {
35 const x: *u0 = @ptrFromInt(1);30 const x: *u0 = @ptrFromInt(1);
36 const y: *u0 = @ptrFromInt(2);31 const y: *u0 = @ptrFromInt(2);
...@@ -46,5 +41,4 @@ comptime {...@@ -46,5 +41,4 @@ comptime {
46// :12:11: error: invalid operands to binary expression: 'pointer' and 'pointer'41// :12:11: error: invalid operands to binary expression: 'pointer' and 'pointer'
47// :20:11: error: incompatible pointer arithmetic operands '[*]u8' and '[*]u16'42// :20:11: error: incompatible pointer arithmetic operands '[*]u8' and '[*]u16'
48// :26:11: error: incompatible pointer arithmetic operands '*u8' and '*u16'43// :26:11: error: incompatible pointer arithmetic operands '*u8' and '*u16'
49// :31:11: error: pointer arithmetic requires element type 'u0' to have runtime bits44// :32:11: error: pointer subtraction requires element type 'u0' to have runtime bits
50// :37:11: error: pointer arithmetic requires element type 'u0' to have runtime bits
test/cases/compile_errors/invalid_type_in_builtin_extern.zig+10-4
...@@ -1,16 +1,22 @@...@@ -1,16 +1,22 @@
1const x = @extern(*comptime_int, .{ .name = "foo" });1const x = @extern(*comptime_int, .{ .name = "foo" });
2const y = @extern(*fn (u8) u8, .{ .name = "bar" });2const y = @extern(*fn (u8) u8, .{ .name = "bar" });
3pub export fn entry() void {3const z = @extern(*fn (u8) callconv(.c) u8, .{ .name = "bar" });
4comptime {
4 _ = x;5 _ = x;
5}6}
6pub export fn entry2() void {7comptime {
7 _ = y;8 _ = y;
8}9}
10comptime {
11 _ = z;
12}
913
10// error14// error
11//15//
12// :1:19: error: extern symbol cannot have type '*comptime_int'16// :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
14// :2:19: error: extern symbol cannot have type '*fn (u8) u8'18// :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
16// :2:19: note: extern function must specify calling convention20// :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 @@...@@ -1,49 +1,44 @@
1export fn entry1() void {1export fn entry0() void {
2 var m2 = &2;
3 _ = &m2;
4}
5export fn entry2() void {
6 var a = undefined;2 var a = undefined;
7 _ = &a;3 _ = &a;
8}4}
9export fn entry3() void {5export fn entry1() void {
10 var b = 1;6 var b = 1;
11 _ = &b;7 _ = &b;
12}8}
13export fn entry4() void {9export fn entry2() void {
14 var c = 1.0;10 var c = 1.0;
15 _ = &c;11 _ = &c;
16}12}
17export fn entry5() void {13export fn entry3() void {
18 var d = null;14 var d = null;
19 _ = &d;15 _ = &d;
20}16}
21export fn entry6(opaque_: *Opaque) void {17export fn entry4(opaque_: *Opaque) void {
22 var e = opaque_.*;18 var e = opaque_.*;
23 _ = &e;19 _ = &e;
24}20}
25export fn entry7() void {21export fn entry5() void {
26 var f = i32;22 var f = i32;
27 _ = &f;23 _ = &f;
28}24}
29const Opaque = opaque {};25const Opaque = opaque {};
30export fn entry8() void {26export fn entry6() void {
31 var e: Opaque = undefined;27 var e: Opaque = undefined;
32 _ = &e;28 _ = &e;
33}29}
3430
35// error31// error
36//32//
37// :2:9: error: variable of type '*const comptime_int' must be const or comptime33// :2:9: error: variable of type '@TypeOf(undefined)' must be const or comptime
38// :6:9: error: variable of type '@TypeOf(undefined)' must be const or comptime34// :6:9: error: variable of type 'comptime_int' must be const or comptime
39// :10:9: error: variable of type 'comptime_int' must be const or comptime35// :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
40// :10:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type37// :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 comptime38// :14:9: error: variable of type '@TypeOf(null)' must be const or comptime
42// :14:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type39// :18:20: error: cannot load opaque type 'tmp.Opaque'
43// :18:9: error: variable of type '@TypeOf(null)' must be const or comptime40// :25:16: note: opaque declared here
44// :22:20: error: cannot load opaque type 'tmp.Opaque'41// :22:9: error: variable of type 'type' must be const or comptime
45// :29:16: note: opaque declared here42// :22:9: note: types are not available at runtime
46// :26:9: error: variable of type 'type' must be const or comptime43// :27:12: error: non-extern variable with opaque type 'tmp.Opaque'
47// :26:9: note: types are not available at runtime44// :25:16: note: opaque declared here
48// :31:12: error: non-extern variable with opaque type 'tmp.Opaque'
49// :29: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 {...@@ -3,18 +3,7 @@ const A = enum {
3 b,3 b,
4 _ = 1,4 _ = 1,
5};5};
6const B = enum {
7 a,
8 b,
9 _,
10};
11comptime {
12 _ = A;
13 _ = B;
14}
156
16// error7// error
17//8//
18// :4:9: error: '_' is used to mark an enum as non-exhaustive and cannot be assigned a value9// :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) {...@@ -4,7 +4,7 @@ const C = enum(u1) {
4 _,4 _,
5};5};
6pub export fn entry() void {6pub export fn entry() void {
7 _ = C;7 _ = C.a;
8}8}
99
10// error10// 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 {...@@ -11,6 +11,6 @@ export fn entry() void {
1111
12// error12// error
13//13//
14// :7:10: error: values of type '[2]tmp.Foo' must be comptime-known, but index value is runtime-known14// :7:10: error: values of type 'tmp.Foo' must be comptime-known, but index value is runtime-known
15// :3:8: note: struct requires comptime because of this field15// :3:8: note: struct requires comptime because of this field
16// :3:8: note: types are not available at runtime16// :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 {...@@ -14,4 +14,4 @@ export fn entry() usize {
14//14//
15// :6:12: error: unable to resolve comptime value15// :6:12: error: unable to resolve comptime value
16// :2:12: note: called at comptime from here16// :2:12: note: called at comptime from here
17// :1:13: note: types must be comptime-known17// :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 {...@@ -4,15 +4,9 @@ const S = extern struct {
4comptime {4comptime {
5 _ = @sizeOf(S) == 1;5 _ = @sizeOf(S) == 1;
6}6}
7comptime {
8 _ = [*c][4]fn () callconv(.c) void;
9}
107
11// error8// error
12//9//
13// :2:8: error: extern structs cannot contain fields of type 'fn () callconv(.c) void'10// :2:8: error: extern structs cannot contain fields of type 'fn () callconv(.c) void'
14// :2:8: note: type has no guaranteed in-memory representation11// :2:8: note: type has no guaranteed in-memory representation
15// :2:8: note: use '*const ' to make a function pointer type12// :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 {...@@ -9,4 +9,4 @@ pub export fn entry() void {
99
10// error10// error
11//11//
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 {...@@ -44,8 +44,12 @@ export fn entry7() void {
4444
45// error45// error
46//46//
47// :2:31: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 2947// :2:24: error: backing integer bit width does not match total bit width of fields
48// :9:31: error: backing integer type 'i31' has bit size 31 but the struct fields have a total bit size of 3248// :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'
49// :17:31: error: expected backing integer type, found 'void'53// :17:31: error: expected backing integer type, found 'void'
50// :23:31: error: expected backing integer type, found 'void'54// :23:31: error: expected backing integer type, found 'void'
51// :27:31: error: expected backing integer type, found 'noreturn'55// :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 {...@@ -76,30 +76,41 @@ export fn entry14() void {
76 x: E,76 x: E,
77 });77 });
78}78}
79export fn entry15() void {
80 _ = @sizeOf(packed struct {
81 x: *const u32,
82 });
83}
7984
80// error85// error
81//86//
82// :3:12: error: packed structs cannot contain fields of type 'anyerror'87// :3:12: error: packed structs cannot contain fields of type 'anyerror'
83// :3:12: note: type has no guaranteed in-memory representation88// :3:12: note: type does not have a bit-packed representation
84// :8:12: error: packed structs cannot contain fields of type '[2]u24'89// :8:12: error: packed structs cannot contain fields of type '[2]u24'
85// :8:12: note: type has no guaranteed in-memory representation90// :8:12: note: type does not have a bit-packed representation
86// :13:20: error: packed structs cannot contain fields of type 'anyerror!u32'91// :13:20: error: packed structs cannot contain fields of type 'anyerror!u32'
87// :13:20: note: type has no guaranteed in-memory representation92// :13:20: note: type does not have a bit-packed representation
88// :18:12: error: packed structs cannot contain fields of type 'tmp.S'93// :18:12: error: packed structs cannot contain fields of type 'tmp.S'
89// :18:12: note: only packed structs layout are allowed in packed types94// :18:12: note: non-packed structs do not have a bit-packed representation
90// :56:11: note: struct declared here95// :56:11: note: struct declared here
91// :23:12: error: packed structs cannot contain fields of type 'tmp.U'96// :23:12: error: packed structs cannot contain fields of type 'tmp.U'
92// :23:12: note: only packed unions layout are allowed in packed types97// :23:12: note: non-packed unions do not have a bit-packed representation
93// :59:18: note: union declared here98// :59:18: note: union declared here
94// :28:12: error: packed structs cannot contain fields of type '?anyerror'99// :28:12: error: packed structs cannot contain fields of type '?anyerror'
95// :28:12: note: type has no guaranteed in-memory representation100// :28:12: note: type does not have a bit-packed representation
96// :38:12: error: packed structs cannot contain fields of type 'fn () void'101// :38:12: error: packed structs cannot contain fields of type 'fn () void'
97// :38:12: note: type has no guaranteed in-memory representation102// :38:12: note: type does not have a bit-packed representation
98// :38:12: note: use '*const ' to make a function pointer type103// :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'
99// :65:31: error: packed structs cannot contain fields of type '[]u8'106// :65:31: error: packed structs cannot contain fields of type '[]u8'
100// :65:31: note: slices have no guaranteed in-memory representation107// :65:31: note: slices do not have a bit-packed representation
101// :70:12: error: packed structs cannot contain fields of type '*type'108// :70:12: error: packed structs cannot contain fields of type '*type'
102// :70:12: note: comptime-only pointer has no guaranteed in-memory representation109// :70:12: note: pointers cannot be directly bitpacked
103// :70:12: note: types are not available at runtime110// :70:12: note: consider using 'usize' and '@intFromPtr'
104// :76:12: error: packed structs cannot contain fields of type 'tmp.entry14.E'111// :76:12: error: packed structs cannot contain fields of type 'tmp.entry14.E'
105// :74:15: note: enum declared here112// :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 @@...@@ -1,12 +1,14 @@
1export fn entry1() void {1export fn entry1() void {
2 _ = packed union {2 const U = packed union {
3 a: u1,3 a: u1,
4 b: u2,4 b: u2,
5 };5 };
6 _ = @as(U, undefined);
6}7}
78
8// error9// error
9//10//
10// :2:16: error: packed union has fields with mismatching bit sizes11// :4:12: error: field bit width does not match earlier field
11// :3:12: note: 1 bits here12// :4:12: note: field type 'u2' has bit width '2'
12// :4:12: note: 2 bits here13// :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 @@...@@ -1,8 +1,9 @@
1export fn entry() void {1export 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);
3}4}
45
5// error6// error
6//7//
7// :2:36: error: duplicate enum field 'A'8// :2:42: error: duplicate enum field 'A' at index '1'
8// :2:36: note: other field here9// :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 @@...@@ -1,8 +1,9 @@
1export fn entry() void {1export fn entry() void {
2 _ = @Enum(u32, .nonexhaustive, &.{ "A", "B" }, &.{ 10, 10 });2 const E = @Enum(u32, .nonexhaustive, &.{ "a", "b" }, &.{ 10, 10 });
3 _ = E.a;
3}4}
45
5// error6// error
6//7//
7// :2:52: error: enum tag value 10 already taken8// :2:58: error: enum tag value '10' for field 'b' already taken
8// :2:52: note: other enum tag value here9// :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 {...@@ -5,4 +5,4 @@ export fn entry() void {
55
6// error6// error
7//7//
8// :1:19: error: tag type must be an integer type8// :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 {...@@ -7,6 +7,5 @@ export fn entry() void {
77
8// error8// error
9//9//
10// :2:35: error: 1 enum fields missing in union10// :2:16: error: enum field 'arst' missing from union
11// :1:13: note: field 'arst' missing, declared here11// :1:36: note: enum field here
12// :1:13: note: enum declared 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 {...@@ -7,7 +7,5 @@ export fn entry() void {
77
8// error8// error
9//9//
10// :2:35: error: 2 enum fields missing in union10// :2:16: error: enum field 'signed' missing from union
11// :1:13: note: field 'signed' missing, declared here11// :1:36: note: enum field here
12// :1:13: note: field 'unsigned' missing, declared here
13// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_union_with_opaque_field.zig+5-3
...@@ -1,9 +1,11 @@...@@ -1,9 +1,11 @@
1const Untagged = @Union(.auto, null, &.{"foo"}, &.{opaque {}}, &.{.{}});1const Opaque = opaque {};
2const Untagged = @Union(.auto, null, &.{"foo"}, &.{Opaque}, &.{.{}});
2export fn entry() usize {3export fn entry() usize {
3 return @sizeOf(Untagged);4 return @sizeOf(Untagged);
4}5}
56
6// error7// error
7//8//
8// :1:49: error: opaque types have unknown size and therefore cannot be directly embedded in unions9// :2:49: error: cannot directly embed opaque type 'tmp.Opaque' in union
9// :1:52: note: opaque declared here10// :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 {...@@ -2,7 +2,11 @@ comptime {
2 _ = @Union(.auto, null, &.{"foo"}, &.{usize}, &.{.{ .@"align" = 3 }});2 _ = @Union(.auto, null, &.{"foo"}, &.{usize}, &.{.{ .@"align" = 3 }});
3}3}
4comptime {4comptime {
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 }});
6}10}
7comptime {11comptime {
8 _ = @Pointer(.many, .{ .@"align" = 7 }, u8, null);12 _ = @Pointer(.many, .{ .@"align" = 7 }, u8, null);
...@@ -12,4 +16,4 @@ comptime {...@@ -12,4 +16,4 @@ comptime {
12//16//
13// :2:51: error: alignment value '3' is not a power of two17// :2:51: error: alignment value '3' is not a power of two
14// :5:48: error: alignment value '5' is not a power of two18// :5:48: error: alignment value '5' is not a power of two
15// :8:26: error: alignment value '7' is not a power of two19// :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 {...@@ -12,5 +12,4 @@ export fn entry() void {
1212
13// error13// error
14//14//
15// :10:15: error: unable to resolve inferred error set of generic function15// :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'
16// :1:1: note: generic function declared here
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 {...@@ -10,6 +10,5 @@ pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void {
1010
11// error11// error
12//12//
13// :5:54: error: pointer to comptime-only type '?*tmp.GuSettings' must be comptime-known, but operand is runtime-known13// :6:19: error: cannot load comptime-only type '?fn (c_int) callconv(.c) void'
14// :2:10: note: struct requires comptime because of this field14// :6:20: note: pointer of type '*?fn (c_int) callconv(.c) void' is runtime-known
15// :2:10: note: use '*const fn (c_int) callconv(.c) void' for a function pointer type
test/cases/compile_errors/runtime_index_into_comptime_only_many_ptr.zig+3-3
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1var rt: usize = 0;1var rt: usize = 0;
2export fn foo() void {2export fn foo() void {
3 const x: [*]const type = &.{ u8, u16 };3 const x: [*]const type = &.{ u8, u16 };
4 _ = &x[rt];4 _ = x[rt];
5}5}
66
7// error7// error
8//8//
9// :4:12: error: values of type '[*]const type' must be comptime-known, but index value is runtime-known9// :4:11: error: values of type 'type' must be comptime-known, but index value is runtime-known
10// :4:11: note: types are not available at runtime10// :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 {...@@ -12,7 +12,6 @@ export fn entry() void {
1212
13// error13// error
14//14//
15// :9:54: error: values of type '[]const builtin.Type.StructField' must be comptime-known, but index value is runtime-known15// :9:54: error: values of type 'builtin.Type.StructField' must be comptime-known, but index value is runtime-known
16// : note: struct requires comptime because of this field16// : note: struct requires comptime because of this field
17// : note: types are not available at runtime17// : 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 {...@@ -24,9 +24,9 @@ pub export fn entry3() void {
24}24}
25// error25// error
26//26//
27// :7:10: error: values of type '[2]fn () void' must be comptime-known, but index value is runtime-known27// :7:10: error: values of type 'fn () void' must be comptime-known, but index value is runtime-known
28// :7:10: note: use '*const fn () void' for a function pointer type28// :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-known29// :15:18: error: values of type 'fn () void' must be comptime-known, but index value is runtime-known
30// :15:17: note: use '*const fn () void' for a function pointer type30// :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-known31// :22:19: error: values of type 'fn () void' must be comptime-known, but index value is runtime-known
32// :22:18: note: use '*const fn () void' for a function pointer type32// :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;...@@ -25,13 +25,13 @@ var rt: u32 = undefined;
25//25//
26// :19:8: error: unable to evaluate comptime expression26// :19:8: error: unable to evaluate comptime expression
27// :19:5: note: operation is runtime due to this operand27// :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
28// :14:8: note: called at comptime from here32// :14:8: note: called at comptime from here
29// :10:12: note: called at comptime from here33// :10:12: note: called at comptime from here
30// :10:12: note: call to function with comptime-only return type 'type' is evaluated at comptime34// :10:12: note: call to function with comptime-only return type 'type' is evaluated at comptime
31// :13:10: note: return type declared here35// :13:10: note: return type declared here
32// :10:12: note: types are not available at runtime36// :10:12: note: types are not available at runtime
33// :2:8: note: called inline here37// :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 {...@@ -12,4 +12,3 @@ pub export fn entry() void {
12// :6:12: error: variable of type 'tmp.S' must be const or comptime12// :6:12: error: variable of type 'tmp.S' must be const or comptime
13// :2:8: note: struct requires comptime because of this field13// :2:8: note: struct requires comptime because of this field
14// :2:8: note: use '*const fn () void' for a function pointer type14// :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 {...@@ -12,4 +12,3 @@ pub export fn entry() void {
12// :6:12: error: variable of type 'tmp.U' must be const or comptime12// :6:12: error: variable of type 'tmp.U' must be const or comptime
13// :2:8: note: union requires comptime because of this field13// :2:8: note: union requires comptime because of this field
14// :2:8: note: use '*const fn () void' for a function pointer type14// :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 @@...@@ -1,7 +1,31 @@
1export fn entry() usize {1export fn entry0() usize {
2 return @sizeOf(@TypeOf(null));2 return @sizeOf(@TypeOf(null));
3}3}
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
5// error22// error
6//23//
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 @@...@@ -1,6 +1,6 @@
1extern fn Text(str: []const u8, num: i32) callconv(.c) void;1extern fn Text(str: []const u8, num: i32) callconv(.c) void;
2export fn entry() void {2export fn entry() void {
3 _ = Text;3 Text(undefined, undefined);
4}4}
55
6// error6// error
test/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig+9-9
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1const Small = enum(u2) {1const Small = enum(u2) {
2 One,2 one,
3 Two,3 two,
4 Three,4 three,
5 Four,5 four,
6 Five,6 five,
7};7};
88
9const SmallUnion = union(enum(u2)) {9const SmallUnion = union(enum(u2)) {
...@@ -14,13 +14,13 @@ const SmallUnion = union(enum(u2)) {...@@ -14,13 +14,13 @@ const SmallUnion = union(enum(u2)) {
14};14};
1515
16comptime {16comptime {
17 _ = Small;17 _ = Small.one;
18}18}
19comptime {19comptime {
20 _ = SmallUnion;20 _ = SmallUnion.one;
21}21}
2222
23// error23// error
24//24//
25// :6: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: enumeration 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 {...@@ -21,22 +21,15 @@ export fn e() void {
21 p.* = undefined;21 p.* = undefined;
22}22}
2323
24export fn f() void {
25 const p: **comptime_int = @ptrFromInt(16); // double pointer ('*comptime_int' is comptime-only)
26 p.* = undefined;
27}
28
29// error24// error
30//25//
31// :3:9: error: cannot store comptime-only type 'fn () void' at runtime26// :3:9: error: cannot store comptime-only type 'fn () void' at runtime
32// :3:6: note: operation is runtime due to this pointer27// :3:6: note: operation is runtime due to this pointer
33// :7:11: error: expected type 'anyopaque', found '@TypeOf(undefined)'28// :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'
35// :11:12: error: cannot load opaque type 'anyopaque'30// :11:12: error: cannot load opaque type 'anyopaque'
36// :16:11: error: expected type 'tmp.Opaque', found '@TypeOf(undefined)'31// :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'
38// :14:16: note: opaque declared here33// :14:16: note: opaque declared here
39// :21:9: error: cannot store comptime-only type 'comptime_int' at runtime34// :21:9: error: cannot store comptime-only type 'comptime_int' at runtime
40// :21:6: note: operation is runtime due to this pointer35// :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 {...@@ -4,9 +4,9 @@ const A = struct {
4};4};
55
6comptime {6comptime {
7 _ = A;7 _ = @as(A, undefined);
8}8}
99
10// error10// error
11//11//
12// :1:11: error: struct 'tmp.A' depends on itself12// :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 {...@@ -12,4 +12,7 @@ export fn entry() void {
1212
13// error13// error
14//14//
15// :1:17: error: struct 'tmp.LhsExpr' depends on itself15// 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 {...@@ -8,4 +8,4 @@ pub export fn entry() void {
88
9// error9// error
10//10//
11// :2:22: error: size of packed struct '131070' exceeds maximum bit width of 6553511// :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 {...@@ -7,4 +7,9 @@ export fn entry() void {
77
8// error8// error
9//9//
10// :1:1: error: dependency loop detected10// 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 {...@@ -16,22 +16,6 @@ pub export fn entry2() void {
16 _ = b;16 _ = b;
17}17}
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
35// error19// error
36//20//
37// :7:13: error: unable to evaluate comptime expression21// :7:13: error: unable to evaluate comptime expression
...@@ -40,6 +24,3 @@ pub export fn entry3() void {...@@ -40,6 +24,3 @@ pub export fn entry3() void {
40// :13:13: error: unable to evaluate comptime expression24// :13:13: error: unable to evaluate comptime expression
41// :13:16: note: operation is runtime due to this operand25// :13:16: note: operation is runtime due to this operand
42// :13:13: note: initializer of container-level variable must be comptime-known26// :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");...@@ -192,50 +192,30 @@ const std = @import("std");
192// :65:17: error: use of undefined value here causes illegal behavior192// :65:17: error: use of undefined value here causes illegal behavior
193// :65:17: error: use of undefined value here causes illegal behavior193// :65:17: error: use of undefined value here causes illegal behavior
194// :65:17: error: use of undefined value here causes illegal behavior194// :65:17: error: use of undefined value here causes illegal behavior
195// :65:17: note: when computing vector element at index '0'
196// :65:17: error: use of undefined value here causes illegal behavior195// :65:17: error: use of undefined value here causes illegal behavior
197// :65:17: note: when computing vector element at index '0'
198// :65:17: error: use of undefined value here causes illegal behavior196// :65:17: error: use of undefined value here causes illegal behavior
199// :65:17: note: when computing vector element at index '0'
200// :65:17: error: use of undefined value here causes illegal behavior197// :65:17: error: use of undefined value here causes illegal behavior
201// :65:17: note: when computing vector element at index '0'
202// :65:17: error: use of undefined value here causes illegal behavior198// :65:17: error: use of undefined value here causes illegal behavior
203// :65:17: note: when computing vector element at index '1'
204// :65:17: error: use of undefined value here causes illegal behavior199// :65:17: error: use of undefined value here causes illegal behavior
205// :65:17: note: when computing vector element at index '1'
206// :65:17: error: use of undefined value here causes illegal behavior200// :65:17: error: use of undefined value here causes illegal behavior
207// :65:17: note: when computing vector element at index '0'
208// :65:17: error: use of undefined value here causes illegal behavior201// :65:17: error: use of undefined value here causes illegal behavior
209// :65:17: note: when computing vector element at index '0'
210// :65:17: error: use of undefined value here causes illegal behavior202// :65:17: error: use of undefined value here causes illegal behavior
211// :65:17: note: when computing vector element at index '0'
212// :65:17: error: use of undefined value here causes illegal behavior203// :65:17: error: use of undefined value here causes illegal behavior
213// :65:17: note: when computing vector element at index '0'
214// :65:17: error: use of undefined value here causes illegal behavior204// :65:17: error: use of undefined value here causes illegal behavior
215// :65:17: error: use of undefined value here causes illegal behavior205// :65:17: error: use of undefined value here causes illegal behavior
216// :65:17: error: use of undefined value here causes illegal behavior206// :65:17: error: use of undefined value here causes illegal behavior
217// :65:17: note: when computing vector element at index '0'
218// :65:17: error: use of undefined value here causes illegal behavior207// :65:17: error: use of undefined value here causes illegal behavior
219// :65:17: note: when computing vector element at index '0'
220// :65:17: error: use of undefined value here causes illegal behavior208// :65:17: error: use of undefined value here causes illegal behavior
221// :65:17: note: when computing vector element at index '0'
222// :65:17: error: use of undefined value here causes illegal behavior209// :65:17: error: use of undefined value here causes illegal behavior
223// :65:17: note: when computing vector element at index '0'
224// :65:17: error: use of undefined value here causes illegal behavior210// :65:17: error: use of undefined value here causes illegal behavior
225// :65:17: note: when computing vector element at index '1'
226// :65:17: error: use of undefined value here causes illegal behavior211// :65:17: error: use of undefined value here causes illegal behavior
227// :65:17: note: when computing vector element at index '1'
228// :65:17: error: use of undefined value here causes illegal behavior212// :65:17: error: use of undefined value here causes illegal behavior
229// :65:17: note: when computing vector element at index '0'
230// :65:17: error: use of undefined value here causes illegal behavior213// :65:17: error: use of undefined value here causes illegal behavior
231// :65:17: note: when computing vector element at index '0'
232// :65:17: error: use of undefined value here causes illegal behavior214// :65:17: error: use of undefined value here causes illegal behavior
233// :65:17: note: when computing vector element at index '0'215// :65:17: note: when computing vector element at index '0'
234// :65:17: error: use of undefined value here causes illegal behavior216// :65:17: error: use of undefined value here causes illegal behavior
235// :65:17: note: when computing vector element at index '0'217// :65:17: note: when computing vector element at index '0'
236// :65:17: error: use of undefined value here causes illegal behavior218// :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
239// :65:17: note: when computing vector element at index '0'219// :65:17: note: when computing vector element at index '0'
240// :65:17: error: use of undefined value here causes illegal behavior220// :65:17: error: use of undefined value here causes illegal behavior
241// :65:17: note: when computing vector element at index '0'221// :65:17: note: when computing vector element at index '0'
...@@ -244,10 +224,6 @@ const std = @import("std");...@@ -244,10 +224,6 @@ const std = @import("std");
244// :65:17: error: use of undefined value here causes illegal behavior224// :65:17: error: use of undefined value here causes illegal behavior
245// :65:17: note: when computing vector element at index '0'225// :65:17: note: when computing vector element at index '0'
246// :65:17: error: use of undefined value here causes illegal behavior226// :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
251// :65:17: note: when computing vector element at index '0'227// :65:17: note: when computing vector element at index '0'
252// :65:17: error: use of undefined value here causes illegal behavior228// :65:17: error: use of undefined value here causes illegal behavior
253// :65:17: note: when computing vector element at index '0'229// :65:17: note: when computing vector element at index '0'
...@@ -256,7 +232,9 @@ const std = @import("std");...@@ -256,7 +232,9 @@ const std = @import("std");
256// :65:17: error: use of undefined value here causes illegal behavior232// :65:17: error: use of undefined value here causes illegal behavior
257// :65:17: note: when computing vector element at index '0'233// :65:17: note: when computing vector element at index '0'
258// :65:17: error: use of undefined value here causes illegal behavior234// :65:17: error: use of undefined value here causes illegal behavior
235// :65:17: note: when computing vector element at index '0'
259// :65:17: error: use of undefined value here causes illegal behavior236// :65:17: error: use of undefined value here causes illegal behavior
237// :65:17: note: when computing vector element at index '0'
260// :65:17: error: use of undefined value here causes illegal behavior238// :65:17: error: use of undefined value here causes illegal behavior
261// :65:17: note: when computing vector element at index '0'239// :65:17: note: when computing vector element at index '0'
262// :65:17: error: use of undefined value here causes illegal behavior240// :65:17: error: use of undefined value here causes illegal behavior
...@@ -266,9 +244,9 @@ const std = @import("std");...@@ -266,9 +244,9 @@ const std = @import("std");
266// :65:17: error: use of undefined value here causes illegal behavior244// :65:17: error: use of undefined value here causes illegal behavior
267// :65:17: note: when computing vector element at index '0'245// :65:17: note: when computing vector element at index '0'
268// :65:17: error: use of undefined value here causes illegal behavior246// :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'
270// :65:17: error: use of undefined value here causes illegal behavior248// :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'
272// :65:17: error: use of undefined value here causes illegal behavior250// :65:17: error: use of undefined value here causes illegal behavior
273// :65:17: note: when computing vector element at index '0'251// :65:17: note: when computing vector element at index '0'
274// :65:17: error: use of undefined value here causes illegal behavior252// :65:17: error: use of undefined value here causes illegal behavior
...@@ -278,7 +256,9 @@ const std = @import("std");...@@ -278,7 +256,9 @@ const std = @import("std");
278// :65:17: error: use of undefined value here causes illegal behavior256// :65:17: error: use of undefined value here causes illegal behavior
279// :65:17: note: when computing vector element at index '0'257// :65:17: note: when computing vector element at index '0'
280// :65:17: error: use of undefined value here causes illegal behavior258// :65:17: error: use of undefined value here causes illegal behavior
259// :65:17: note: when computing vector element at index '0'
281// :65:17: error: use of undefined value here causes illegal behavior260// :65:17: error: use of undefined value here causes illegal behavior
261// :65:17: note: when computing vector element at index '0'
282// :65:17: error: use of undefined value here causes illegal behavior262// :65:17: error: use of undefined value here causes illegal behavior
283// :65:17: note: when computing vector element at index '0'263// :65:17: note: when computing vector element at index '0'
284// :65:17: error: use of undefined value here causes illegal behavior264// :65:17: error: use of undefined value here causes illegal behavior
...@@ -288,9 +268,9 @@ const std = @import("std");...@@ -288,9 +268,9 @@ const std = @import("std");
288// :65:17: error: use of undefined value here causes illegal behavior268// :65:17: error: use of undefined value here causes illegal behavior
289// :65:17: note: when computing vector element at index '0'269// :65:17: note: when computing vector element at index '0'
290// :65:17: error: use of undefined value here causes illegal behavior270// :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'
292// :65:17: error: use of undefined value here causes illegal behavior272// :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'
294// :65:17: error: use of undefined value here causes illegal behavior274// :65:17: error: use of undefined value here causes illegal behavior
295// :65:17: note: when computing vector element at index '0'275// :65:17: note: when computing vector element at index '0'
296// :65:17: error: use of undefined value here causes illegal behavior276// :65:17: error: use of undefined value here causes illegal behavior
...@@ -300,7 +280,9 @@ const std = @import("std");...@@ -300,7 +280,9 @@ const std = @import("std");
300// :65:17: error: use of undefined value here causes illegal behavior280// :65:17: error: use of undefined value here causes illegal behavior
301// :65:17: note: when computing vector element at index '0'281// :65:17: note: when computing vector element at index '0'
302// :65:17: error: use of undefined value here causes illegal behavior282// :65:17: error: use of undefined value here causes illegal behavior
283// :65:17: note: when computing vector element at index '0'
303// :65:17: error: use of undefined value here causes illegal behavior284// :65:17: error: use of undefined value here causes illegal behavior
285// :65:17: note: when computing vector element at index '0'
304// :65:17: error: use of undefined value here causes illegal behavior286// :65:17: error: use of undefined value here causes illegal behavior
305// :65:17: note: when computing vector element at index '0'287// :65:17: note: when computing vector element at index '0'
306// :65:17: error: use of undefined value here causes illegal behavior288// :65:17: error: use of undefined value here causes illegal behavior
...@@ -310,9 +292,9 @@ const std = @import("std");...@@ -310,9 +292,9 @@ const std = @import("std");
310// :65:17: error: use of undefined value here causes illegal behavior292// :65:17: error: use of undefined value here causes illegal behavior
311// :65:17: note: when computing vector element at index '0'293// :65:17: note: when computing vector element at index '0'
312// :65:17: error: use of undefined value here causes illegal behavior294// :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'
314// :65:17: error: use of undefined value here causes illegal behavior296// :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'
316// :65:17: error: use of undefined value here causes illegal behavior298// :65:17: error: use of undefined value here causes illegal behavior
317// :65:17: note: when computing vector element at index '0'299// :65:17: note: when computing vector element at index '0'
318// :65:17: error: use of undefined value here causes illegal behavior300// :65:17: error: use of undefined value here causes illegal behavior
...@@ -322,7 +304,9 @@ const std = @import("std");...@@ -322,7 +304,9 @@ const std = @import("std");
322// :65:17: error: use of undefined value here causes illegal behavior304// :65:17: error: use of undefined value here causes illegal behavior
323// :65:17: note: when computing vector element at index '0'305// :65:17: note: when computing vector element at index '0'
324// :65:17: error: use of undefined value here causes illegal behavior306// :65:17: error: use of undefined value here causes illegal behavior
307// :65:17: note: when computing vector element at index '0'
325// :65:17: error: use of undefined value here causes illegal behavior308// :65:17: error: use of undefined value here causes illegal behavior
309// :65:17: note: when computing vector element at index '0'
326// :65:17: error: use of undefined value here causes illegal behavior310// :65:17: error: use of undefined value here causes illegal behavior
327// :65:17: note: when computing vector element at index '0'311// :65:17: note: when computing vector element at index '0'
328// :65:17: error: use of undefined value here causes illegal behavior312// :65:17: error: use of undefined value here causes illegal behavior
...@@ -332,9 +316,9 @@ const std = @import("std");...@@ -332,9 +316,9 @@ const std = @import("std");
332// :65:17: error: use of undefined value here causes illegal behavior316// :65:17: error: use of undefined value here causes illegal behavior
333// :65:17: note: when computing vector element at index '0'317// :65:17: note: when computing vector element at index '0'
334// :65:17: error: use of undefined value here causes illegal behavior318// :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'
336// :65:17: error: use of undefined value here causes illegal behavior320// :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'
338// :65:17: error: use of undefined value here causes illegal behavior322// :65:17: error: use of undefined value here causes illegal behavior
339// :65:17: note: when computing vector element at index '0'323// :65:17: note: when computing vector element at index '0'
340// :65:17: error: use of undefined value here causes illegal behavior324// :65:17: error: use of undefined value here causes illegal behavior
...@@ -344,7 +328,9 @@ const std = @import("std");...@@ -344,7 +328,9 @@ const std = @import("std");
344// :65:17: error: use of undefined value here causes illegal behavior328// :65:17: error: use of undefined value here causes illegal behavior
345// :65:17: note: when computing vector element at index '0'329// :65:17: note: when computing vector element at index '0'
346// :65:17: error: use of undefined value here causes illegal behavior330// :65:17: error: use of undefined value here causes illegal behavior
331// :65:17: note: when computing vector element at index '0'
347// :65:17: error: use of undefined value here causes illegal behavior332// :65:17: error: use of undefined value here causes illegal behavior
333// :65:17: note: when computing vector element at index '0'
348// :65:17: error: use of undefined value here causes illegal behavior334// :65:17: error: use of undefined value here causes illegal behavior
349// :65:17: note: when computing vector element at index '0'335// :65:17: note: when computing vector element at index '0'
350// :65:17: error: use of undefined value here causes illegal behavior336// :65:17: error: use of undefined value here causes illegal behavior
...@@ -354,9 +340,9 @@ const std = @import("std");...@@ -354,9 +340,9 @@ const std = @import("std");
354// :65:17: error: use of undefined value here causes illegal behavior340// :65:17: error: use of undefined value here causes illegal behavior
355// :65:17: note: when computing vector element at index '0'341// :65:17: note: when computing vector element at index '0'
356// :65:17: error: use of undefined value here causes illegal behavior342// :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'
358// :65:17: error: use of undefined value here causes illegal behavior344// :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'
360// :65:17: error: use of undefined value here causes illegal behavior346// :65:17: error: use of undefined value here causes illegal behavior
361// :65:17: note: when computing vector element at index '0'347// :65:17: note: when computing vector element at index '0'
362// :65:17: error: use of undefined value here causes illegal behavior348// :65:17: error: use of undefined value here causes illegal behavior
...@@ -366,7 +352,9 @@ const std = @import("std");...@@ -366,7 +352,9 @@ const std = @import("std");
366// :65:17: error: use of undefined value here causes illegal behavior352// :65:17: error: use of undefined value here causes illegal behavior
367// :65:17: note: when computing vector element at index '0'353// :65:17: note: when computing vector element at index '0'
368// :65:17: error: use of undefined value here causes illegal behavior354// :65:17: error: use of undefined value here causes illegal behavior
355// :65:17: note: when computing vector element at index '0'
369// :65:17: error: use of undefined value here causes illegal behavior356// :65:17: error: use of undefined value here causes illegal behavior
357// :65:17: note: when computing vector element at index '0'
370// :65:17: error: use of undefined value here causes illegal behavior358// :65:17: error: use of undefined value here causes illegal behavior
371// :65:17: note: when computing vector element at index '0'359// :65:17: note: when computing vector element at index '0'
372// :65:17: error: use of undefined value here causes illegal behavior360// :65:17: error: use of undefined value here causes illegal behavior
...@@ -376,9 +364,9 @@ const std = @import("std");...@@ -376,9 +364,9 @@ const std = @import("std");
376// :65:17: error: use of undefined value here causes illegal behavior364// :65:17: error: use of undefined value here causes illegal behavior
377// :65:17: note: when computing vector element at index '0'365// :65:17: note: when computing vector element at index '0'
378// :65:17: error: use of undefined value here causes illegal behavior366// :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'
380// :65:17: error: use of undefined value here causes illegal behavior368// :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'
382// :65:17: error: use of undefined value here causes illegal behavior370// :65:17: error: use of undefined value here causes illegal behavior
383// :65:17: note: when computing vector element at index '0'371// :65:17: note: when computing vector element at index '0'
384// :65:17: error: use of undefined value here causes illegal behavior372// :65:17: error: use of undefined value here causes illegal behavior
...@@ -388,7 +376,9 @@ const std = @import("std");...@@ -388,7 +376,9 @@ const std = @import("std");
388// :65:17: error: use of undefined value here causes illegal behavior376// :65:17: error: use of undefined value here causes illegal behavior
389// :65:17: note: when computing vector element at index '0'377// :65:17: note: when computing vector element at index '0'
390// :65:17: error: use of undefined value here causes illegal behavior378// :65:17: error: use of undefined value here causes illegal behavior
379// :65:17: note: when computing vector element at index '0'
391// :65:17: error: use of undefined value here causes illegal behavior380// :65:17: error: use of undefined value here causes illegal behavior
381// :65:17: note: when computing vector element at index '0'
392// :65:17: error: use of undefined value here causes illegal behavior382// :65:17: error: use of undefined value here causes illegal behavior
393// :65:17: note: when computing vector element at index '0'383// :65:17: note: when computing vector element at index '0'
394// :65:17: error: use of undefined value here causes illegal behavior384// :65:17: error: use of undefined value here causes illegal behavior
...@@ -402,35 +392,45 @@ const std = @import("std");...@@ -402,35 +392,45 @@ const std = @import("std");
402// :65:17: error: use of undefined value here causes illegal behavior392// :65:17: error: use of undefined value here causes illegal behavior
403// :65:17: note: when computing vector element at index '1'393// :65:17: note: when computing vector element at index '1'
404// :65:17: error: use of undefined value here causes illegal behavior394// :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'
406// :65:17: error: use of undefined value here causes illegal behavior396// :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'
408// :65:17: error: use of undefined value here causes illegal behavior398// :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'
410// :65:17: error: use of undefined value here causes illegal behavior400// :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'
412// :65:17: error: use of undefined value here causes illegal behavior402// :65:17: error: use of undefined value here causes illegal behavior
403// :65:17: note: when computing vector element at index '1'
413// :65:17: error: use of undefined value here causes illegal behavior404// :65:17: error: use of undefined value here causes illegal behavior
405// :65:17: note: when computing vector element at index '1'
414// :65:17: error: use of undefined value here causes illegal behavior406// :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'
416// :65:17: error: use of undefined value here causes illegal behavior408// :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'
418// :65:17: error: use of undefined value here causes illegal behavior410// :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'
420// :65:17: error: use of undefined value here causes illegal behavior412// :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'
422// :65:17: error: use of undefined value here causes illegal behavior414// :65:17: error: use of undefined value here causes illegal behavior
423// :65:17: note: when computing vector element at index '1'415// :65:17: note: when computing vector element at index '1'
424// :65:17: error: use of undefined value here causes illegal behavior416// :65:17: error: use of undefined value here causes illegal behavior
425// :65:17: note: when computing vector element at index '1'417// :65:17: note: when computing vector element at index '1'
426// :65:17: error: use of undefined value here causes illegal behavior418// :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'
428// :65:17: error: use of undefined value here causes illegal behavior420// :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'
430// :65:17: error: use of undefined value here causes illegal behavior422// :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'
432// :65:17: error: use of undefined value here causes illegal behavior424// :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'
434// :65:21: error: use of undefined value here causes illegal behavior434// :65:21: error: use of undefined value here causes illegal behavior
435// :65:21: note: when computing vector element at index '0'435// :65:21: note: when computing vector element at index '0'
436// :65:21: error: use of undefined value here causes illegal behavior436// :65:21: error: use of undefined value here causes illegal behavior
...@@ -478,50 +478,30 @@ const std = @import("std");...@@ -478,50 +478,30 @@ const std = @import("std");
478// :69:27: error: use of undefined value here causes illegal behavior478// :69:27: error: use of undefined value here causes illegal behavior
479// :69:27: error: use of undefined value here causes illegal behavior479// :69:27: error: use of undefined value here causes illegal behavior
480// :69:27: error: use of undefined value here causes illegal behavior480// :69:27: error: use of undefined value here causes illegal behavior
481// :69:27: note: when computing vector element at index '0'
482// :69:27: error: use of undefined value here causes illegal behavior481// :69:27: error: use of undefined value here causes illegal behavior
483// :69:27: note: when computing vector element at index '0'
484// :69:27: error: use of undefined value here causes illegal behavior482// :69:27: error: use of undefined value here causes illegal behavior
485// :69:27: note: when computing vector element at index '0'
486// :69:27: error: use of undefined value here causes illegal behavior483// :69:27: error: use of undefined value here causes illegal behavior
487// :69:27: note: when computing vector element at index '0'
488// :69:27: error: use of undefined value here causes illegal behavior484// :69:27: error: use of undefined value here causes illegal behavior
489// :69:27: note: when computing vector element at index '1'
490// :69:27: error: use of undefined value here causes illegal behavior485// :69:27: error: use of undefined value here causes illegal behavior
491// :69:27: note: when computing vector element at index '1'
492// :69:27: error: use of undefined value here causes illegal behavior486// :69:27: error: use of undefined value here causes illegal behavior
493// :69:27: note: when computing vector element at index '0'
494// :69:27: error: use of undefined value here causes illegal behavior487// :69:27: error: use of undefined value here causes illegal behavior
495// :69:27: note: when computing vector element at index '0'
496// :69:27: error: use of undefined value here causes illegal behavior488// :69:27: error: use of undefined value here causes illegal behavior
497// :69:27: note: when computing vector element at index '0'
498// :69:27: error: use of undefined value here causes illegal behavior489// :69:27: error: use of undefined value here causes illegal behavior
499// :69:27: note: when computing vector element at index '0'
500// :69:27: error: use of undefined value here causes illegal behavior490// :69:27: error: use of undefined value here causes illegal behavior
501// :69:27: error: use of undefined value here causes illegal behavior491// :69:27: error: use of undefined value here causes illegal behavior
502// :69:27: error: use of undefined value here causes illegal behavior492// :69:27: error: use of undefined value here causes illegal behavior
503// :69:27: note: when computing vector element at index '0'
504// :69:27: error: use of undefined value here causes illegal behavior493// :69:27: error: use of undefined value here causes illegal behavior
505// :69:27: note: when computing vector element at index '0'
506// :69:27: error: use of undefined value here causes illegal behavior494// :69:27: error: use of undefined value here causes illegal behavior
507// :69:27: note: when computing vector element at index '0'
508// :69:27: error: use of undefined value here causes illegal behavior495// :69:27: error: use of undefined value here causes illegal behavior
509// :69:27: note: when computing vector element at index '0'
510// :69:27: error: use of undefined value here causes illegal behavior496// :69:27: error: use of undefined value here causes illegal behavior
511// :69:27: note: when computing vector element at index '1'
512// :69:27: error: use of undefined value here causes illegal behavior497// :69:27: error: use of undefined value here causes illegal behavior
513// :69:27: note: when computing vector element at index '1'
514// :69:27: error: use of undefined value here causes illegal behavior498// :69:27: error: use of undefined value here causes illegal behavior
515// :69:27: note: when computing vector element at index '0'
516// :69:27: error: use of undefined value here causes illegal behavior499// :69:27: error: use of undefined value here causes illegal behavior
517// :69:27: note: when computing vector element at index '0'
518// :69:27: error: use of undefined value here causes illegal behavior500// :69:27: error: use of undefined value here causes illegal behavior
519// :69:27: note: when computing vector element at index '0'501// :69:27: note: when computing vector element at index '0'
520// :69:27: error: use of undefined value here causes illegal behavior502// :69:27: error: use of undefined value here causes illegal behavior
521// :69:27: note: when computing vector element at index '0'503// :69:27: note: when computing vector element at index '0'
522// :69:27: error: use of undefined value here causes illegal behavior504// :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
525// :69:27: note: when computing vector element at index '0'505// :69:27: note: when computing vector element at index '0'
526// :69:27: error: use of undefined value here causes illegal behavior506// :69:27: error: use of undefined value here causes illegal behavior
527// :69:27: note: when computing vector element at index '0'507// :69:27: note: when computing vector element at index '0'
...@@ -530,10 +510,6 @@ const std = @import("std");...@@ -530,10 +510,6 @@ const std = @import("std");
530// :69:27: error: use of undefined value here causes illegal behavior510// :69:27: error: use of undefined value here causes illegal behavior
531// :69:27: note: when computing vector element at index '0'511// :69:27: note: when computing vector element at index '0'
532// :69:27: error: use of undefined value here causes illegal behavior512// :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
537// :69:27: note: when computing vector element at index '0'513// :69:27: note: when computing vector element at index '0'
538// :69:27: error: use of undefined value here causes illegal behavior514// :69:27: error: use of undefined value here causes illegal behavior
539// :69:27: note: when computing vector element at index '0'515// :69:27: note: when computing vector element at index '0'
...@@ -542,7 +518,9 @@ const std = @import("std");...@@ -542,7 +518,9 @@ const std = @import("std");
542// :69:27: error: use of undefined value here causes illegal behavior518// :69:27: error: use of undefined value here causes illegal behavior
543// :69:27: note: when computing vector element at index '0'519// :69:27: note: when computing vector element at index '0'
544// :69:27: error: use of undefined value here causes illegal behavior520// :69:27: error: use of undefined value here causes illegal behavior
521// :69:27: note: when computing vector element at index '0'
545// :69:27: error: use of undefined value here causes illegal behavior522// :69:27: error: use of undefined value here causes illegal behavior
523// :69:27: note: when computing vector element at index '0'
546// :69:27: error: use of undefined value here causes illegal behavior524// :69:27: error: use of undefined value here causes illegal behavior
547// :69:27: note: when computing vector element at index '0'525// :69:27: note: when computing vector element at index '0'
548// :69:27: error: use of undefined value here causes illegal behavior526// :69:27: error: use of undefined value here causes illegal behavior
...@@ -552,9 +530,9 @@ const std = @import("std");...@@ -552,9 +530,9 @@ const std = @import("std");
552// :69:27: error: use of undefined value here causes illegal behavior530// :69:27: error: use of undefined value here causes illegal behavior
553// :69:27: note: when computing vector element at index '0'531// :69:27: note: when computing vector element at index '0'
554// :69:27: error: use of undefined value here causes illegal behavior532// :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'
556// :69:27: error: use of undefined value here causes illegal behavior534// :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'
558// :69:27: error: use of undefined value here causes illegal behavior536// :69:27: error: use of undefined value here causes illegal behavior
559// :69:27: note: when computing vector element at index '0'537// :69:27: note: when computing vector element at index '0'
560// :69:27: error: use of undefined value here causes illegal behavior538// :69:27: error: use of undefined value here causes illegal behavior
...@@ -564,7 +542,9 @@ const std = @import("std");...@@ -564,7 +542,9 @@ const std = @import("std");
564// :69:27: error: use of undefined value here causes illegal behavior542// :69:27: error: use of undefined value here causes illegal behavior
565// :69:27: note: when computing vector element at index '0'543// :69:27: note: when computing vector element at index '0'
566// :69:27: error: use of undefined value here causes illegal behavior544// :69:27: error: use of undefined value here causes illegal behavior
545// :69:27: note: when computing vector element at index '0'
567// :69:27: error: use of undefined value here causes illegal behavior546// :69:27: error: use of undefined value here causes illegal behavior
547// :69:27: note: when computing vector element at index '0'
568// :69:27: error: use of undefined value here causes illegal behavior548// :69:27: error: use of undefined value here causes illegal behavior
569// :69:27: note: when computing vector element at index '0'549// :69:27: note: when computing vector element at index '0'
570// :69:27: error: use of undefined value here causes illegal behavior550// :69:27: error: use of undefined value here causes illegal behavior
...@@ -574,9 +554,9 @@ const std = @import("std");...@@ -574,9 +554,9 @@ const std = @import("std");
574// :69:27: error: use of undefined value here causes illegal behavior554// :69:27: error: use of undefined value here causes illegal behavior
575// :69:27: note: when computing vector element at index '0'555// :69:27: note: when computing vector element at index '0'
576// :69:27: error: use of undefined value here causes illegal behavior556// :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'
578// :69:27: error: use of undefined value here causes illegal behavior558// :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'
580// :69:27: error: use of undefined value here causes illegal behavior560// :69:27: error: use of undefined value here causes illegal behavior
581// :69:27: note: when computing vector element at index '0'561// :69:27: note: when computing vector element at index '0'
582// :69:27: error: use of undefined value here causes illegal behavior562// :69:27: error: use of undefined value here causes illegal behavior
...@@ -586,7 +566,9 @@ const std = @import("std");...@@ -586,7 +566,9 @@ const std = @import("std");
586// :69:27: error: use of undefined value here causes illegal behavior566// :69:27: error: use of undefined value here causes illegal behavior
587// :69:27: note: when computing vector element at index '0'567// :69:27: note: when computing vector element at index '0'
588// :69:27: error: use of undefined value here causes illegal behavior568// :69:27: error: use of undefined value here causes illegal behavior
569// :69:27: note: when computing vector element at index '0'
589// :69:27: error: use of undefined value here causes illegal behavior570// :69:27: error: use of undefined value here causes illegal behavior
571// :69:27: note: when computing vector element at index '0'
590// :69:27: error: use of undefined value here causes illegal behavior572// :69:27: error: use of undefined value here causes illegal behavior
591// :69:27: note: when computing vector element at index '0'573// :69:27: note: when computing vector element at index '0'
592// :69:27: error: use of undefined value here causes illegal behavior574// :69:27: error: use of undefined value here causes illegal behavior
...@@ -596,9 +578,9 @@ const std = @import("std");...@@ -596,9 +578,9 @@ const std = @import("std");
596// :69:27: error: use of undefined value here causes illegal behavior578// :69:27: error: use of undefined value here causes illegal behavior
597// :69:27: note: when computing vector element at index '0'579// :69:27: note: when computing vector element at index '0'
598// :69:27: error: use of undefined value here causes illegal behavior580// :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'
600// :69:27: error: use of undefined value here causes illegal behavior582// :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'
602// :69:27: error: use of undefined value here causes illegal behavior584// :69:27: error: use of undefined value here causes illegal behavior
603// :69:27: note: when computing vector element at index '0'585// :69:27: note: when computing vector element at index '0'
604// :69:27: error: use of undefined value here causes illegal behavior586// :69:27: error: use of undefined value here causes illegal behavior
...@@ -608,7 +590,9 @@ const std = @import("std");...@@ -608,7 +590,9 @@ const std = @import("std");
608// :69:27: error: use of undefined value here causes illegal behavior590// :69:27: error: use of undefined value here causes illegal behavior
609// :69:27: note: when computing vector element at index '0'591// :69:27: note: when computing vector element at index '0'
610// :69:27: error: use of undefined value here causes illegal behavior592// :69:27: error: use of undefined value here causes illegal behavior
593// :69:27: note: when computing vector element at index '0'
611// :69:27: error: use of undefined value here causes illegal behavior594// :69:27: error: use of undefined value here causes illegal behavior
595// :69:27: note: when computing vector element at index '0'
612// :69:27: error: use of undefined value here causes illegal behavior596// :69:27: error: use of undefined value here causes illegal behavior
613// :69:27: note: when computing vector element at index '0'597// :69:27: note: when computing vector element at index '0'
614// :69:27: error: use of undefined value here causes illegal behavior598// :69:27: error: use of undefined value here causes illegal behavior
...@@ -618,9 +602,9 @@ const std = @import("std");...@@ -618,9 +602,9 @@ const std = @import("std");
618// :69:27: error: use of undefined value here causes illegal behavior602// :69:27: error: use of undefined value here causes illegal behavior
619// :69:27: note: when computing vector element at index '0'603// :69:27: note: when computing vector element at index '0'
620// :69:27: error: use of undefined value here causes illegal behavior604// :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'
622// :69:27: error: use of undefined value here causes illegal behavior606// :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'
624// :69:27: error: use of undefined value here causes illegal behavior608// :69:27: error: use of undefined value here causes illegal behavior
625// :69:27: note: when computing vector element at index '0'609// :69:27: note: when computing vector element at index '0'
626// :69:27: error: use of undefined value here causes illegal behavior610// :69:27: error: use of undefined value here causes illegal behavior
...@@ -630,7 +614,9 @@ const std = @import("std");...@@ -630,7 +614,9 @@ const std = @import("std");
630// :69:27: error: use of undefined value here causes illegal behavior614// :69:27: error: use of undefined value here causes illegal behavior
631// :69:27: note: when computing vector element at index '0'615// :69:27: note: when computing vector element at index '0'
632// :69:27: error: use of undefined value here causes illegal behavior616// :69:27: error: use of undefined value here causes illegal behavior
617// :69:27: note: when computing vector element at index '0'
633// :69:27: error: use of undefined value here causes illegal behavior618// :69:27: error: use of undefined value here causes illegal behavior
619// :69:27: note: when computing vector element at index '0'
634// :69:27: error: use of undefined value here causes illegal behavior620// :69:27: error: use of undefined value here causes illegal behavior
635// :69:27: note: when computing vector element at index '0'621// :69:27: note: when computing vector element at index '0'
636// :69:27: error: use of undefined value here causes illegal behavior622// :69:27: error: use of undefined value here causes illegal behavior
...@@ -640,9 +626,9 @@ const std = @import("std");...@@ -640,9 +626,9 @@ const std = @import("std");
640// :69:27: error: use of undefined value here causes illegal behavior626// :69:27: error: use of undefined value here causes illegal behavior
641// :69:27: note: when computing vector element at index '0'627// :69:27: note: when computing vector element at index '0'
642// :69:27: error: use of undefined value here causes illegal behavior628// :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'
644// :69:27: error: use of undefined value here causes illegal behavior630// :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'
646// :69:27: error: use of undefined value here causes illegal behavior632// :69:27: error: use of undefined value here causes illegal behavior
647// :69:27: note: when computing vector element at index '0'633// :69:27: note: when computing vector element at index '0'
648// :69:27: error: use of undefined value here causes illegal behavior634// :69:27: error: use of undefined value here causes illegal behavior
...@@ -652,7 +638,9 @@ const std = @import("std");...@@ -652,7 +638,9 @@ const std = @import("std");
652// :69:27: error: use of undefined value here causes illegal behavior638// :69:27: error: use of undefined value here causes illegal behavior
653// :69:27: note: when computing vector element at index '0'639// :69:27: note: when computing vector element at index '0'
654// :69:27: error: use of undefined value here causes illegal behavior640// :69:27: error: use of undefined value here causes illegal behavior
641// :69:27: note: when computing vector element at index '0'
655// :69:27: error: use of undefined value here causes illegal behavior642// :69:27: error: use of undefined value here causes illegal behavior
643// :69:27: note: when computing vector element at index '0'
656// :69:27: error: use of undefined value here causes illegal behavior644// :69:27: error: use of undefined value here causes illegal behavior
657// :69:27: note: when computing vector element at index '0'645// :69:27: note: when computing vector element at index '0'
658// :69:27: error: use of undefined value here causes illegal behavior646// :69:27: error: use of undefined value here causes illegal behavior
...@@ -662,9 +650,9 @@ const std = @import("std");...@@ -662,9 +650,9 @@ const std = @import("std");
662// :69:27: error: use of undefined value here causes illegal behavior650// :69:27: error: use of undefined value here causes illegal behavior
663// :69:27: note: when computing vector element at index '0'651// :69:27: note: when computing vector element at index '0'
664// :69:27: error: use of undefined value here causes illegal behavior652// :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'
666// :69:27: error: use of undefined value here causes illegal behavior654// :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'
668// :69:27: error: use of undefined value here causes illegal behavior656// :69:27: error: use of undefined value here causes illegal behavior
669// :69:27: note: when computing vector element at index '0'657// :69:27: note: when computing vector element at index '0'
670// :69:27: error: use of undefined value here causes illegal behavior658// :69:27: error: use of undefined value here causes illegal behavior
...@@ -674,7 +662,9 @@ const std = @import("std");...@@ -674,7 +662,9 @@ const std = @import("std");
674// :69:27: error: use of undefined value here causes illegal behavior662// :69:27: error: use of undefined value here causes illegal behavior
675// :69:27: note: when computing vector element at index '0'663// :69:27: note: when computing vector element at index '0'
676// :69:27: error: use of undefined value here causes illegal behavior664// :69:27: error: use of undefined value here causes illegal behavior
665// :69:27: note: when computing vector element at index '0'
677// :69:27: error: use of undefined value here causes illegal behavior666// :69:27: error: use of undefined value here causes illegal behavior
667// :69:27: note: when computing vector element at index '0'
678// :69:27: error: use of undefined value here causes illegal behavior668// :69:27: error: use of undefined value here causes illegal behavior
679// :69:27: note: when computing vector element at index '0'669// :69:27: note: when computing vector element at index '0'
680// :69:27: error: use of undefined value here causes illegal behavior670// :69:27: error: use of undefined value here causes illegal behavior
...@@ -688,35 +678,45 @@ const std = @import("std");...@@ -688,35 +678,45 @@ const std = @import("std");
688// :69:27: error: use of undefined value here causes illegal behavior678// :69:27: error: use of undefined value here causes illegal behavior
689// :69:27: note: when computing vector element at index '1'679// :69:27: note: when computing vector element at index '1'
690// :69:27: error: use of undefined value here causes illegal behavior680// :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'
692// :69:27: error: use of undefined value here causes illegal behavior682// :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'
694// :69:27: error: use of undefined value here causes illegal behavior684// :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'
696// :69:27: error: use of undefined value here causes illegal behavior686// :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'
698// :69:27: error: use of undefined value here causes illegal behavior688// :69:27: error: use of undefined value here causes illegal behavior
689// :69:27: note: when computing vector element at index '1'
699// :69:27: error: use of undefined value here causes illegal behavior690// :69:27: error: use of undefined value here causes illegal behavior
691// :69:27: note: when computing vector element at index '1'
700// :69:27: error: use of undefined value here causes illegal behavior692// :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'
702// :69:27: error: use of undefined value here causes illegal behavior694// :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'
704// :69:27: error: use of undefined value here causes illegal behavior696// :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'
706// :69:27: error: use of undefined value here causes illegal behavior698// :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'
708// :69:27: error: use of undefined value here causes illegal behavior700// :69:27: error: use of undefined value here causes illegal behavior
709// :69:27: note: when computing vector element at index '1'701// :69:27: note: when computing vector element at index '1'
710// :69:27: error: use of undefined value here causes illegal behavior702// :69:27: error: use of undefined value here causes illegal behavior
711// :69:27: note: when computing vector element at index '1'703// :69:27: note: when computing vector element at index '1'
712// :69:27: error: use of undefined value here causes illegal behavior704// :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'
714// :69:27: error: use of undefined value here causes illegal behavior706// :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'
716// :69:27: error: use of undefined value here causes illegal behavior708// :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'
718// :69:27: error: use of undefined value here causes illegal behavior710// :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'
720// :69:30: error: use of undefined value here causes illegal behavior720// :69:30: error: use of undefined value here causes illegal behavior
721// :69:30: note: when computing vector element at index '0'721// :69:30: note: when computing vector element at index '0'
722// :69:30: error: use of undefined value here causes illegal behavior722// :69:30: error: use of undefined value here causes illegal behavior
...@@ -764,50 +764,30 @@ const std = @import("std");...@@ -764,50 +764,30 @@ const std = @import("std");
764// :73:27: error: use of undefined value here causes illegal behavior764// :73:27: error: use of undefined value here causes illegal behavior
765// :73:27: error: use of undefined value here causes illegal behavior765// :73:27: error: use of undefined value here causes illegal behavior
766// :73:27: error: use of undefined value here causes illegal behavior766// :73:27: error: use of undefined value here causes illegal behavior
767// :73:27: note: when computing vector element at index '0'
768// :73:27: error: use of undefined value here causes illegal behavior767// :73:27: error: use of undefined value here causes illegal behavior
769// :73:27: note: when computing vector element at index '0'
770// :73:27: error: use of undefined value here causes illegal behavior768// :73:27: error: use of undefined value here causes illegal behavior
771// :73:27: note: when computing vector element at index '0'
772// :73:27: error: use of undefined value here causes illegal behavior769// :73:27: error: use of undefined value here causes illegal behavior
773// :73:27: note: when computing vector element at index '0'
774// :73:27: error: use of undefined value here causes illegal behavior770// :73:27: error: use of undefined value here causes illegal behavior
775// :73:27: note: when computing vector element at index '1'
776// :73:27: error: use of undefined value here causes illegal behavior771// :73:27: error: use of undefined value here causes illegal behavior
777// :73:27: note: when computing vector element at index '1'
778// :73:27: error: use of undefined value here causes illegal behavior772// :73:27: error: use of undefined value here causes illegal behavior
779// :73:27: note: when computing vector element at index '0'
780// :73:27: error: use of undefined value here causes illegal behavior773// :73:27: error: use of undefined value here causes illegal behavior
781// :73:27: note: when computing vector element at index '0'
782// :73:27: error: use of undefined value here causes illegal behavior774// :73:27: error: use of undefined value here causes illegal behavior
783// :73:27: note: when computing vector element at index '0'
784// :73:27: error: use of undefined value here causes illegal behavior775// :73:27: error: use of undefined value here causes illegal behavior
785// :73:27: note: when computing vector element at index '0'
786// :73:27: error: use of undefined value here causes illegal behavior776// :73:27: error: use of undefined value here causes illegal behavior
787// :73:27: error: use of undefined value here causes illegal behavior777// :73:27: error: use of undefined value here causes illegal behavior
788// :73:27: error: use of undefined value here causes illegal behavior778// :73:27: error: use of undefined value here causes illegal behavior
789// :73:27: note: when computing vector element at index '0'
790// :73:27: error: use of undefined value here causes illegal behavior779// :73:27: error: use of undefined value here causes illegal behavior
791// :73:27: note: when computing vector element at index '0'
792// :73:27: error: use of undefined value here causes illegal behavior780// :73:27: error: use of undefined value here causes illegal behavior
793// :73:27: note: when computing vector element at index '0'
794// :73:27: error: use of undefined value here causes illegal behavior781// :73:27: error: use of undefined value here causes illegal behavior
795// :73:27: note: when computing vector element at index '0'
796// :73:27: error: use of undefined value here causes illegal behavior782// :73:27: error: use of undefined value here causes illegal behavior
797// :73:27: note: when computing vector element at index '1'
798// :73:27: error: use of undefined value here causes illegal behavior783// :73:27: error: use of undefined value here causes illegal behavior
799// :73:27: note: when computing vector element at index '1'
800// :73:27: error: use of undefined value here causes illegal behavior784// :73:27: error: use of undefined value here causes illegal behavior
801// :73:27: note: when computing vector element at index '0'
802// :73:27: error: use of undefined value here causes illegal behavior785// :73:27: error: use of undefined value here causes illegal behavior
803// :73:27: note: when computing vector element at index '0'
804// :73:27: error: use of undefined value here causes illegal behavior786// :73:27: error: use of undefined value here causes illegal behavior
805// :73:27: note: when computing vector element at index '0'787// :73:27: note: when computing vector element at index '0'
806// :73:27: error: use of undefined value here causes illegal behavior788// :73:27: error: use of undefined value here causes illegal behavior
807// :73:27: note: when computing vector element at index '0'789// :73:27: note: when computing vector element at index '0'
808// :73:27: error: use of undefined value here causes illegal behavior790// :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
811// :73:27: note: when computing vector element at index '0'791// :73:27: note: when computing vector element at index '0'
812// :73:27: error: use of undefined value here causes illegal behavior792// :73:27: error: use of undefined value here causes illegal behavior
813// :73:27: note: when computing vector element at index '0'793// :73:27: note: when computing vector element at index '0'
...@@ -816,10 +796,6 @@ const std = @import("std");...@@ -816,10 +796,6 @@ const std = @import("std");
816// :73:27: error: use of undefined value here causes illegal behavior796// :73:27: error: use of undefined value here causes illegal behavior
817// :73:27: note: when computing vector element at index '0'797// :73:27: note: when computing vector element at index '0'
818// :73:27: error: use of undefined value here causes illegal behavior798// :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
823// :73:27: note: when computing vector element at index '0'799// :73:27: note: when computing vector element at index '0'
824// :73:27: error: use of undefined value here causes illegal behavior800// :73:27: error: use of undefined value here causes illegal behavior
825// :73:27: note: when computing vector element at index '0'801// :73:27: note: when computing vector element at index '0'
...@@ -828,7 +804,9 @@ const std = @import("std");...@@ -828,7 +804,9 @@ const std = @import("std");
828// :73:27: error: use of undefined value here causes illegal behavior804// :73:27: error: use of undefined value here causes illegal behavior
829// :73:27: note: when computing vector element at index '0'805// :73:27: note: when computing vector element at index '0'
830// :73:27: error: use of undefined value here causes illegal behavior806// :73:27: error: use of undefined value here causes illegal behavior
807// :73:27: note: when computing vector element at index '0'
831// :73:27: error: use of undefined value here causes illegal behavior808// :73:27: error: use of undefined value here causes illegal behavior
809// :73:27: note: when computing vector element at index '0'
832// :73:27: error: use of undefined value here causes illegal behavior810// :73:27: error: use of undefined value here causes illegal behavior
833// :73:27: note: when computing vector element at index '0'811// :73:27: note: when computing vector element at index '0'
834// :73:27: error: use of undefined value here causes illegal behavior812// :73:27: error: use of undefined value here causes illegal behavior
...@@ -838,9 +816,9 @@ const std = @import("std");...@@ -838,9 +816,9 @@ const std = @import("std");
838// :73:27: error: use of undefined value here causes illegal behavior816// :73:27: error: use of undefined value here causes illegal behavior
839// :73:27: note: when computing vector element at index '0'817// :73:27: note: when computing vector element at index '0'
840// :73:27: error: use of undefined value here causes illegal behavior818// :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'
842// :73:27: error: use of undefined value here causes illegal behavior820// :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'
844// :73:27: error: use of undefined value here causes illegal behavior822// :73:27: error: use of undefined value here causes illegal behavior
845// :73:27: note: when computing vector element at index '0'823// :73:27: note: when computing vector element at index '0'
846// :73:27: error: use of undefined value here causes illegal behavior824// :73:27: error: use of undefined value here causes illegal behavior
...@@ -850,7 +828,9 @@ const std = @import("std");...@@ -850,7 +828,9 @@ const std = @import("std");
850// :73:27: error: use of undefined value here causes illegal behavior828// :73:27: error: use of undefined value here causes illegal behavior
851// :73:27: note: when computing vector element at index '0'829// :73:27: note: when computing vector element at index '0'
852// :73:27: error: use of undefined value here causes illegal behavior830// :73:27: error: use of undefined value here causes illegal behavior
831// :73:27: note: when computing vector element at index '0'
853// :73:27: error: use of undefined value here causes illegal behavior832// :73:27: error: use of undefined value here causes illegal behavior
833// :73:27: note: when computing vector element at index '0'
854// :73:27: error: use of undefined value here causes illegal behavior834// :73:27: error: use of undefined value here causes illegal behavior
855// :73:27: note: when computing vector element at index '0'835// :73:27: note: when computing vector element at index '0'
856// :73:27: error: use of undefined value here causes illegal behavior836// :73:27: error: use of undefined value here causes illegal behavior
...@@ -860,9 +840,9 @@ const std = @import("std");...@@ -860,9 +840,9 @@ const std = @import("std");
860// :73:27: error: use of undefined value here causes illegal behavior840// :73:27: error: use of undefined value here causes illegal behavior
861// :73:27: note: when computing vector element at index '0'841// :73:27: note: when computing vector element at index '0'
862// :73:27: error: use of undefined value here causes illegal behavior842// :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'
864// :73:27: error: use of undefined value here causes illegal behavior844// :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'
866// :73:27: error: use of undefined value here causes illegal behavior846// :73:27: error: use of undefined value here causes illegal behavior
867// :73:27: note: when computing vector element at index '0'847// :73:27: note: when computing vector element at index '0'
868// :73:27: error: use of undefined value here causes illegal behavior848// :73:27: error: use of undefined value here causes illegal behavior
...@@ -872,7 +852,9 @@ const std = @import("std");...@@ -872,7 +852,9 @@ const std = @import("std");
872// :73:27: error: use of undefined value here causes illegal behavior852// :73:27: error: use of undefined value here causes illegal behavior
873// :73:27: note: when computing vector element at index '0'853// :73:27: note: when computing vector element at index '0'
874// :73:27: error: use of undefined value here causes illegal behavior854// :73:27: error: use of undefined value here causes illegal behavior
855// :73:27: note: when computing vector element at index '0'
875// :73:27: error: use of undefined value here causes illegal behavior856// :73:27: error: use of undefined value here causes illegal behavior
857// :73:27: note: when computing vector element at index '0'
876// :73:27: error: use of undefined value here causes illegal behavior858// :73:27: error: use of undefined value here causes illegal behavior
877// :73:27: note: when computing vector element at index '0'859// :73:27: note: when computing vector element at index '0'
878// :73:27: error: use of undefined value here causes illegal behavior860// :73:27: error: use of undefined value here causes illegal behavior
...@@ -882,9 +864,9 @@ const std = @import("std");...@@ -882,9 +864,9 @@ const std = @import("std");
882// :73:27: error: use of undefined value here causes illegal behavior864// :73:27: error: use of undefined value here causes illegal behavior
883// :73:27: note: when computing vector element at index '0'865// :73:27: note: when computing vector element at index '0'
884// :73:27: error: use of undefined value here causes illegal behavior866// :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'
886// :73:27: error: use of undefined value here causes illegal behavior868// :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'
888// :73:27: error: use of undefined value here causes illegal behavior870// :73:27: error: use of undefined value here causes illegal behavior
889// :73:27: note: when computing vector element at index '0'871// :73:27: note: when computing vector element at index '0'
890// :73:27: error: use of undefined value here causes illegal behavior872// :73:27: error: use of undefined value here causes illegal behavior
...@@ -894,7 +876,9 @@ const std = @import("std");...@@ -894,7 +876,9 @@ const std = @import("std");
894// :73:27: error: use of undefined value here causes illegal behavior876// :73:27: error: use of undefined value here causes illegal behavior
895// :73:27: note: when computing vector element at index '0'877// :73:27: note: when computing vector element at index '0'
896// :73:27: error: use of undefined value here causes illegal behavior878// :73:27: error: use of undefined value here causes illegal behavior
879// :73:27: note: when computing vector element at index '0'
897// :73:27: error: use of undefined value here causes illegal behavior880// :73:27: error: use of undefined value here causes illegal behavior
881// :73:27: note: when computing vector element at index '0'
898// :73:27: error: use of undefined value here causes illegal behavior882// :73:27: error: use of undefined value here causes illegal behavior
899// :73:27: note: when computing vector element at index '0'883// :73:27: note: when computing vector element at index '0'
900// :73:27: error: use of undefined value here causes illegal behavior884// :73:27: error: use of undefined value here causes illegal behavior
...@@ -904,9 +888,9 @@ const std = @import("std");...@@ -904,9 +888,9 @@ const std = @import("std");
904// :73:27: error: use of undefined value here causes illegal behavior888// :73:27: error: use of undefined value here causes illegal behavior
905// :73:27: note: when computing vector element at index '0'889// :73:27: note: when computing vector element at index '0'
906// :73:27: error: use of undefined value here causes illegal behavior890// :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'
908// :73:27: error: use of undefined value here causes illegal behavior892// :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'
910// :73:27: error: use of undefined value here causes illegal behavior894// :73:27: error: use of undefined value here causes illegal behavior
911// :73:27: note: when computing vector element at index '0'895// :73:27: note: when computing vector element at index '0'
912// :73:27: error: use of undefined value here causes illegal behavior896// :73:27: error: use of undefined value here causes illegal behavior
...@@ -916,7 +900,9 @@ const std = @import("std");...@@ -916,7 +900,9 @@ const std = @import("std");
916// :73:27: error: use of undefined value here causes illegal behavior900// :73:27: error: use of undefined value here causes illegal behavior
917// :73:27: note: when computing vector element at index '0'901// :73:27: note: when computing vector element at index '0'
918// :73:27: error: use of undefined value here causes illegal behavior902// :73:27: error: use of undefined value here causes illegal behavior
903// :73:27: note: when computing vector element at index '0'
919// :73:27: error: use of undefined value here causes illegal behavior904// :73:27: error: use of undefined value here causes illegal behavior
905// :73:27: note: when computing vector element at index '0'
920// :73:27: error: use of undefined value here causes illegal behavior906// :73:27: error: use of undefined value here causes illegal behavior
921// :73:27: note: when computing vector element at index '0'907// :73:27: note: when computing vector element at index '0'
922// :73:27: error: use of undefined value here causes illegal behavior908// :73:27: error: use of undefined value here causes illegal behavior
...@@ -926,9 +912,9 @@ const std = @import("std");...@@ -926,9 +912,9 @@ const std = @import("std");
926// :73:27: error: use of undefined value here causes illegal behavior912// :73:27: error: use of undefined value here causes illegal behavior
927// :73:27: note: when computing vector element at index '0'913// :73:27: note: when computing vector element at index '0'
928// :73:27: error: use of undefined value here causes illegal behavior914// :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'
930// :73:27: error: use of undefined value here causes illegal behavior916// :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'
932// :73:27: error: use of undefined value here causes illegal behavior918// :73:27: error: use of undefined value here causes illegal behavior
933// :73:27: note: when computing vector element at index '0'919// :73:27: note: when computing vector element at index '0'
934// :73:27: error: use of undefined value here causes illegal behavior920// :73:27: error: use of undefined value here causes illegal behavior
...@@ -938,7 +924,9 @@ const std = @import("std");...@@ -938,7 +924,9 @@ const std = @import("std");
938// :73:27: error: use of undefined value here causes illegal behavior924// :73:27: error: use of undefined value here causes illegal behavior
939// :73:27: note: when computing vector element at index '0'925// :73:27: note: when computing vector element at index '0'
940// :73:27: error: use of undefined value here causes illegal behavior926// :73:27: error: use of undefined value here causes illegal behavior
927// :73:27: note: when computing vector element at index '0'
941// :73:27: error: use of undefined value here causes illegal behavior928// :73:27: error: use of undefined value here causes illegal behavior
929// :73:27: note: when computing vector element at index '0'
942// :73:27: error: use of undefined value here causes illegal behavior930// :73:27: error: use of undefined value here causes illegal behavior
943// :73:27: note: when computing vector element at index '0'931// :73:27: note: when computing vector element at index '0'
944// :73:27: error: use of undefined value here causes illegal behavior932// :73:27: error: use of undefined value here causes illegal behavior
...@@ -948,9 +936,9 @@ const std = @import("std");...@@ -948,9 +936,9 @@ const std = @import("std");
948// :73:27: error: use of undefined value here causes illegal behavior936// :73:27: error: use of undefined value here causes illegal behavior
949// :73:27: note: when computing vector element at index '0'937// :73:27: note: when computing vector element at index '0'
950// :73:27: error: use of undefined value here causes illegal behavior938// :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'
952// :73:27: error: use of undefined value here causes illegal behavior940// :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'
954// :73:27: error: use of undefined value here causes illegal behavior942// :73:27: error: use of undefined value here causes illegal behavior
955// :73:27: note: when computing vector element at index '0'943// :73:27: note: when computing vector element at index '0'
956// :73:27: error: use of undefined value here causes illegal behavior944// :73:27: error: use of undefined value here causes illegal behavior
...@@ -960,7 +948,9 @@ const std = @import("std");...@@ -960,7 +948,9 @@ const std = @import("std");
960// :73:27: error: use of undefined value here causes illegal behavior948// :73:27: error: use of undefined value here causes illegal behavior
961// :73:27: note: when computing vector element at index '0'949// :73:27: note: when computing vector element at index '0'
962// :73:27: error: use of undefined value here causes illegal behavior950// :73:27: error: use of undefined value here causes illegal behavior
951// :73:27: note: when computing vector element at index '0'
963// :73:27: error: use of undefined value here causes illegal behavior952// :73:27: error: use of undefined value here causes illegal behavior
953// :73:27: note: when computing vector element at index '0'
964// :73:27: error: use of undefined value here causes illegal behavior954// :73:27: error: use of undefined value here causes illegal behavior
965// :73:27: note: when computing vector element at index '0'955// :73:27: note: when computing vector element at index '0'
966// :73:27: error: use of undefined value here causes illegal behavior956// :73:27: error: use of undefined value here causes illegal behavior
...@@ -974,35 +964,45 @@ const std = @import("std");...@@ -974,35 +964,45 @@ const std = @import("std");
974// :73:27: error: use of undefined value here causes illegal behavior964// :73:27: error: use of undefined value here causes illegal behavior
975// :73:27: note: when computing vector element at index '1'965// :73:27: note: when computing vector element at index '1'
976// :73:27: error: use of undefined value here causes illegal behavior966// :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'
978// :73:27: error: use of undefined value here causes illegal behavior968// :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'
980// :73:27: error: use of undefined value here causes illegal behavior970// :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'
982// :73:27: error: use of undefined value here causes illegal behavior972// :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'
984// :73:27: error: use of undefined value here causes illegal behavior974// :73:27: error: use of undefined value here causes illegal behavior
975// :73:27: note: when computing vector element at index '1'
985// :73:27: error: use of undefined value here causes illegal behavior976// :73:27: error: use of undefined value here causes illegal behavior
977// :73:27: note: when computing vector element at index '1'
986// :73:27: error: use of undefined value here causes illegal behavior978// :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'
988// :73:27: error: use of undefined value here causes illegal behavior980// :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'
990// :73:27: error: use of undefined value here causes illegal behavior982// :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'
992// :73:27: error: use of undefined value here causes illegal behavior984// :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'
994// :73:27: error: use of undefined value here causes illegal behavior986// :73:27: error: use of undefined value here causes illegal behavior
995// :73:27: note: when computing vector element at index '1'987// :73:27: note: when computing vector element at index '1'
996// :73:27: error: use of undefined value here causes illegal behavior988// :73:27: error: use of undefined value here causes illegal behavior
997// :73:27: note: when computing vector element at index '1'989// :73:27: note: when computing vector element at index '1'
998// :73:27: error: use of undefined value here causes illegal behavior990// :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'
1000// :73:27: error: use of undefined value here causes illegal behavior992// :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'
1002// :73:27: error: use of undefined value here causes illegal behavior994// :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'
1004// :73:27: error: use of undefined value here causes illegal behavior996// :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'
1006// :73:30: error: use of undefined value here causes illegal behavior1006// :73:30: error: use of undefined value here causes illegal behavior
1007// :73:30: note: when computing vector element at index '0'1007// :73:30: note: when computing vector element at index '0'
1008// :73:30: error: use of undefined value here causes illegal behavior1008// :73:30: error: use of undefined value here causes illegal behavior
...@@ -1050,50 +1050,30 @@ const std = @import("std");...@@ -1050,50 +1050,30 @@ const std = @import("std");
1050// :77:27: error: use of undefined value here causes illegal behavior1050// :77:27: error: use of undefined value here causes illegal behavior
1051// :77:27: error: use of undefined value here causes illegal behavior1051// :77:27: error: use of undefined value here causes illegal behavior
1052// :77:27: error: use of undefined value here causes illegal behavior1052// :77:27: error: use of undefined value here causes illegal behavior
1053// :77:27: note: when computing vector element at index '0'
1054// :77:27: error: use of undefined value here causes illegal behavior1053// :77:27: error: use of undefined value here causes illegal behavior
1055// :77:27: note: when computing vector element at index '0'
1056// :77:27: error: use of undefined value here causes illegal behavior1054// :77:27: error: use of undefined value here causes illegal behavior
1057// :77:27: note: when computing vector element at index '0'
1058// :77:27: error: use of undefined value here causes illegal behavior1055// :77:27: error: use of undefined value here causes illegal behavior
1059// :77:27: note: when computing vector element at index '0'
1060// :77:27: error: use of undefined value here causes illegal behavior1056// :77:27: error: use of undefined value here causes illegal behavior
1061// :77:27: note: when computing vector element at index '1'
1062// :77:27: error: use of undefined value here causes illegal behavior1057// :77:27: error: use of undefined value here causes illegal behavior
1063// :77:27: note: when computing vector element at index '1'
1064// :77:27: error: use of undefined value here causes illegal behavior1058// :77:27: error: use of undefined value here causes illegal behavior
1065// :77:27: note: when computing vector element at index '0'
1066// :77:27: error: use of undefined value here causes illegal behavior1059// :77:27: error: use of undefined value here causes illegal behavior
1067// :77:27: note: when computing vector element at index '0'
1068// :77:27: error: use of undefined value here causes illegal behavior1060// :77:27: error: use of undefined value here causes illegal behavior
1069// :77:27: note: when computing vector element at index '0'
1070// :77:27: error: use of undefined value here causes illegal behavior1061// :77:27: error: use of undefined value here causes illegal behavior
1071// :77:27: note: when computing vector element at index '0'
1072// :77:27: error: use of undefined value here causes illegal behavior1062// :77:27: error: use of undefined value here causes illegal behavior
1073// :77:27: error: use of undefined value here causes illegal behavior1063// :77:27: error: use of undefined value here causes illegal behavior
1074// :77:27: error: use of undefined value here causes illegal behavior1064// :77:27: error: use of undefined value here causes illegal behavior
1075// :77:27: note: when computing vector element at index '0'
1076// :77:27: error: use of undefined value here causes illegal behavior1065// :77:27: error: use of undefined value here causes illegal behavior
1077// :77:27: note: when computing vector element at index '0'
1078// :77:27: error: use of undefined value here causes illegal behavior1066// :77:27: error: use of undefined value here causes illegal behavior
1079// :77:27: note: when computing vector element at index '0'
1080// :77:27: error: use of undefined value here causes illegal behavior1067// :77:27: error: use of undefined value here causes illegal behavior
1081// :77:27: note: when computing vector element at index '0'
1082// :77:27: error: use of undefined value here causes illegal behavior1068// :77:27: error: use of undefined value here causes illegal behavior
1083// :77:27: note: when computing vector element at index '1'
1084// :77:27: error: use of undefined value here causes illegal behavior1069// :77:27: error: use of undefined value here causes illegal behavior
1085// :77:27: note: when computing vector element at index '1'
1086// :77:27: error: use of undefined value here causes illegal behavior1070// :77:27: error: use of undefined value here causes illegal behavior
1087// :77:27: note: when computing vector element at index '0'
1088// :77:27: error: use of undefined value here causes illegal behavior1071// :77:27: error: use of undefined value here causes illegal behavior
1089// :77:27: note: when computing vector element at index '0'
1090// :77:27: error: use of undefined value here causes illegal behavior1072// :77:27: error: use of undefined value here causes illegal behavior
1091// :77:27: note: when computing vector element at index '0'1073// :77:27: note: when computing vector element at index '0'
1092// :77:27: error: use of undefined value here causes illegal behavior1074// :77:27: error: use of undefined value here causes illegal behavior
1093// :77:27: note: when computing vector element at index '0'1075// :77:27: note: when computing vector element at index '0'
1094// :77:27: error: use of undefined value here causes illegal behavior1076// :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
1097// :77:27: note: when computing vector element at index '0'1077// :77:27: note: when computing vector element at index '0'
1098// :77:27: error: use of undefined value here causes illegal behavior1078// :77:27: error: use of undefined value here causes illegal behavior
1099// :77:27: note: when computing vector element at index '0'1079// :77:27: note: when computing vector element at index '0'
...@@ -1102,10 +1082,6 @@ const std = @import("std");...@@ -1102,10 +1082,6 @@ const std = @import("std");
1102// :77:27: error: use of undefined value here causes illegal behavior1082// :77:27: error: use of undefined value here causes illegal behavior
1103// :77:27: note: when computing vector element at index '0'1083// :77:27: note: when computing vector element at index '0'
1104// :77:27: error: use of undefined value here causes illegal behavior1084// :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
1109// :77:27: note: when computing vector element at index '0'1085// :77:27: note: when computing vector element at index '0'
1110// :77:27: error: use of undefined value here causes illegal behavior1086// :77:27: error: use of undefined value here causes illegal behavior
1111// :77:27: note: when computing vector element at index '0'1087// :77:27: note: when computing vector element at index '0'
...@@ -1114,7 +1090,9 @@ const std = @import("std");...@@ -1114,7 +1090,9 @@ const std = @import("std");
1114// :77:27: error: use of undefined value here causes illegal behavior1090// :77:27: error: use of undefined value here causes illegal behavior
1115// :77:27: note: when computing vector element at index '0'1091// :77:27: note: when computing vector element at index '0'
1116// :77:27: error: use of undefined value here causes illegal behavior1092// :77:27: error: use of undefined value here causes illegal behavior
1093// :77:27: note: when computing vector element at index '0'
1117// :77:27: error: use of undefined value here causes illegal behavior1094// :77:27: error: use of undefined value here causes illegal behavior
1095// :77:27: note: when computing vector element at index '0'
1118// :77:27: error: use of undefined value here causes illegal behavior1096// :77:27: error: use of undefined value here causes illegal behavior
1119// :77:27: note: when computing vector element at index '0'1097// :77:27: note: when computing vector element at index '0'
1120// :77:27: error: use of undefined value here causes illegal behavior1098// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1124,9 +1102,9 @@ const std = @import("std");...@@ -1124,9 +1102,9 @@ const std = @import("std");
1124// :77:27: error: use of undefined value here causes illegal behavior1102// :77:27: error: use of undefined value here causes illegal behavior
1125// :77:27: note: when computing vector element at index '0'1103// :77:27: note: when computing vector element at index '0'
1126// :77:27: error: use of undefined value here causes illegal behavior1104// :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'
1128// :77:27: error: use of undefined value here causes illegal behavior1106// :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'
1130// :77:27: error: use of undefined value here causes illegal behavior1108// :77:27: error: use of undefined value here causes illegal behavior
1131// :77:27: note: when computing vector element at index '0'1109// :77:27: note: when computing vector element at index '0'
1132// :77:27: error: use of undefined value here causes illegal behavior1110// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1136,7 +1114,9 @@ const std = @import("std");...@@ -1136,7 +1114,9 @@ const std = @import("std");
1136// :77:27: error: use of undefined value here causes illegal behavior1114// :77:27: error: use of undefined value here causes illegal behavior
1137// :77:27: note: when computing vector element at index '0'1115// :77:27: note: when computing vector element at index '0'
1138// :77:27: error: use of undefined value here causes illegal behavior1116// :77:27: error: use of undefined value here causes illegal behavior
1117// :77:27: note: when computing vector element at index '0'
1139// :77:27: error: use of undefined value here causes illegal behavior1118// :77:27: error: use of undefined value here causes illegal behavior
1119// :77:27: note: when computing vector element at index '0'
1140// :77:27: error: use of undefined value here causes illegal behavior1120// :77:27: error: use of undefined value here causes illegal behavior
1141// :77:27: note: when computing vector element at index '0'1121// :77:27: note: when computing vector element at index '0'
1142// :77:27: error: use of undefined value here causes illegal behavior1122// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1146,9 +1126,9 @@ const std = @import("std");...@@ -1146,9 +1126,9 @@ const std = @import("std");
1146// :77:27: error: use of undefined value here causes illegal behavior1126// :77:27: error: use of undefined value here causes illegal behavior
1147// :77:27: note: when computing vector element at index '0'1127// :77:27: note: when computing vector element at index '0'
1148// :77:27: error: use of undefined value here causes illegal behavior1128// :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'
1150// :77:27: error: use of undefined value here causes illegal behavior1130// :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'
1152// :77:27: error: use of undefined value here causes illegal behavior1132// :77:27: error: use of undefined value here causes illegal behavior
1153// :77:27: note: when computing vector element at index '0'1133// :77:27: note: when computing vector element at index '0'
1154// :77:27: error: use of undefined value here causes illegal behavior1134// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1158,7 +1138,9 @@ const std = @import("std");...@@ -1158,7 +1138,9 @@ const std = @import("std");
1158// :77:27: error: use of undefined value here causes illegal behavior1138// :77:27: error: use of undefined value here causes illegal behavior
1159// :77:27: note: when computing vector element at index '0'1139// :77:27: note: when computing vector element at index '0'
1160// :77:27: error: use of undefined value here causes illegal behavior1140// :77:27: error: use of undefined value here causes illegal behavior
1141// :77:27: note: when computing vector element at index '0'
1161// :77:27: error: use of undefined value here causes illegal behavior1142// :77:27: error: use of undefined value here causes illegal behavior
1143// :77:27: note: when computing vector element at index '0'
1162// :77:27: error: use of undefined value here causes illegal behavior1144// :77:27: error: use of undefined value here causes illegal behavior
1163// :77:27: note: when computing vector element at index '0'1145// :77:27: note: when computing vector element at index '0'
1164// :77:27: error: use of undefined value here causes illegal behavior1146// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1168,9 +1150,9 @@ const std = @import("std");...@@ -1168,9 +1150,9 @@ const std = @import("std");
1168// :77:27: error: use of undefined value here causes illegal behavior1150// :77:27: error: use of undefined value here causes illegal behavior
1169// :77:27: note: when computing vector element at index '0'1151// :77:27: note: when computing vector element at index '0'
1170// :77:27: error: use of undefined value here causes illegal behavior1152// :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'
1172// :77:27: error: use of undefined value here causes illegal behavior1154// :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'
1174// :77:27: error: use of undefined value here causes illegal behavior1156// :77:27: error: use of undefined value here causes illegal behavior
1175// :77:27: note: when computing vector element at index '0'1157// :77:27: note: when computing vector element at index '0'
1176// :77:27: error: use of undefined value here causes illegal behavior1158// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1180,7 +1162,9 @@ const std = @import("std");...@@ -1180,7 +1162,9 @@ const std = @import("std");
1180// :77:27: error: use of undefined value here causes illegal behavior1162// :77:27: error: use of undefined value here causes illegal behavior
1181// :77:27: note: when computing vector element at index '0'1163// :77:27: note: when computing vector element at index '0'
1182// :77:27: error: use of undefined value here causes illegal behavior1164// :77:27: error: use of undefined value here causes illegal behavior
1165// :77:27: note: when computing vector element at index '0'
1183// :77:27: error: use of undefined value here causes illegal behavior1166// :77:27: error: use of undefined value here causes illegal behavior
1167// :77:27: note: when computing vector element at index '0'
1184// :77:27: error: use of undefined value here causes illegal behavior1168// :77:27: error: use of undefined value here causes illegal behavior
1185// :77:27: note: when computing vector element at index '0'1169// :77:27: note: when computing vector element at index '0'
1186// :77:27: error: use of undefined value here causes illegal behavior1170// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1190,9 +1174,9 @@ const std = @import("std");...@@ -1190,9 +1174,9 @@ const std = @import("std");
1190// :77:27: error: use of undefined value here causes illegal behavior1174// :77:27: error: use of undefined value here causes illegal behavior
1191// :77:27: note: when computing vector element at index '0'1175// :77:27: note: when computing vector element at index '0'
1192// :77:27: error: use of undefined value here causes illegal behavior1176// :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'
1194// :77:27: error: use of undefined value here causes illegal behavior1178// :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'
1196// :77:27: error: use of undefined value here causes illegal behavior1180// :77:27: error: use of undefined value here causes illegal behavior
1197// :77:27: note: when computing vector element at index '0'1181// :77:27: note: when computing vector element at index '0'
1198// :77:27: error: use of undefined value here causes illegal behavior1182// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1202,7 +1186,9 @@ const std = @import("std");...@@ -1202,7 +1186,9 @@ const std = @import("std");
1202// :77:27: error: use of undefined value here causes illegal behavior1186// :77:27: error: use of undefined value here causes illegal behavior
1203// :77:27: note: when computing vector element at index '0'1187// :77:27: note: when computing vector element at index '0'
1204// :77:27: error: use of undefined value here causes illegal behavior1188// :77:27: error: use of undefined value here causes illegal behavior
1189// :77:27: note: when computing vector element at index '0'
1205// :77:27: error: use of undefined value here causes illegal behavior1190// :77:27: error: use of undefined value here causes illegal behavior
1191// :77:27: note: when computing vector element at index '0'
1206// :77:27: error: use of undefined value here causes illegal behavior1192// :77:27: error: use of undefined value here causes illegal behavior
1207// :77:27: note: when computing vector element at index '0'1193// :77:27: note: when computing vector element at index '0'
1208// :77:27: error: use of undefined value here causes illegal behavior1194// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1212,9 +1198,9 @@ const std = @import("std");...@@ -1212,9 +1198,9 @@ const std = @import("std");
1212// :77:27: error: use of undefined value here causes illegal behavior1198// :77:27: error: use of undefined value here causes illegal behavior
1213// :77:27: note: when computing vector element at index '0'1199// :77:27: note: when computing vector element at index '0'
1214// :77:27: error: use of undefined value here causes illegal behavior1200// :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'
1216// :77:27: error: use of undefined value here causes illegal behavior1202// :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'
1218// :77:27: error: use of undefined value here causes illegal behavior1204// :77:27: error: use of undefined value here causes illegal behavior
1219// :77:27: note: when computing vector element at index '0'1205// :77:27: note: when computing vector element at index '0'
1220// :77:27: error: use of undefined value here causes illegal behavior1206// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1224,7 +1210,9 @@ const std = @import("std");...@@ -1224,7 +1210,9 @@ const std = @import("std");
1224// :77:27: error: use of undefined value here causes illegal behavior1210// :77:27: error: use of undefined value here causes illegal behavior
1225// :77:27: note: when computing vector element at index '0'1211// :77:27: note: when computing vector element at index '0'
1226// :77:27: error: use of undefined value here causes illegal behavior1212// :77:27: error: use of undefined value here causes illegal behavior
1213// :77:27: note: when computing vector element at index '0'
1227// :77:27: error: use of undefined value here causes illegal behavior1214// :77:27: error: use of undefined value here causes illegal behavior
1215// :77:27: note: when computing vector element at index '0'
1228// :77:27: error: use of undefined value here causes illegal behavior1216// :77:27: error: use of undefined value here causes illegal behavior
1229// :77:27: note: when computing vector element at index '0'1217// :77:27: note: when computing vector element at index '0'
1230// :77:27: error: use of undefined value here causes illegal behavior1218// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1234,9 +1222,9 @@ const std = @import("std");...@@ -1234,9 +1222,9 @@ const std = @import("std");
1234// :77:27: error: use of undefined value here causes illegal behavior1222// :77:27: error: use of undefined value here causes illegal behavior
1235// :77:27: note: when computing vector element at index '0'1223// :77:27: note: when computing vector element at index '0'
1236// :77:27: error: use of undefined value here causes illegal behavior1224// :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'
1238// :77:27: error: use of undefined value here causes illegal behavior1226// :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'
1240// :77:27: error: use of undefined value here causes illegal behavior1228// :77:27: error: use of undefined value here causes illegal behavior
1241// :77:27: note: when computing vector element at index '0'1229// :77:27: note: when computing vector element at index '0'
1242// :77:27: error: use of undefined value here causes illegal behavior1230// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1246,7 +1234,9 @@ const std = @import("std");...@@ -1246,7 +1234,9 @@ const std = @import("std");
1246// :77:27: error: use of undefined value here causes illegal behavior1234// :77:27: error: use of undefined value here causes illegal behavior
1247// :77:27: note: when computing vector element at index '0'1235// :77:27: note: when computing vector element at index '0'
1248// :77:27: error: use of undefined value here causes illegal behavior1236// :77:27: error: use of undefined value here causes illegal behavior
1237// :77:27: note: when computing vector element at index '0'
1249// :77:27: error: use of undefined value here causes illegal behavior1238// :77:27: error: use of undefined value here causes illegal behavior
1239// :77:27: note: when computing vector element at index '0'
1250// :77:27: error: use of undefined value here causes illegal behavior1240// :77:27: error: use of undefined value here causes illegal behavior
1251// :77:27: note: when computing vector element at index '0'1241// :77:27: note: when computing vector element at index '0'
1252// :77:27: error: use of undefined value here causes illegal behavior1242// :77:27: error: use of undefined value here causes illegal behavior
...@@ -1260,35 +1250,45 @@ const std = @import("std");...@@ -1260,35 +1250,45 @@ const std = @import("std");
1260// :77:27: error: use of undefined value here causes illegal behavior1250// :77:27: error: use of undefined value here causes illegal behavior
1261// :77:27: note: when computing vector element at index '1'1251// :77:27: note: when computing vector element at index '1'
1262// :77:27: error: use of undefined value here causes illegal behavior1252// :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'
1264// :77:27: error: use of undefined value here causes illegal behavior1254// :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'
1266// :77:27: error: use of undefined value here causes illegal behavior1256// :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'
1268// :77:27: error: use of undefined value here causes illegal behavior1258// :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'
1270// :77:27: error: use of undefined value here causes illegal behavior1260// :77:27: error: use of undefined value here causes illegal behavior
1261// :77:27: note: when computing vector element at index '1'
1271// :77:27: error: use of undefined value here causes illegal behavior1262// :77:27: error: use of undefined value here causes illegal behavior
1263// :77:27: note: when computing vector element at index '1'
1272// :77:27: error: use of undefined value here causes illegal behavior1264// :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'
1274// :77:27: error: use of undefined value here causes illegal behavior1266// :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'
1276// :77:27: error: use of undefined value here causes illegal behavior1268// :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'
1278// :77:27: error: use of undefined value here causes illegal behavior1270// :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'
1280// :77:27: error: use of undefined value here causes illegal behavior1272// :77:27: error: use of undefined value here causes illegal behavior
1281// :77:27: note: when computing vector element at index '1'1273// :77:27: note: when computing vector element at index '1'
1282// :77:27: error: use of undefined value here causes illegal behavior1274// :77:27: error: use of undefined value here causes illegal behavior
1283// :77:27: note: when computing vector element at index '1'1275// :77:27: note: when computing vector element at index '1'
1284// :77:27: error: use of undefined value here causes illegal behavior1276// :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'
1286// :77:27: error: use of undefined value here causes illegal behavior1278// :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'
1288// :77:27: error: use of undefined value here causes illegal behavior1280// :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'
1290// :77:27: error: use of undefined value here causes illegal behavior1282// :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'
1292// :77:30: error: use of undefined value here causes illegal behavior1292// :77:30: error: use of undefined value here causes illegal behavior
1293// :77:30: note: when computing vector element at index '0'1293// :77:30: note: when computing vector element at index '0'
1294// :77:30: error: use of undefined value here causes illegal behavior1294// :77:30: error: use of undefined value here causes illegal behavior
...@@ -1336,50 +1336,30 @@ const std = @import("std");...@@ -1336,50 +1336,30 @@ const std = @import("std");
1336// :81:17: error: use of undefined value here causes illegal behavior1336// :81:17: error: use of undefined value here causes illegal behavior
1337// :81:17: error: use of undefined value here causes illegal behavior1337// :81:17: error: use of undefined value here causes illegal behavior
1338// :81:17: error: use of undefined value here causes illegal behavior1338// :81:17: error: use of undefined value here causes illegal behavior
1339// :81:17: note: when computing vector element at index '0'
1340// :81:17: error: use of undefined value here causes illegal behavior1339// :81:17: error: use of undefined value here causes illegal behavior
1341// :81:17: note: when computing vector element at index '0'
1342// :81:17: error: use of undefined value here causes illegal behavior1340// :81:17: error: use of undefined value here causes illegal behavior
1343// :81:17: note: when computing vector element at index '0'
1344// :81:17: error: use of undefined value here causes illegal behavior1341// :81:17: error: use of undefined value here causes illegal behavior
1345// :81:17: note: when computing vector element at index '0'
1346// :81:17: error: use of undefined value here causes illegal behavior1342// :81:17: error: use of undefined value here causes illegal behavior
1347// :81:17: note: when computing vector element at index '1'
1348// :81:17: error: use of undefined value here causes illegal behavior1343// :81:17: error: use of undefined value here causes illegal behavior
1349// :81:17: note: when computing vector element at index '1'
1350// :81:17: error: use of undefined value here causes illegal behavior1344// :81:17: error: use of undefined value here causes illegal behavior
1351// :81:17: note: when computing vector element at index '0'
1352// :81:17: error: use of undefined value here causes illegal behavior1345// :81:17: error: use of undefined value here causes illegal behavior
1353// :81:17: note: when computing vector element at index '0'
1354// :81:17: error: use of undefined value here causes illegal behavior1346// :81:17: error: use of undefined value here causes illegal behavior
1355// :81:17: note: when computing vector element at index '0'
1356// :81:17: error: use of undefined value here causes illegal behavior1347// :81:17: error: use of undefined value here causes illegal behavior
1357// :81:17: note: when computing vector element at index '0'
1358// :81:17: error: use of undefined value here causes illegal behavior1348// :81:17: error: use of undefined value here causes illegal behavior
1359// :81:17: error: use of undefined value here causes illegal behavior1349// :81:17: error: use of undefined value here causes illegal behavior
1360// :81:17: error: use of undefined value here causes illegal behavior1350// :81:17: error: use of undefined value here causes illegal behavior
1361// :81:17: note: when computing vector element at index '0'
1362// :81:17: error: use of undefined value here causes illegal behavior1351// :81:17: error: use of undefined value here causes illegal behavior
1363// :81:17: note: when computing vector element at index '0'
1364// :81:17: error: use of undefined value here causes illegal behavior1352// :81:17: error: use of undefined value here causes illegal behavior
1365// :81:17: note: when computing vector element at index '0'
1366// :81:17: error: use of undefined value here causes illegal behavior1353// :81:17: error: use of undefined value here causes illegal behavior
1367// :81:17: note: when computing vector element at index '0'
1368// :81:17: error: use of undefined value here causes illegal behavior1354// :81:17: error: use of undefined value here causes illegal behavior
1369// :81:17: note: when computing vector element at index '1'
1370// :81:17: error: use of undefined value here causes illegal behavior1355// :81:17: error: use of undefined value here causes illegal behavior
1371// :81:17: note: when computing vector element at index '1'
1372// :81:17: error: use of undefined value here causes illegal behavior1356// :81:17: error: use of undefined value here causes illegal behavior
1373// :81:17: note: when computing vector element at index '0'
1374// :81:17: error: use of undefined value here causes illegal behavior1357// :81:17: error: use of undefined value here causes illegal behavior
1375// :81:17: note: when computing vector element at index '0'
1376// :81:17: error: use of undefined value here causes illegal behavior1358// :81:17: error: use of undefined value here causes illegal behavior
1377// :81:17: note: when computing vector element at index '0'1359// :81:17: note: when computing vector element at index '0'
1378// :81:17: error: use of undefined value here causes illegal behavior1360// :81:17: error: use of undefined value here causes illegal behavior
1379// :81:17: note: when computing vector element at index '0'1361// :81:17: note: when computing vector element at index '0'
1380// :81:17: error: use of undefined value here causes illegal behavior1362// :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
1383// :81:17: note: when computing vector element at index '0'1363// :81:17: note: when computing vector element at index '0'
1384// :81:17: error: use of undefined value here causes illegal behavior1364// :81:17: error: use of undefined value here causes illegal behavior
1385// :81:17: note: when computing vector element at index '0'1365// :81:17: note: when computing vector element at index '0'
...@@ -1388,10 +1368,6 @@ const std = @import("std");...@@ -1388,10 +1368,6 @@ const std = @import("std");
1388// :81:17: error: use of undefined value here causes illegal behavior1368// :81:17: error: use of undefined value here causes illegal behavior
1389// :81:17: note: when computing vector element at index '0'1369// :81:17: note: when computing vector element at index '0'
1390// :81:17: error: use of undefined value here causes illegal behavior1370// :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
1395// :81:17: note: when computing vector element at index '0'1371// :81:17: note: when computing vector element at index '0'
1396// :81:17: error: use of undefined value here causes illegal behavior1372// :81:17: error: use of undefined value here causes illegal behavior
1397// :81:17: note: when computing vector element at index '0'1373// :81:17: note: when computing vector element at index '0'
...@@ -1400,7 +1376,9 @@ const std = @import("std");...@@ -1400,7 +1376,9 @@ const std = @import("std");
1400// :81:17: error: use of undefined value here causes illegal behavior1376// :81:17: error: use of undefined value here causes illegal behavior
1401// :81:17: note: when computing vector element at index '0'1377// :81:17: note: when computing vector element at index '0'
1402// :81:17: error: use of undefined value here causes illegal behavior1378// :81:17: error: use of undefined value here causes illegal behavior
1379// :81:17: note: when computing vector element at index '0'
1403// :81:17: error: use of undefined value here causes illegal behavior1380// :81:17: error: use of undefined value here causes illegal behavior
1381// :81:17: note: when computing vector element at index '0'
1404// :81:17: error: use of undefined value here causes illegal behavior1382// :81:17: error: use of undefined value here causes illegal behavior
1405// :81:17: note: when computing vector element at index '0'1383// :81:17: note: when computing vector element at index '0'
1406// :81:17: error: use of undefined value here causes illegal behavior1384// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1410,9 +1388,9 @@ const std = @import("std");...@@ -1410,9 +1388,9 @@ const std = @import("std");
1410// :81:17: error: use of undefined value here causes illegal behavior1388// :81:17: error: use of undefined value here causes illegal behavior
1411// :81:17: note: when computing vector element at index '0'1389// :81:17: note: when computing vector element at index '0'
1412// :81:17: error: use of undefined value here causes illegal behavior1390// :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'
1414// :81:17: error: use of undefined value here causes illegal behavior1392// :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'
1416// :81:17: error: use of undefined value here causes illegal behavior1394// :81:17: error: use of undefined value here causes illegal behavior
1417// :81:17: note: when computing vector element at index '0'1395// :81:17: note: when computing vector element at index '0'
1418// :81:17: error: use of undefined value here causes illegal behavior1396// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1422,7 +1400,9 @@ const std = @import("std");...@@ -1422,7 +1400,9 @@ const std = @import("std");
1422// :81:17: error: use of undefined value here causes illegal behavior1400// :81:17: error: use of undefined value here causes illegal behavior
1423// :81:17: note: when computing vector element at index '0'1401// :81:17: note: when computing vector element at index '0'
1424// :81:17: error: use of undefined value here causes illegal behavior1402// :81:17: error: use of undefined value here causes illegal behavior
1403// :81:17: note: when computing vector element at index '0'
1425// :81:17: error: use of undefined value here causes illegal behavior1404// :81:17: error: use of undefined value here causes illegal behavior
1405// :81:17: note: when computing vector element at index '0'
1426// :81:17: error: use of undefined value here causes illegal behavior1406// :81:17: error: use of undefined value here causes illegal behavior
1427// :81:17: note: when computing vector element at index '0'1407// :81:17: note: when computing vector element at index '0'
1428// :81:17: error: use of undefined value here causes illegal behavior1408// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1432,9 +1412,9 @@ const std = @import("std");...@@ -1432,9 +1412,9 @@ const std = @import("std");
1432// :81:17: error: use of undefined value here causes illegal behavior1412// :81:17: error: use of undefined value here causes illegal behavior
1433// :81:17: note: when computing vector element at index '0'1413// :81:17: note: when computing vector element at index '0'
1434// :81:17: error: use of undefined value here causes illegal behavior1414// :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'
1436// :81:17: error: use of undefined value here causes illegal behavior1416// :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'
1438// :81:17: error: use of undefined value here causes illegal behavior1418// :81:17: error: use of undefined value here causes illegal behavior
1439// :81:17: note: when computing vector element at index '0'1419// :81:17: note: when computing vector element at index '0'
1440// :81:17: error: use of undefined value here causes illegal behavior1420// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1444,7 +1424,9 @@ const std = @import("std");...@@ -1444,7 +1424,9 @@ const std = @import("std");
1444// :81:17: error: use of undefined value here causes illegal behavior1424// :81:17: error: use of undefined value here causes illegal behavior
1445// :81:17: note: when computing vector element at index '0'1425// :81:17: note: when computing vector element at index '0'
1446// :81:17: error: use of undefined value here causes illegal behavior1426// :81:17: error: use of undefined value here causes illegal behavior
1427// :81:17: note: when computing vector element at index '0'
1447// :81:17: error: use of undefined value here causes illegal behavior1428// :81:17: error: use of undefined value here causes illegal behavior
1429// :81:17: note: when computing vector element at index '0'
1448// :81:17: error: use of undefined value here causes illegal behavior1430// :81:17: error: use of undefined value here causes illegal behavior
1449// :81:17: note: when computing vector element at index '0'1431// :81:17: note: when computing vector element at index '0'
1450// :81:17: error: use of undefined value here causes illegal behavior1432// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1454,9 +1436,9 @@ const std = @import("std");...@@ -1454,9 +1436,9 @@ const std = @import("std");
1454// :81:17: error: use of undefined value here causes illegal behavior1436// :81:17: error: use of undefined value here causes illegal behavior
1455// :81:17: note: when computing vector element at index '0'1437// :81:17: note: when computing vector element at index '0'
1456// :81:17: error: use of undefined value here causes illegal behavior1438// :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'
1458// :81:17: error: use of undefined value here causes illegal behavior1440// :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'
1460// :81:17: error: use of undefined value here causes illegal behavior1442// :81:17: error: use of undefined value here causes illegal behavior
1461// :81:17: note: when computing vector element at index '0'1443// :81:17: note: when computing vector element at index '0'
1462// :81:17: error: use of undefined value here causes illegal behavior1444// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1466,7 +1448,9 @@ const std = @import("std");...@@ -1466,7 +1448,9 @@ const std = @import("std");
1466// :81:17: error: use of undefined value here causes illegal behavior1448// :81:17: error: use of undefined value here causes illegal behavior
1467// :81:17: note: when computing vector element at index '0'1449// :81:17: note: when computing vector element at index '0'
1468// :81:17: error: use of undefined value here causes illegal behavior1450// :81:17: error: use of undefined value here causes illegal behavior
1451// :81:17: note: when computing vector element at index '0'
1469// :81:17: error: use of undefined value here causes illegal behavior1452// :81:17: error: use of undefined value here causes illegal behavior
1453// :81:17: note: when computing vector element at index '0'
1470// :81:17: error: use of undefined value here causes illegal behavior1454// :81:17: error: use of undefined value here causes illegal behavior
1471// :81:17: note: when computing vector element at index '0'1455// :81:17: note: when computing vector element at index '0'
1472// :81:17: error: use of undefined value here causes illegal behavior1456// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1476,9 +1460,9 @@ const std = @import("std");...@@ -1476,9 +1460,9 @@ const std = @import("std");
1476// :81:17: error: use of undefined value here causes illegal behavior1460// :81:17: error: use of undefined value here causes illegal behavior
1477// :81:17: note: when computing vector element at index '0'1461// :81:17: note: when computing vector element at index '0'
1478// :81:17: error: use of undefined value here causes illegal behavior1462// :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'
1480// :81:17: error: use of undefined value here causes illegal behavior1464// :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'
1482// :81:17: error: use of undefined value here causes illegal behavior1466// :81:17: error: use of undefined value here causes illegal behavior
1483// :81:17: note: when computing vector element at index '0'1467// :81:17: note: when computing vector element at index '0'
1484// :81:17: error: use of undefined value here causes illegal behavior1468// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1488,7 +1472,9 @@ const std = @import("std");...@@ -1488,7 +1472,9 @@ const std = @import("std");
1488// :81:17: error: use of undefined value here causes illegal behavior1472// :81:17: error: use of undefined value here causes illegal behavior
1489// :81:17: note: when computing vector element at index '0'1473// :81:17: note: when computing vector element at index '0'
1490// :81:17: error: use of undefined value here causes illegal behavior1474// :81:17: error: use of undefined value here causes illegal behavior
1475// :81:17: note: when computing vector element at index '0'
1491// :81:17: error: use of undefined value here causes illegal behavior1476// :81:17: error: use of undefined value here causes illegal behavior
1477// :81:17: note: when computing vector element at index '0'
1492// :81:17: error: use of undefined value here causes illegal behavior1478// :81:17: error: use of undefined value here causes illegal behavior
1493// :81:17: note: when computing vector element at index '0'1479// :81:17: note: when computing vector element at index '0'
1494// :81:17: error: use of undefined value here causes illegal behavior1480// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1498,9 +1484,9 @@ const std = @import("std");...@@ -1498,9 +1484,9 @@ const std = @import("std");
1498// :81:17: error: use of undefined value here causes illegal behavior1484// :81:17: error: use of undefined value here causes illegal behavior
1499// :81:17: note: when computing vector element at index '0'1485// :81:17: note: when computing vector element at index '0'
1500// :81:17: error: use of undefined value here causes illegal behavior1486// :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'
1502// :81:17: error: use of undefined value here causes illegal behavior1488// :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'
1504// :81:17: error: use of undefined value here causes illegal behavior1490// :81:17: error: use of undefined value here causes illegal behavior
1505// :81:17: note: when computing vector element at index '0'1491// :81:17: note: when computing vector element at index '0'
1506// :81:17: error: use of undefined value here causes illegal behavior1492// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1510,7 +1496,9 @@ const std = @import("std");...@@ -1510,7 +1496,9 @@ const std = @import("std");
1510// :81:17: error: use of undefined value here causes illegal behavior1496// :81:17: error: use of undefined value here causes illegal behavior
1511// :81:17: note: when computing vector element at index '0'1497// :81:17: note: when computing vector element at index '0'
1512// :81:17: error: use of undefined value here causes illegal behavior1498// :81:17: error: use of undefined value here causes illegal behavior
1499// :81:17: note: when computing vector element at index '0'
1513// :81:17: error: use of undefined value here causes illegal behavior1500// :81:17: error: use of undefined value here causes illegal behavior
1501// :81:17: note: when computing vector element at index '0'
1514// :81:17: error: use of undefined value here causes illegal behavior1502// :81:17: error: use of undefined value here causes illegal behavior
1515// :81:17: note: when computing vector element at index '0'1503// :81:17: note: when computing vector element at index '0'
1516// :81:17: error: use of undefined value here causes illegal behavior1504// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1520,9 +1508,9 @@ const std = @import("std");...@@ -1520,9 +1508,9 @@ const std = @import("std");
1520// :81:17: error: use of undefined value here causes illegal behavior1508// :81:17: error: use of undefined value here causes illegal behavior
1521// :81:17: note: when computing vector element at index '0'1509// :81:17: note: when computing vector element at index '0'
1522// :81:17: error: use of undefined value here causes illegal behavior1510// :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'
1524// :81:17: error: use of undefined value here causes illegal behavior1512// :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'
1526// :81:17: error: use of undefined value here causes illegal behavior1514// :81:17: error: use of undefined value here causes illegal behavior
1527// :81:17: note: when computing vector element at index '0'1515// :81:17: note: when computing vector element at index '0'
1528// :81:17: error: use of undefined value here causes illegal behavior1516// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1532,7 +1520,9 @@ const std = @import("std");...@@ -1532,7 +1520,9 @@ const std = @import("std");
1532// :81:17: error: use of undefined value here causes illegal behavior1520// :81:17: error: use of undefined value here causes illegal behavior
1533// :81:17: note: when computing vector element at index '0'1521// :81:17: note: when computing vector element at index '0'
1534// :81:17: error: use of undefined value here causes illegal behavior1522// :81:17: error: use of undefined value here causes illegal behavior
1523// :81:17: note: when computing vector element at index '0'
1535// :81:17: error: use of undefined value here causes illegal behavior1524// :81:17: error: use of undefined value here causes illegal behavior
1525// :81:17: note: when computing vector element at index '0'
1536// :81:17: error: use of undefined value here causes illegal behavior1526// :81:17: error: use of undefined value here causes illegal behavior
1537// :81:17: note: when computing vector element at index '0'1527// :81:17: note: when computing vector element at index '0'
1538// :81:17: error: use of undefined value here causes illegal behavior1528// :81:17: error: use of undefined value here causes illegal behavior
...@@ -1546,35 +1536,45 @@ const std = @import("std");...@@ -1546,35 +1536,45 @@ const std = @import("std");
1546// :81:17: error: use of undefined value here causes illegal behavior1536// :81:17: error: use of undefined value here causes illegal behavior
1547// :81:17: note: when computing vector element at index '1'1537// :81:17: note: when computing vector element at index '1'
1548// :81:17: error: use of undefined value here causes illegal behavior1538// :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'
1550// :81:17: error: use of undefined value here causes illegal behavior1540// :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'
1552// :81:17: error: use of undefined value here causes illegal behavior1542// :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'
1554// :81:17: error: use of undefined value here causes illegal behavior1544// :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'
1556// :81:17: error: use of undefined value here causes illegal behavior1546// :81:17: error: use of undefined value here causes illegal behavior
1547// :81:17: note: when computing vector element at index '1'
1557// :81:17: error: use of undefined value here causes illegal behavior1548// :81:17: error: use of undefined value here causes illegal behavior
1549// :81:17: note: when computing vector element at index '1'
1558// :81:17: error: use of undefined value here causes illegal behavior1550// :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'
1560// :81:17: error: use of undefined value here causes illegal behavior1552// :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'
1562// :81:17: error: use of undefined value here causes illegal behavior1554// :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'
1564// :81:17: error: use of undefined value here causes illegal behavior1556// :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'
1566// :81:17: error: use of undefined value here causes illegal behavior1558// :81:17: error: use of undefined value here causes illegal behavior
1567// :81:17: note: when computing vector element at index '1'1559// :81:17: note: when computing vector element at index '1'
1568// :81:17: error: use of undefined value here causes illegal behavior1560// :81:17: error: use of undefined value here causes illegal behavior
1569// :81:17: note: when computing vector element at index '1'1561// :81:17: note: when computing vector element at index '1'
1570// :81:17: error: use of undefined value here causes illegal behavior1562// :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'
1572// :81:17: error: use of undefined value here causes illegal behavior1564// :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'
1574// :81:17: error: use of undefined value here causes illegal behavior1566// :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'
1576// :81:17: error: use of undefined value here causes illegal behavior1568// :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'
1578// :81:21: error: use of undefined value here causes illegal behavior1578// :81:21: error: use of undefined value here causes illegal behavior
1579// :81:21: note: when computing vector element at index '0'1579// :81:21: note: when computing vector element at index '0'
1580// :81:21: error: use of undefined value here causes illegal behavior1580// :81:21: error: use of undefined value here causes illegal behavior
...@@ -1622,39 +1622,25 @@ const std = @import("std");...@@ -1622,39 +1622,25 @@ const std = @import("std");
1622// :85:22: error: use of undefined value here causes illegal behavior1622// :85:22: error: use of undefined value here causes illegal behavior
1623// :85:22: error: use of undefined value here causes illegal behavior1623// :85:22: error: use of undefined value here causes illegal behavior
1624// :85:22: error: use of undefined value here causes illegal behavior1624// :85:22: error: use of undefined value here causes illegal behavior
1625// :85:22: note: when computing vector element at index '0'
1626// :85:22: error: use of undefined value here causes illegal behavior1625// :85:22: error: use of undefined value here causes illegal behavior
1627// :85:22: note: when computing vector element at index '0'
1628// :85:22: error: use of undefined value here causes illegal behavior1626// :85:22: error: use of undefined value here causes illegal behavior
1629// :85:22: note: when computing vector element at index '0'
1630// :85:22: error: use of undefined value here causes illegal behavior1627// :85:22: error: use of undefined value here causes illegal behavior
1631// :85:22: note: when computing vector element at index '0'
1632// :85:22: error: use of undefined value here causes illegal behavior1628// :85:22: error: use of undefined value here causes illegal behavior
1633// :85:22: note: when computing vector element at index '1'
1634// :85:22: error: use of undefined value here causes illegal behavior1629// :85:22: error: use of undefined value here causes illegal behavior
1635// :85:22: note: when computing vector element at index '1'
1636// :85:22: error: use of undefined value here causes illegal behavior1630// :85:22: error: use of undefined value here causes illegal behavior
1637// :85:22: note: when computing vector element at index '0'
1638// :85:22: error: use of undefined value here causes illegal behavior1631// :85:22: error: use of undefined value here causes illegal behavior
1639// :85:22: note: when computing vector element at index '0'
1640// :85:22: error: use of undefined value here causes illegal behavior1632// :85:22: error: use of undefined value here causes illegal behavior
1641// :85:22: note: when computing vector element at index '0'
1642// :85:22: error: use of undefined value here causes illegal behavior1633// :85:22: error: use of undefined value here causes illegal behavior
1643// :85:22: note: when computing vector element at index '0'
1644// :85:22: error: use of undefined value here causes illegal behavior1634// :85:22: error: use of undefined value here causes illegal behavior
1645// :85:22: error: use of undefined value here causes illegal behavior1635// :85:22: error: use of undefined value here causes illegal behavior
1646// :85:22: error: use of undefined value here causes illegal behavior1636// :85:22: error: use of undefined value here causes illegal behavior
1647// :85:22: note: when computing vector element at index '0'
1648// :85:22: error: use of undefined value here causes illegal behavior1637// :85:22: error: use of undefined value here causes illegal behavior
1649// :85:22: note: when computing vector element at index '0'
1650// :85:22: error: use of undefined value here causes illegal behavior1638// :85:22: error: use of undefined value here causes illegal behavior
1651// :85:22: note: when computing vector element at index '0'
1652// :85:22: error: use of undefined value here causes illegal behavior1639// :85:22: error: use of undefined value here causes illegal behavior
1653// :85:22: note: when computing vector element at index '0'
1654// :85:22: error: use of undefined value here causes illegal behavior1640// :85:22: error: use of undefined value here causes illegal behavior
1655// :85:22: note: when computing vector element at index '1'
1656// :85:22: error: use of undefined value here causes illegal behavior1641// :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
1658// :85:22: error: use of undefined value here causes illegal behavior1644// :85:22: error: use of undefined value here causes illegal behavior
1659// :85:22: note: when computing vector element at index '0'1645// :85:22: note: when computing vector element at index '0'
1660// :85:22: error: use of undefined value here causes illegal behavior1646// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1664,7 +1650,9 @@ const std = @import("std");...@@ -1664,7 +1650,9 @@ const std = @import("std");
1664// :85:22: error: use of undefined value here causes illegal behavior1650// :85:22: error: use of undefined value here causes illegal behavior
1665// :85:22: note: when computing vector element at index '0'1651// :85:22: note: when computing vector element at index '0'
1666// :85:22: error: use of undefined value here causes illegal behavior1652// :85:22: error: use of undefined value here causes illegal behavior
1653// :85:22: note: when computing vector element at index '0'
1667// :85:22: error: use of undefined value here causes illegal behavior1654// :85:22: error: use of undefined value here causes illegal behavior
1655// :85:22: note: when computing vector element at index '0'
1668// :85:22: error: use of undefined value here causes illegal behavior1656// :85:22: error: use of undefined value here causes illegal behavior
1669// :85:22: note: when computing vector element at index '0'1657// :85:22: note: when computing vector element at index '0'
1670// :85:22: error: use of undefined value here causes illegal behavior1658// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1674,9 +1662,9 @@ const std = @import("std");...@@ -1674,9 +1662,9 @@ const std = @import("std");
1674// :85:22: error: use of undefined value here causes illegal behavior1662// :85:22: error: use of undefined value here causes illegal behavior
1675// :85:22: note: when computing vector element at index '0'1663// :85:22: note: when computing vector element at index '0'
1676// :85:22: error: use of undefined value here causes illegal behavior1664// :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'
1678// :85:22: error: use of undefined value here causes illegal behavior1666// :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'
1680// :85:22: error: use of undefined value here causes illegal behavior1668// :85:22: error: use of undefined value here causes illegal behavior
1681// :85:22: note: when computing vector element at index '0'1669// :85:22: note: when computing vector element at index '0'
1682// :85:22: error: use of undefined value here causes illegal behavior1670// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1686,7 +1674,9 @@ const std = @import("std");...@@ -1686,7 +1674,9 @@ const std = @import("std");
1686// :85:22: error: use of undefined value here causes illegal behavior1674// :85:22: error: use of undefined value here causes illegal behavior
1687// :85:22: note: when computing vector element at index '0'1675// :85:22: note: when computing vector element at index '0'
1688// :85:22: error: use of undefined value here causes illegal behavior1676// :85:22: error: use of undefined value here causes illegal behavior
1677// :85:22: note: when computing vector element at index '0'
1689// :85:22: error: use of undefined value here causes illegal behavior1678// :85:22: error: use of undefined value here causes illegal behavior
1679// :85:22: note: when computing vector element at index '0'
1690// :85:22: error: use of undefined value here causes illegal behavior1680// :85:22: error: use of undefined value here causes illegal behavior
1691// :85:22: note: when computing vector element at index '0'1681// :85:22: note: when computing vector element at index '0'
1692// :85:22: error: use of undefined value here causes illegal behavior1682// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1696,9 +1686,9 @@ const std = @import("std");...@@ -1696,9 +1686,9 @@ const std = @import("std");
1696// :85:22: error: use of undefined value here causes illegal behavior1686// :85:22: error: use of undefined value here causes illegal behavior
1697// :85:22: note: when computing vector element at index '0'1687// :85:22: note: when computing vector element at index '0'
1698// :85:22: error: use of undefined value here causes illegal behavior1688// :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'
1700// :85:22: error: use of undefined value here causes illegal behavior1690// :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'
1702// :85:22: error: use of undefined value here causes illegal behavior1692// :85:22: error: use of undefined value here causes illegal behavior
1703// :85:22: note: when computing vector element at index '0'1693// :85:22: note: when computing vector element at index '0'
1704// :85:22: error: use of undefined value here causes illegal behavior1694// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1708,7 +1698,9 @@ const std = @import("std");...@@ -1708,7 +1698,9 @@ const std = @import("std");
1708// :85:22: error: use of undefined value here causes illegal behavior1698// :85:22: error: use of undefined value here causes illegal behavior
1709// :85:22: note: when computing vector element at index '0'1699// :85:22: note: when computing vector element at index '0'
1710// :85:22: error: use of undefined value here causes illegal behavior1700// :85:22: error: use of undefined value here causes illegal behavior
1701// :85:22: note: when computing vector element at index '0'
1711// :85:22: error: use of undefined value here causes illegal behavior1702// :85:22: error: use of undefined value here causes illegal behavior
1703// :85:22: note: when computing vector element at index '0'
1712// :85:22: error: use of undefined value here causes illegal behavior1704// :85:22: error: use of undefined value here causes illegal behavior
1713// :85:22: note: when computing vector element at index '0'1705// :85:22: note: when computing vector element at index '0'
1714// :85:22: error: use of undefined value here causes illegal behavior1706// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1718,10 +1710,6 @@ const std = @import("std");...@@ -1718,10 +1710,6 @@ const std = @import("std");
1718// :85:22: error: use of undefined value here causes illegal behavior1710// :85:22: error: use of undefined value here causes illegal behavior
1719// :85:22: note: when computing vector element at index '0'1711// :85:22: note: when computing vector element at index '0'
1720// :85:22: error: use of undefined value here causes illegal behavior1712// :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
1725// :85:22: note: when computing vector element at index '0'1713// :85:22: note: when computing vector element at index '0'
1726// :85:22: error: use of undefined value here causes illegal behavior1714// :85:22: error: use of undefined value here causes illegal behavior
1727// :85:22: note: when computing vector element at index '0'1715// :85:22: note: when computing vector element at index '0'
...@@ -1730,8 +1718,6 @@ const std = @import("std");...@@ -1730,8 +1718,6 @@ const std = @import("std");
1730// :85:22: error: use of undefined value here causes illegal behavior1718// :85:22: error: use of undefined value here causes illegal behavior
1731// :85:22: note: when computing vector element at index '0'1719// :85:22: note: when computing vector element at index '0'
1732// :85:22: error: use of undefined value here causes illegal behavior1720// :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
1735// :85:22: note: when computing vector element at index '0'1721// :85:22: note: when computing vector element at index '0'
1736// :85:22: error: use of undefined value here causes illegal behavior1722// :85:22: error: use of undefined value here causes illegal behavior
1737// :85:22: note: when computing vector element at index '0'1723// :85:22: note: when computing vector element at index '0'
...@@ -1740,10 +1726,6 @@ const std = @import("std");...@@ -1740,10 +1726,6 @@ const std = @import("std");
1740// :85:22: error: use of undefined value here causes illegal behavior1726// :85:22: error: use of undefined value here causes illegal behavior
1741// :85:22: note: when computing vector element at index '0'1727// :85:22: note: when computing vector element at index '0'
1742// :85:22: error: use of undefined value here causes illegal behavior1728// :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
1747// :85:22: note: when computing vector element at index '0'1729// :85:22: note: when computing vector element at index '0'
1748// :85:22: error: use of undefined value here causes illegal behavior1730// :85:22: error: use of undefined value here causes illegal behavior
1749// :85:22: note: when computing vector element at index '0'1731// :85:22: note: when computing vector element at index '0'
...@@ -1752,7 +1734,9 @@ const std = @import("std");...@@ -1752,7 +1734,9 @@ const std = @import("std");
1752// :85:22: error: use of undefined value here causes illegal behavior1734// :85:22: error: use of undefined value here causes illegal behavior
1753// :85:22: note: when computing vector element at index '0'1735// :85:22: note: when computing vector element at index '0'
1754// :85:22: error: use of undefined value here causes illegal behavior1736// :85:22: error: use of undefined value here causes illegal behavior
1737// :85:22: note: when computing vector element at index '0'
1755// :85:22: error: use of undefined value here causes illegal behavior1738// :85:22: error: use of undefined value here causes illegal behavior
1739// :85:22: note: when computing vector element at index '0'
1756// :85:22: error: use of undefined value here causes illegal behavior1740// :85:22: error: use of undefined value here causes illegal behavior
1757// :85:22: note: when computing vector element at index '0'1741// :85:22: note: when computing vector element at index '0'
1758// :85:22: error: use of undefined value here causes illegal behavior1742// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1762,9 +1746,9 @@ const std = @import("std");...@@ -1762,9 +1746,9 @@ const std = @import("std");
1762// :85:22: error: use of undefined value here causes illegal behavior1746// :85:22: error: use of undefined value here causes illegal behavior
1763// :85:22: note: when computing vector element at index '0'1747// :85:22: note: when computing vector element at index '0'
1764// :85:22: error: use of undefined value here causes illegal behavior1748// :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'
1766// :85:22: error: use of undefined value here causes illegal behavior1750// :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'
1768// :85:22: error: use of undefined value here causes illegal behavior1752// :85:22: error: use of undefined value here causes illegal behavior
1769// :85:22: note: when computing vector element at index '0'1753// :85:22: note: when computing vector element at index '0'
1770// :85:22: error: use of undefined value here causes illegal behavior1754// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1774,7 +1758,9 @@ const std = @import("std");...@@ -1774,7 +1758,9 @@ const std = @import("std");
1774// :85:22: error: use of undefined value here causes illegal behavior1758// :85:22: error: use of undefined value here causes illegal behavior
1775// :85:22: note: when computing vector element at index '0'1759// :85:22: note: when computing vector element at index '0'
1776// :85:22: error: use of undefined value here causes illegal behavior1760// :85:22: error: use of undefined value here causes illegal behavior
1761// :85:22: note: when computing vector element at index '0'
1777// :85:22: error: use of undefined value here causes illegal behavior1762// :85:22: error: use of undefined value here causes illegal behavior
1763// :85:22: note: when computing vector element at index '0'
1778// :85:22: error: use of undefined value here causes illegal behavior1764// :85:22: error: use of undefined value here causes illegal behavior
1779// :85:22: note: when computing vector element at index '0'1765// :85:22: note: when computing vector element at index '0'
1780// :85:22: error: use of undefined value here causes illegal behavior1766// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1784,9 +1770,9 @@ const std = @import("std");...@@ -1784,9 +1770,9 @@ const std = @import("std");
1784// :85:22: error: use of undefined value here causes illegal behavior1770// :85:22: error: use of undefined value here causes illegal behavior
1785// :85:22: note: when computing vector element at index '0'1771// :85:22: note: when computing vector element at index '0'
1786// :85:22: error: use of undefined value here causes illegal behavior1772// :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'
1788// :85:22: error: use of undefined value here causes illegal behavior1774// :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'
1790// :85:22: error: use of undefined value here causes illegal behavior1776// :85:22: error: use of undefined value here causes illegal behavior
1791// :85:22: note: when computing vector element at index '0'1777// :85:22: note: when computing vector element at index '0'
1792// :85:22: error: use of undefined value here causes illegal behavior1778// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1796,7 +1782,9 @@ const std = @import("std");...@@ -1796,7 +1782,9 @@ const std = @import("std");
1796// :85:22: error: use of undefined value here causes illegal behavior1782// :85:22: error: use of undefined value here causes illegal behavior
1797// :85:22: note: when computing vector element at index '0'1783// :85:22: note: when computing vector element at index '0'
1798// :85:22: error: use of undefined value here causes illegal behavior1784// :85:22: error: use of undefined value here causes illegal behavior
1785// :85:22: note: when computing vector element at index '0'
1799// :85:22: error: use of undefined value here causes illegal behavior1786// :85:22: error: use of undefined value here causes illegal behavior
1787// :85:22: note: when computing vector element at index '0'
1800// :85:22: error: use of undefined value here causes illegal behavior1788// :85:22: error: use of undefined value here causes illegal behavior
1801// :85:22: note: when computing vector element at index '0'1789// :85:22: note: when computing vector element at index '0'
1802// :85:22: error: use of undefined value here causes illegal behavior1790// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1806,9 +1794,9 @@ const std = @import("std");...@@ -1806,9 +1794,9 @@ const std = @import("std");
1806// :85:22: error: use of undefined value here causes illegal behavior1794// :85:22: error: use of undefined value here causes illegal behavior
1807// :85:22: note: when computing vector element at index '0'1795// :85:22: note: when computing vector element at index '0'
1808// :85:22: error: use of undefined value here causes illegal behavior1796// :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'
1810// :85:22: error: use of undefined value here causes illegal behavior1798// :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'
1812// :85:22: error: use of undefined value here causes illegal behavior1800// :85:22: error: use of undefined value here causes illegal behavior
1813// :85:22: note: when computing vector element at index '0'1801// :85:22: note: when computing vector element at index '0'
1814// :85:22: error: use of undefined value here causes illegal behavior1802// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1818,7 +1806,9 @@ const std = @import("std");...@@ -1818,7 +1806,9 @@ const std = @import("std");
1818// :85:22: error: use of undefined value here causes illegal behavior1806// :85:22: error: use of undefined value here causes illegal behavior
1819// :85:22: note: when computing vector element at index '0'1807// :85:22: note: when computing vector element at index '0'
1820// :85:22: error: use of undefined value here causes illegal behavior1808// :85:22: error: use of undefined value here causes illegal behavior
1809// :85:22: note: when computing vector element at index '0'
1821// :85:22: error: use of undefined value here causes illegal behavior1810// :85:22: error: use of undefined value here causes illegal behavior
1811// :85:22: note: when computing vector element at index '0'
1822// :85:22: error: use of undefined value here causes illegal behavior1812// :85:22: error: use of undefined value here causes illegal behavior
1823// :85:22: note: when computing vector element at index '0'1813// :85:22: note: when computing vector element at index '0'
1824// :85:22: error: use of undefined value here causes illegal behavior1814// :85:22: error: use of undefined value here causes illegal behavior
...@@ -1832,35 +1822,45 @@ const std = @import("std");...@@ -1832,35 +1822,45 @@ const std = @import("std");
1832// :85:22: error: use of undefined value here causes illegal behavior1822// :85:22: error: use of undefined value here causes illegal behavior
1833// :85:22: note: when computing vector element at index '1'1823// :85:22: note: when computing vector element at index '1'
1834// :85:22: error: use of undefined value here causes illegal behavior1824// :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'
1836// :85:22: error: use of undefined value here causes illegal behavior1826// :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'
1838// :85:22: error: use of undefined value here causes illegal behavior1828// :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'
1840// :85:22: error: use of undefined value here causes illegal behavior1830// :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'
1842// :85:22: error: use of undefined value here causes illegal behavior1832// :85:22: error: use of undefined value here causes illegal behavior
1833// :85:22: note: when computing vector element at index '1'
1843// :85:22: error: use of undefined value here causes illegal behavior1834// :85:22: error: use of undefined value here causes illegal behavior
1835// :85:22: note: when computing vector element at index '1'
1844// :85:22: error: use of undefined value here causes illegal behavior1836// :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'
1846// :85:22: error: use of undefined value here causes illegal behavior1838// :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'
1848// :85:22: error: use of undefined value here causes illegal behavior1840// :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'
1850// :85:22: error: use of undefined value here causes illegal behavior1842// :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'
1852// :85:22: error: use of undefined value here causes illegal behavior1844// :85:22: error: use of undefined value here causes illegal behavior
1853// :85:22: note: when computing vector element at index '1'1845// :85:22: note: when computing vector element at index '1'
1854// :85:22: error: use of undefined value here causes illegal behavior1846// :85:22: error: use of undefined value here causes illegal behavior
1855// :85:22: note: when computing vector element at index '1'1847// :85:22: note: when computing vector element at index '1'
1856// :85:22: error: use of undefined value here causes illegal behavior1848// :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'
1858// :85:22: error: use of undefined value here causes illegal behavior1850// :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'
1860// :85:22: error: use of undefined value here causes illegal behavior1852// :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'
1862// :85:22: error: use of undefined value here causes illegal behavior1854// :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'
1864// :85:25: error: use of undefined value here causes illegal behavior1864// :85:25: error: use of undefined value here causes illegal behavior
1865// :85:25: note: when computing vector element at index '0'1865// :85:25: note: when computing vector element at index '0'
1866// :85:25: error: use of undefined value here causes illegal behavior1866// :85:25: error: use of undefined value here causes illegal behavior
...@@ -1908,50 +1908,30 @@ const std = @import("std");...@@ -1908,50 +1908,30 @@ const std = @import("std");
1908// :89:22: error: use of undefined value here causes illegal behavior1908// :89:22: error: use of undefined value here causes illegal behavior
1909// :89:22: error: use of undefined value here causes illegal behavior1909// :89:22: error: use of undefined value here causes illegal behavior
1910// :89:22: error: use of undefined value here causes illegal behavior1910// :89:22: error: use of undefined value here causes illegal behavior
1911// :89:22: note: when computing vector element at index '0'
1912// :89:22: error: use of undefined value here causes illegal behavior1911// :89:22: error: use of undefined value here causes illegal behavior
1913// :89:22: note: when computing vector element at index '0'
1914// :89:22: error: use of undefined value here causes illegal behavior1912// :89:22: error: use of undefined value here causes illegal behavior
1915// :89:22: note: when computing vector element at index '0'
1916// :89:22: error: use of undefined value here causes illegal behavior1913// :89:22: error: use of undefined value here causes illegal behavior
1917// :89:22: note: when computing vector element at index '0'
1918// :89:22: error: use of undefined value here causes illegal behavior1914// :89:22: error: use of undefined value here causes illegal behavior
1919// :89:22: note: when computing vector element at index '1'
1920// :89:22: error: use of undefined value here causes illegal behavior1915// :89:22: error: use of undefined value here causes illegal behavior
1921// :89:22: note: when computing vector element at index '1'
1922// :89:22: error: use of undefined value here causes illegal behavior1916// :89:22: error: use of undefined value here causes illegal behavior
1923// :89:22: note: when computing vector element at index '0'
1924// :89:22: error: use of undefined value here causes illegal behavior1917// :89:22: error: use of undefined value here causes illegal behavior
1925// :89:22: note: when computing vector element at index '0'
1926// :89:22: error: use of undefined value here causes illegal behavior1918// :89:22: error: use of undefined value here causes illegal behavior
1927// :89:22: note: when computing vector element at index '0'
1928// :89:22: error: use of undefined value here causes illegal behavior1919// :89:22: error: use of undefined value here causes illegal behavior
1929// :89:22: note: when computing vector element at index '0'
1930// :89:22: error: use of undefined value here causes illegal behavior1920// :89:22: error: use of undefined value here causes illegal behavior
1931// :89:22: error: use of undefined value here causes illegal behavior1921// :89:22: error: use of undefined value here causes illegal behavior
1932// :89:22: error: use of undefined value here causes illegal behavior1922// :89:22: error: use of undefined value here causes illegal behavior
1933// :89:22: note: when computing vector element at index '0'
1934// :89:22: error: use of undefined value here causes illegal behavior1923// :89:22: error: use of undefined value here causes illegal behavior
1935// :89:22: note: when computing vector element at index '0'
1936// :89:22: error: use of undefined value here causes illegal behavior1924// :89:22: error: use of undefined value here causes illegal behavior
1937// :89:22: note: when computing vector element at index '0'
1938// :89:22: error: use of undefined value here causes illegal behavior1925// :89:22: error: use of undefined value here causes illegal behavior
1939// :89:22: note: when computing vector element at index '0'
1940// :89:22: error: use of undefined value here causes illegal behavior1926// :89:22: error: use of undefined value here causes illegal behavior
1941// :89:22: note: when computing vector element at index '1'
1942// :89:22: error: use of undefined value here causes illegal behavior1927// :89:22: error: use of undefined value here causes illegal behavior
1943// :89:22: note: when computing vector element at index '1'
1944// :89:22: error: use of undefined value here causes illegal behavior1928// :89:22: error: use of undefined value here causes illegal behavior
1945// :89:22: note: when computing vector element at index '0'
1946// :89:22: error: use of undefined value here causes illegal behavior1929// :89:22: error: use of undefined value here causes illegal behavior
1947// :89:22: note: when computing vector element at index '0'
1948// :89:22: error: use of undefined value here causes illegal behavior1930// :89:22: error: use of undefined value here causes illegal behavior
1949// :89:22: note: when computing vector element at index '0'1931// :89:22: note: when computing vector element at index '0'
1950// :89:22: error: use of undefined value here causes illegal behavior1932// :89:22: error: use of undefined value here causes illegal behavior
1951// :89:22: note: when computing vector element at index '0'1933// :89:22: note: when computing vector element at index '0'
1952// :89:22: error: use of undefined value here causes illegal behavior1934// :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
1955// :89:22: note: when computing vector element at index '0'1935// :89:22: note: when computing vector element at index '0'
1956// :89:22: error: use of undefined value here causes illegal behavior1936// :89:22: error: use of undefined value here causes illegal behavior
1957// :89:22: note: when computing vector element at index '0'1937// :89:22: note: when computing vector element at index '0'
...@@ -1960,10 +1940,6 @@ const std = @import("std");...@@ -1960,10 +1940,6 @@ const std = @import("std");
1960// :89:22: error: use of undefined value here causes illegal behavior1940// :89:22: error: use of undefined value here causes illegal behavior
1961// :89:22: note: when computing vector element at index '0'1941// :89:22: note: when computing vector element at index '0'
1962// :89:22: error: use of undefined value here causes illegal behavior1942// :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
1967// :89:22: note: when computing vector element at index '0'1943// :89:22: note: when computing vector element at index '0'
1968// :89:22: error: use of undefined value here causes illegal behavior1944// :89:22: error: use of undefined value here causes illegal behavior
1969// :89:22: note: when computing vector element at index '0'1945// :89:22: note: when computing vector element at index '0'
...@@ -1972,7 +1948,9 @@ const std = @import("std");...@@ -1972,7 +1948,9 @@ const std = @import("std");
1972// :89:22: error: use of undefined value here causes illegal behavior1948// :89:22: error: use of undefined value here causes illegal behavior
1973// :89:22: note: when computing vector element at index '0'1949// :89:22: note: when computing vector element at index '0'
1974// :89:22: error: use of undefined value here causes illegal behavior1950// :89:22: error: use of undefined value here causes illegal behavior
1951// :89:22: note: when computing vector element at index '0'
1975// :89:22: error: use of undefined value here causes illegal behavior1952// :89:22: error: use of undefined value here causes illegal behavior
1953// :89:22: note: when computing vector element at index '0'
1976// :89:22: error: use of undefined value here causes illegal behavior1954// :89:22: error: use of undefined value here causes illegal behavior
1977// :89:22: note: when computing vector element at index '0'1955// :89:22: note: when computing vector element at index '0'
1978// :89:22: error: use of undefined value here causes illegal behavior1956// :89:22: error: use of undefined value here causes illegal behavior
...@@ -1982,9 +1960,9 @@ const std = @import("std");...@@ -1982,9 +1960,9 @@ const std = @import("std");
1982// :89:22: error: use of undefined value here causes illegal behavior1960// :89:22: error: use of undefined value here causes illegal behavior
1983// :89:22: note: when computing vector element at index '0'1961// :89:22: note: when computing vector element at index '0'
1984// :89:22: error: use of undefined value here causes illegal behavior1962// :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'
1986// :89:22: error: use of undefined value here causes illegal behavior1964// :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'
1988// :89:22: error: use of undefined value here causes illegal behavior1966// :89:22: error: use of undefined value here causes illegal behavior
1989// :89:22: note: when computing vector element at index '0'1967// :89:22: note: when computing vector element at index '0'
1990// :89:22: error: use of undefined value here causes illegal behavior1968// :89:22: error: use of undefined value here causes illegal behavior
...@@ -1994,7 +1972,9 @@ const std = @import("std");...@@ -1994,7 +1972,9 @@ const std = @import("std");
1994// :89:22: error: use of undefined value here causes illegal behavior1972// :89:22: error: use of undefined value here causes illegal behavior
1995// :89:22: note: when computing vector element at index '0'1973// :89:22: note: when computing vector element at index '0'
1996// :89:22: error: use of undefined value here causes illegal behavior1974// :89:22: error: use of undefined value here causes illegal behavior
1975// :89:22: note: when computing vector element at index '0'
1997// :89:22: error: use of undefined value here causes illegal behavior1976// :89:22: error: use of undefined value here causes illegal behavior
1977// :89:22: note: when computing vector element at index '0'
1998// :89:22: error: use of undefined value here causes illegal behavior1978// :89:22: error: use of undefined value here causes illegal behavior
1999// :89:22: note: when computing vector element at index '0'1979// :89:22: note: when computing vector element at index '0'
2000// :89:22: error: use of undefined value here causes illegal behavior1980// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2004,9 +1984,9 @@ const std = @import("std");...@@ -2004,9 +1984,9 @@ const std = @import("std");
2004// :89:22: error: use of undefined value here causes illegal behavior1984// :89:22: error: use of undefined value here causes illegal behavior
2005// :89:22: note: when computing vector element at index '0'1985// :89:22: note: when computing vector element at index '0'
2006// :89:22: error: use of undefined value here causes illegal behavior1986// :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'
2008// :89:22: error: use of undefined value here causes illegal behavior1988// :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'
2010// :89:22: error: use of undefined value here causes illegal behavior1990// :89:22: error: use of undefined value here causes illegal behavior
2011// :89:22: note: when computing vector element at index '0'1991// :89:22: note: when computing vector element at index '0'
2012// :89:22: error: use of undefined value here causes illegal behavior1992// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2016,7 +1996,9 @@ const std = @import("std");...@@ -2016,7 +1996,9 @@ const std = @import("std");
2016// :89:22: error: use of undefined value here causes illegal behavior1996// :89:22: error: use of undefined value here causes illegal behavior
2017// :89:22: note: when computing vector element at index '0'1997// :89:22: note: when computing vector element at index '0'
2018// :89:22: error: use of undefined value here causes illegal behavior1998// :89:22: error: use of undefined value here causes illegal behavior
1999// :89:22: note: when computing vector element at index '0'
2019// :89:22: error: use of undefined value here causes illegal behavior2000// :89:22: error: use of undefined value here causes illegal behavior
2001// :89:22: note: when computing vector element at index '0'
2020// :89:22: error: use of undefined value here causes illegal behavior2002// :89:22: error: use of undefined value here causes illegal behavior
2021// :89:22: note: when computing vector element at index '0'2003// :89:22: note: when computing vector element at index '0'
2022// :89:22: error: use of undefined value here causes illegal behavior2004// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2026,9 +2008,9 @@ const std = @import("std");...@@ -2026,9 +2008,9 @@ const std = @import("std");
2026// :89:22: error: use of undefined value here causes illegal behavior2008// :89:22: error: use of undefined value here causes illegal behavior
2027// :89:22: note: when computing vector element at index '0'2009// :89:22: note: when computing vector element at index '0'
2028// :89:22: error: use of undefined value here causes illegal behavior2010// :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'
2030// :89:22: error: use of undefined value here causes illegal behavior2012// :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'
2032// :89:22: error: use of undefined value here causes illegal behavior2014// :89:22: error: use of undefined value here causes illegal behavior
2033// :89:22: note: when computing vector element at index '0'2015// :89:22: note: when computing vector element at index '0'
2034// :89:22: error: use of undefined value here causes illegal behavior2016// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2038,7 +2020,9 @@ const std = @import("std");...@@ -2038,7 +2020,9 @@ const std = @import("std");
2038// :89:22: error: use of undefined value here causes illegal behavior2020// :89:22: error: use of undefined value here causes illegal behavior
2039// :89:22: note: when computing vector element at index '0'2021// :89:22: note: when computing vector element at index '0'
2040// :89:22: error: use of undefined value here causes illegal behavior2022// :89:22: error: use of undefined value here causes illegal behavior
2023// :89:22: note: when computing vector element at index '0'
2041// :89:22: error: use of undefined value here causes illegal behavior2024// :89:22: error: use of undefined value here causes illegal behavior
2025// :89:22: note: when computing vector element at index '0'
2042// :89:22: error: use of undefined value here causes illegal behavior2026// :89:22: error: use of undefined value here causes illegal behavior
2043// :89:22: note: when computing vector element at index '0'2027// :89:22: note: when computing vector element at index '0'
2044// :89:22: error: use of undefined value here causes illegal behavior2028// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2048,9 +2032,9 @@ const std = @import("std");...@@ -2048,9 +2032,9 @@ const std = @import("std");
2048// :89:22: error: use of undefined value here causes illegal behavior2032// :89:22: error: use of undefined value here causes illegal behavior
2049// :89:22: note: when computing vector element at index '0'2033// :89:22: note: when computing vector element at index '0'
2050// :89:22: error: use of undefined value here causes illegal behavior2034// :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'
2052// :89:22: error: use of undefined value here causes illegal behavior2036// :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'
2054// :89:22: error: use of undefined value here causes illegal behavior2038// :89:22: error: use of undefined value here causes illegal behavior
2055// :89:22: note: when computing vector element at index '0'2039// :89:22: note: when computing vector element at index '0'
2056// :89:22: error: use of undefined value here causes illegal behavior2040// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2060,7 +2044,9 @@ const std = @import("std");...@@ -2060,7 +2044,9 @@ const std = @import("std");
2060// :89:22: error: use of undefined value here causes illegal behavior2044// :89:22: error: use of undefined value here causes illegal behavior
2061// :89:22: note: when computing vector element at index '0'2045// :89:22: note: when computing vector element at index '0'
2062// :89:22: error: use of undefined value here causes illegal behavior2046// :89:22: error: use of undefined value here causes illegal behavior
2047// :89:22: note: when computing vector element at index '0'
2063// :89:22: error: use of undefined value here causes illegal behavior2048// :89:22: error: use of undefined value here causes illegal behavior
2049// :89:22: note: when computing vector element at index '0'
2064// :89:22: error: use of undefined value here causes illegal behavior2050// :89:22: error: use of undefined value here causes illegal behavior
2065// :89:22: note: when computing vector element at index '0'2051// :89:22: note: when computing vector element at index '0'
2066// :89:22: error: use of undefined value here causes illegal behavior2052// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2070,9 +2056,9 @@ const std = @import("std");...@@ -2070,9 +2056,9 @@ const std = @import("std");
2070// :89:22: error: use of undefined value here causes illegal behavior2056// :89:22: error: use of undefined value here causes illegal behavior
2071// :89:22: note: when computing vector element at index '0'2057// :89:22: note: when computing vector element at index '0'
2072// :89:22: error: use of undefined value here causes illegal behavior2058// :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'
2074// :89:22: error: use of undefined value here causes illegal behavior2060// :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'
2076// :89:22: error: use of undefined value here causes illegal behavior2062// :89:22: error: use of undefined value here causes illegal behavior
2077// :89:22: note: when computing vector element at index '0'2063// :89:22: note: when computing vector element at index '0'
2078// :89:22: error: use of undefined value here causes illegal behavior2064// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2082,7 +2068,9 @@ const std = @import("std");...@@ -2082,7 +2068,9 @@ const std = @import("std");
2082// :89:22: error: use of undefined value here causes illegal behavior2068// :89:22: error: use of undefined value here causes illegal behavior
2083// :89:22: note: when computing vector element at index '0'2069// :89:22: note: when computing vector element at index '0'
2084// :89:22: error: use of undefined value here causes illegal behavior2070// :89:22: error: use of undefined value here causes illegal behavior
2071// :89:22: note: when computing vector element at index '0'
2085// :89:22: error: use of undefined value here causes illegal behavior2072// :89:22: error: use of undefined value here causes illegal behavior
2073// :89:22: note: when computing vector element at index '0'
2086// :89:22: error: use of undefined value here causes illegal behavior2074// :89:22: error: use of undefined value here causes illegal behavior
2087// :89:22: note: when computing vector element at index '0'2075// :89:22: note: when computing vector element at index '0'
2088// :89:22: error: use of undefined value here causes illegal behavior2076// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2092,9 +2080,9 @@ const std = @import("std");...@@ -2092,9 +2080,9 @@ const std = @import("std");
2092// :89:22: error: use of undefined value here causes illegal behavior2080// :89:22: error: use of undefined value here causes illegal behavior
2093// :89:22: note: when computing vector element at index '0'2081// :89:22: note: when computing vector element at index '0'
2094// :89:22: error: use of undefined value here causes illegal behavior2082// :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'
2096// :89:22: error: use of undefined value here causes illegal behavior2084// :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'
2098// :89:22: error: use of undefined value here causes illegal behavior2086// :89:22: error: use of undefined value here causes illegal behavior
2099// :89:22: note: when computing vector element at index '0'2087// :89:22: note: when computing vector element at index '0'
2100// :89:22: error: use of undefined value here causes illegal behavior2088// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2104,7 +2092,9 @@ const std = @import("std");...@@ -2104,7 +2092,9 @@ const std = @import("std");
2104// :89:22: error: use of undefined value here causes illegal behavior2092// :89:22: error: use of undefined value here causes illegal behavior
2105// :89:22: note: when computing vector element at index '0'2093// :89:22: note: when computing vector element at index '0'
2106// :89:22: error: use of undefined value here causes illegal behavior2094// :89:22: error: use of undefined value here causes illegal behavior
2095// :89:22: note: when computing vector element at index '0'
2107// :89:22: error: use of undefined value here causes illegal behavior2096// :89:22: error: use of undefined value here causes illegal behavior
2097// :89:22: note: when computing vector element at index '0'
2108// :89:22: error: use of undefined value here causes illegal behavior2098// :89:22: error: use of undefined value here causes illegal behavior
2109// :89:22: note: when computing vector element at index '0'2099// :89:22: note: when computing vector element at index '0'
2110// :89:22: error: use of undefined value here causes illegal behavior2100// :89:22: error: use of undefined value here causes illegal behavior
...@@ -2118,35 +2108,45 @@ const std = @import("std");...@@ -2118,35 +2108,45 @@ const std = @import("std");
2118// :89:22: error: use of undefined value here causes illegal behavior2108// :89:22: error: use of undefined value here causes illegal behavior
2119// :89:22: note: when computing vector element at index '1'2109// :89:22: note: when computing vector element at index '1'
2120// :89:22: error: use of undefined value here causes illegal behavior2110// :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'
2122// :89:22: error: use of undefined value here causes illegal behavior2112// :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'
2124// :89:22: error: use of undefined value here causes illegal behavior2114// :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'
2126// :89:22: error: use of undefined value here causes illegal behavior2116// :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'
2128// :89:22: error: use of undefined value here causes illegal behavior2118// :89:22: error: use of undefined value here causes illegal behavior
2119// :89:22: note: when computing vector element at index '1'
2129// :89:22: error: use of undefined value here causes illegal behavior2120// :89:22: error: use of undefined value here causes illegal behavior
2121// :89:22: note: when computing vector element at index '1'
2130// :89:22: error: use of undefined value here causes illegal behavior2122// :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'
2132// :89:22: error: use of undefined value here causes illegal behavior2124// :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'
2134// :89:22: error: use of undefined value here causes illegal behavior2126// :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'
2136// :89:22: error: use of undefined value here causes illegal behavior2128// :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'
2138// :89:22: error: use of undefined value here causes illegal behavior2130// :89:22: error: use of undefined value here causes illegal behavior
2139// :89:22: note: when computing vector element at index '1'2131// :89:22: note: when computing vector element at index '1'
2140// :89:22: error: use of undefined value here causes illegal behavior2132// :89:22: error: use of undefined value here causes illegal behavior
2141// :89:22: note: when computing vector element at index '1'2133// :89:22: note: when computing vector element at index '1'
2142// :89:22: error: use of undefined value here causes illegal behavior2134// :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'
2144// :89:22: error: use of undefined value here causes illegal behavior2136// :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'
2146// :89:22: error: use of undefined value here causes illegal behavior2138// :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'
2148// :89:22: error: use of undefined value here causes illegal behavior2140// :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'
2150// :89:25: error: use of undefined value here causes illegal behavior2150// :89:25: error: use of undefined value here causes illegal behavior
2151// :89:25: note: when computing vector element at index '0'2151// :89:25: note: when computing vector element at index '0'
2152// :89:25: error: use of undefined value here causes illegal behavior2152// :89:25: error: use of undefined value here causes illegal behavior
...@@ -2198,21 +2198,13 @@ const std = @import("std");...@@ -2198,21 +2198,13 @@ const std = @import("std");
2198// :95:17: error: use of undefined value here causes illegal behavior2198// :95:17: error: use of undefined value here causes illegal behavior
2199// :95:17: error: use of undefined value here causes illegal behavior2199// :95:17: error: use of undefined value here causes illegal behavior
2200// :95:17: error: use of undefined value here causes illegal behavior2200// :95:17: error: use of undefined value here causes illegal behavior
2201// :95:17: note: when computing vector element at index '1'
2202// :95:17: error: use of undefined value here causes illegal behavior2201// :95:17: error: use of undefined value here causes illegal behavior
2203// :95:17: note: when computing vector element at index '1'
2204// :95:17: error: use of undefined value here causes illegal behavior2202// :95:17: error: use of undefined value here causes illegal behavior
2205// :95:17: note: when computing vector element at index '1'
2206// :95:17: error: use of undefined value here causes illegal behavior2203// :95:17: error: use of undefined value here causes illegal behavior
2207// :95:17: note: when computing vector element at index '1'
2208// :95:17: error: use of undefined value here causes illegal behavior2204// :95:17: error: use of undefined value here causes illegal behavior
2209// :95:17: note: when computing vector element at index '0'
2210// :95:17: error: use of undefined value here causes illegal behavior2205// :95:17: error: use of undefined value here causes illegal behavior
2211// :95:17: note: when computing vector element at index '0'
2212// :95:17: error: use of undefined value here causes illegal behavior2206// :95:17: error: use of undefined value here causes illegal behavior
2213// :95:17: note: when computing vector element at index '0'
2214// :95:17: error: use of undefined value here causes illegal behavior2207// :95:17: error: use of undefined value here causes illegal behavior
2215// :95:17: note: when computing vector element at index '0'
2216// :95:17: error: use of undefined value here causes illegal behavior2208// :95:17: error: use of undefined value here causes illegal behavior
2217// :95:17: error: use of undefined value here causes illegal behavior2209// :95:17: error: use of undefined value here causes illegal behavior
2218// :95:17: error: use of undefined value here causes illegal behavior2210// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2220,21 +2212,13 @@ const std = @import("std");...@@ -2220,21 +2212,13 @@ const std = @import("std");
2220// :95:17: error: use of undefined value here causes illegal behavior2212// :95:17: error: use of undefined value here causes illegal behavior
2221// :95:17: error: use of undefined value here causes illegal behavior2213// :95:17: error: use of undefined value here causes illegal behavior
2222// :95:17: error: use of undefined value here causes illegal behavior2214// :95:17: error: use of undefined value here causes illegal behavior
2223// :95:17: note: when computing vector element at index '1'
2224// :95:17: error: use of undefined value here causes illegal behavior2215// :95:17: error: use of undefined value here causes illegal behavior
2225// :95:17: note: when computing vector element at index '1'
2226// :95:17: error: use of undefined value here causes illegal behavior2216// :95:17: error: use of undefined value here causes illegal behavior
2227// :95:17: note: when computing vector element at index '1'
2228// :95:17: error: use of undefined value here causes illegal behavior2217// :95:17: error: use of undefined value here causes illegal behavior
2229// :95:17: note: when computing vector element at index '1'
2230// :95:17: error: use of undefined value here causes illegal behavior2218// :95:17: error: use of undefined value here causes illegal behavior
2231// :95:17: note: when computing vector element at index '0'
2232// :95:17: error: use of undefined value here causes illegal behavior2219// :95:17: error: use of undefined value here causes illegal behavior
2233// :95:17: note: when computing vector element at index '0'
2234// :95:17: error: use of undefined value here causes illegal behavior2220// :95:17: error: use of undefined value here causes illegal behavior
2235// :95:17: note: when computing vector element at index '0'
2236// :95:17: error: use of undefined value here causes illegal behavior2221// :95:17: error: use of undefined value here causes illegal behavior
2237// :95:17: note: when computing vector element at index '0'
2238// :95:17: error: use of undefined value here causes illegal behavior2222// :95:17: error: use of undefined value here causes illegal behavior
2239// :95:17: error: use of undefined value here causes illegal behavior2223// :95:17: error: use of undefined value here causes illegal behavior
2240// :95:17: error: use of undefined value here causes illegal behavior2224// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2242,21 +2226,13 @@ const std = @import("std");...@@ -2242,21 +2226,13 @@ const std = @import("std");
2242// :95:17: error: use of undefined value here causes illegal behavior2226// :95:17: error: use of undefined value here causes illegal behavior
2243// :95:17: error: use of undefined value here causes illegal behavior2227// :95:17: error: use of undefined value here causes illegal behavior
2244// :95:17: error: use of undefined value here causes illegal behavior2228// :95:17: error: use of undefined value here causes illegal behavior
2245// :95:17: note: when computing vector element at index '1'
2246// :95:17: error: use of undefined value here causes illegal behavior2229// :95:17: error: use of undefined value here causes illegal behavior
2247// :95:17: note: when computing vector element at index '1'
2248// :95:17: error: use of undefined value here causes illegal behavior2230// :95:17: error: use of undefined value here causes illegal behavior
2249// :95:17: note: when computing vector element at index '1'
2250// :95:17: error: use of undefined value here causes illegal behavior2231// :95:17: error: use of undefined value here causes illegal behavior
2251// :95:17: note: when computing vector element at index '1'
2252// :95:17: error: use of undefined value here causes illegal behavior2232// :95:17: error: use of undefined value here causes illegal behavior
2253// :95:17: note: when computing vector element at index '0'
2254// :95:17: error: use of undefined value here causes illegal behavior2233// :95:17: error: use of undefined value here causes illegal behavior
2255// :95:17: note: when computing vector element at index '0'
2256// :95:17: error: use of undefined value here causes illegal behavior2234// :95:17: error: use of undefined value here causes illegal behavior
2257// :95:17: note: when computing vector element at index '0'
2258// :95:17: error: use of undefined value here causes illegal behavior2235// :95:17: error: use of undefined value here causes illegal behavior
2259// :95:17: note: when computing vector element at index '0'
2260// :95:17: error: use of undefined value here causes illegal behavior2236// :95:17: error: use of undefined value here causes illegal behavior
2261// :95:17: error: use of undefined value here causes illegal behavior2237// :95:17: error: use of undefined value here causes illegal behavior
2262// :95:17: error: use of undefined value here causes illegal behavior2238// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2264,21 +2240,13 @@ const std = @import("std");...@@ -2264,21 +2240,13 @@ const std = @import("std");
2264// :95:17: error: use of undefined value here causes illegal behavior2240// :95:17: error: use of undefined value here causes illegal behavior
2265// :95:17: error: use of undefined value here causes illegal behavior2241// :95:17: error: use of undefined value here causes illegal behavior
2266// :95:17: error: use of undefined value here causes illegal behavior2242// :95:17: error: use of undefined value here causes illegal behavior
2267// :95:17: note: when computing vector element at index '1'
2268// :95:17: error: use of undefined value here causes illegal behavior2243// :95:17: error: use of undefined value here causes illegal behavior
2269// :95:17: note: when computing vector element at index '1'
2270// :95:17: error: use of undefined value here causes illegal behavior2244// :95:17: error: use of undefined value here causes illegal behavior
2271// :95:17: note: when computing vector element at index '1'
2272// :95:17: error: use of undefined value here causes illegal behavior2245// :95:17: error: use of undefined value here causes illegal behavior
2273// :95:17: note: when computing vector element at index '1'
2274// :95:17: error: use of undefined value here causes illegal behavior2246// :95:17: error: use of undefined value here causes illegal behavior
2275// :95:17: note: when computing vector element at index '0'
2276// :95:17: error: use of undefined value here causes illegal behavior2247// :95:17: error: use of undefined value here causes illegal behavior
2277// :95:17: note: when computing vector element at index '0'
2278// :95:17: error: use of undefined value here causes illegal behavior2248// :95:17: error: use of undefined value here causes illegal behavior
2279// :95:17: note: when computing vector element at index '0'
2280// :95:17: error: use of undefined value here causes illegal behavior2249// :95:17: error: use of undefined value here causes illegal behavior
2281// :95:17: note: when computing vector element at index '0'
2282// :95:17: error: use of undefined value here causes illegal behavior2250// :95:17: error: use of undefined value here causes illegal behavior
2283// :95:17: error: use of undefined value here causes illegal behavior2251// :95:17: error: use of undefined value here causes illegal behavior
2284// :95:17: error: use of undefined value here causes illegal behavior2252// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2286,13 +2254,9 @@ const std = @import("std");...@@ -2286,13 +2254,9 @@ const std = @import("std");
2286// :95:17: error: use of undefined value here causes illegal behavior2254// :95:17: error: use of undefined value here causes illegal behavior
2287// :95:17: error: use of undefined value here causes illegal behavior2255// :95:17: error: use of undefined value here causes illegal behavior
2288// :95:17: error: use of undefined value here causes illegal behavior2256// :95:17: error: use of undefined value here causes illegal behavior
2289// :95:17: note: when computing vector element at index '1'
2290// :95:17: error: use of undefined value here causes illegal behavior2257// :95:17: error: use of undefined value here causes illegal behavior
2291// :95:17: note: when computing vector element at index '1'
2292// :95:17: error: use of undefined value here causes illegal behavior2258// :95:17: error: use of undefined value here causes illegal behavior
2293// :95:17: note: when computing vector element at index '1'
2294// :95:17: error: use of undefined value here causes illegal behavior2259// :95:17: error: use of undefined value here causes illegal behavior
2295// :95:17: note: when computing vector element at index '1'
2296// :95:17: error: use of undefined value here causes illegal behavior2260// :95:17: error: use of undefined value here causes illegal behavior
2297// :95:17: note: when computing vector element at index '0'2261// :95:17: note: when computing vector element at index '0'
2298// :95:17: error: use of undefined value here causes illegal behavior2262// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2302,19 +2266,21 @@ const std = @import("std");...@@ -2302,19 +2266,21 @@ const std = @import("std");
2302// :95:17: error: use of undefined value here causes illegal behavior2266// :95:17: error: use of undefined value here causes illegal behavior
2303// :95:17: note: when computing vector element at index '0'2267// :95:17: note: when computing vector element at index '0'
2304// :95:17: error: use of undefined value here causes illegal behavior2268// :95:17: error: use of undefined value here causes illegal behavior
2269// :95:17: note: when computing vector element at index '0'
2305// :95:17: error: use of undefined value here causes illegal behavior2270// :95:17: error: use of undefined value here causes illegal behavior
2271// :95:17: note: when computing vector element at index '0'
2306// :95:17: error: use of undefined value here causes illegal behavior2272// :95:17: error: use of undefined value here causes illegal behavior
2273// :95:17: note: when computing vector element at index '0'
2307// :95:17: error: use of undefined value here causes illegal behavior2274// :95:17: error: use of undefined value here causes illegal behavior
2275// :95:17: note: when computing vector element at index '0'
2308// :95:17: error: use of undefined value here causes illegal behavior2276// :95:17: error: use of undefined value here causes illegal behavior
2277// :95:17: note: when computing vector element at index '0'
2309// :95:17: error: use of undefined value here causes illegal behavior2278// :95:17: error: use of undefined value here causes illegal behavior
2279// :95:17: note: when computing vector element at index '0'
2310// :95:17: error: use of undefined value here causes illegal behavior2280// :95:17: error: use of undefined value here causes illegal behavior
2311// :95:17: note: when computing vector element at index '1'2281// :95:17: note: when computing vector element at index '0'
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'
2316// :95:17: error: use of undefined value here causes illegal behavior2282// :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'
2318// :95:17: error: use of undefined value here causes illegal behavior2284// :95:17: error: use of undefined value here causes illegal behavior
2319// :95:17: note: when computing vector element at index '0'2285// :95:17: note: when computing vector element at index '0'
2320// :95:17: error: use of undefined value here causes illegal behavior2286// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2324,19 +2290,25 @@ const std = @import("std");...@@ -2324,19 +2290,25 @@ const std = @import("std");
2324// :95:17: error: use of undefined value here causes illegal behavior2290// :95:17: error: use of undefined value here causes illegal behavior
2325// :95:17: note: when computing vector element at index '0'2291// :95:17: note: when computing vector element at index '0'
2326// :95:17: error: use of undefined value here causes illegal behavior2292// :95:17: error: use of undefined value here causes illegal behavior
2293// :95:17: note: when computing vector element at index '0'
2327// :95:17: error: use of undefined value here causes illegal behavior2294// :95:17: error: use of undefined value here causes illegal behavior
2295// :95:17: note: when computing vector element at index '0'
2328// :95:17: error: use of undefined value here causes illegal behavior2296// :95:17: error: use of undefined value here causes illegal behavior
2297// :95:17: note: when computing vector element at index '0'
2329// :95:17: error: use of undefined value here causes illegal behavior2298// :95:17: error: use of undefined value here causes illegal behavior
2299// :95:17: note: when computing vector element at index '0'
2330// :95:17: error: use of undefined value here causes illegal behavior2300// :95:17: error: use of undefined value here causes illegal behavior
2301// :95:17: note: when computing vector element at index '0'
2331// :95:17: error: use of undefined value here causes illegal behavior2302// :95:17: error: use of undefined value here causes illegal behavior
2303// :95:17: note: when computing vector element at index '0'
2332// :95:17: error: use of undefined value here causes illegal behavior2304// :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'
2334// :95:17: error: use of undefined value here causes illegal behavior2306// :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'
2336// :95:17: error: use of undefined value here causes illegal behavior2308// :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'
2338// :95:17: error: use of undefined value here causes illegal behavior2310// :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'
2340// :95:17: error: use of undefined value here causes illegal behavior2312// :95:17: error: use of undefined value here causes illegal behavior
2341// :95:17: note: when computing vector element at index '0'2313// :95:17: note: when computing vector element at index '0'
2342// :95:17: error: use of undefined value here causes illegal behavior2314// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2346,19 +2318,25 @@ const std = @import("std");...@@ -2346,19 +2318,25 @@ const std = @import("std");
2346// :95:17: error: use of undefined value here causes illegal behavior2318// :95:17: error: use of undefined value here causes illegal behavior
2347// :95:17: note: when computing vector element at index '0'2319// :95:17: note: when computing vector element at index '0'
2348// :95:17: error: use of undefined value here causes illegal behavior2320// :95:17: error: use of undefined value here causes illegal behavior
2321// :95:17: note: when computing vector element at index '0'
2349// :95:17: error: use of undefined value here causes illegal behavior2322// :95:17: error: use of undefined value here causes illegal behavior
2323// :95:17: note: when computing vector element at index '0'
2350// :95:17: error: use of undefined value here causes illegal behavior2324// :95:17: error: use of undefined value here causes illegal behavior
2325// :95:17: note: when computing vector element at index '0'
2351// :95:17: error: use of undefined value here causes illegal behavior2326// :95:17: error: use of undefined value here causes illegal behavior
2327// :95:17: note: when computing vector element at index '0'
2352// :95:17: error: use of undefined value here causes illegal behavior2328// :95:17: error: use of undefined value here causes illegal behavior
2329// :95:17: note: when computing vector element at index '0'
2353// :95:17: error: use of undefined value here causes illegal behavior2330// :95:17: error: use of undefined value here causes illegal behavior
2331// :95:17: note: when computing vector element at index '0'
2354// :95:17: error: use of undefined value here causes illegal behavior2332// :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'
2356// :95:17: error: use of undefined value here causes illegal behavior2334// :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'
2358// :95:17: error: use of undefined value here causes illegal behavior2336// :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'
2360// :95:17: error: use of undefined value here causes illegal behavior2338// :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'
2362// :95:17: error: use of undefined value here causes illegal behavior2340// :95:17: error: use of undefined value here causes illegal behavior
2363// :95:17: note: when computing vector element at index '0'2341// :95:17: note: when computing vector element at index '0'
2364// :95:17: error: use of undefined value here causes illegal behavior2342// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2368,11 +2346,17 @@ const std = @import("std");...@@ -2368,11 +2346,17 @@ const std = @import("std");
2368// :95:17: error: use of undefined value here causes illegal behavior2346// :95:17: error: use of undefined value here causes illegal behavior
2369// :95:17: note: when computing vector element at index '0'2347// :95:17: note: when computing vector element at index '0'
2370// :95:17: error: use of undefined value here causes illegal behavior2348// :95:17: error: use of undefined value here causes illegal behavior
2349// :95:17: note: when computing vector element at index '1'
2371// :95:17: error: use of undefined value here causes illegal behavior2350// :95:17: error: use of undefined value here causes illegal behavior
2351// :95:17: note: when computing vector element at index '1'
2372// :95:17: error: use of undefined value here causes illegal behavior2352// :95:17: error: use of undefined value here causes illegal behavior
2353// :95:17: note: when computing vector element at index '1'
2373// :95:17: error: use of undefined value here causes illegal behavior2354// :95:17: error: use of undefined value here causes illegal behavior
2355// :95:17: note: when computing vector element at index '1'
2374// :95:17: error: use of undefined value here causes illegal behavior2356// :95:17: error: use of undefined value here causes illegal behavior
2357// :95:17: note: when computing vector element at index '1'
2375// :95:17: error: use of undefined value here causes illegal behavior2358// :95:17: error: use of undefined value here causes illegal behavior
2359// :95:17: note: when computing vector element at index '1'
2376// :95:17: error: use of undefined value here causes illegal behavior2360// :95:17: error: use of undefined value here causes illegal behavior
2377// :95:17: note: when computing vector element at index '1'2361// :95:17: note: when computing vector element at index '1'
2378// :95:17: error: use of undefined value here causes illegal behavior2362// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2382,19 +2366,25 @@ const std = @import("std");...@@ -2382,19 +2366,25 @@ const std = @import("std");
2382// :95:17: error: use of undefined value here causes illegal behavior2366// :95:17: error: use of undefined value here causes illegal behavior
2383// :95:17: note: when computing vector element at index '1'2367// :95:17: note: when computing vector element at index '1'
2384// :95:17: error: use of undefined value here causes illegal behavior2368// :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'
2386// :95:17: error: use of undefined value here causes illegal behavior2370// :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'
2388// :95:17: error: use of undefined value here causes illegal behavior2372// :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'
2390// :95:17: error: use of undefined value here causes illegal behavior2374// :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'
2392// :95:17: error: use of undefined value here causes illegal behavior2376// :95:17: error: use of undefined value here causes illegal behavior
2377// :95:17: note: when computing vector element at index '1'
2393// :95:17: error: use of undefined value here causes illegal behavior2378// :95:17: error: use of undefined value here causes illegal behavior
2379// :95:17: note: when computing vector element at index '1'
2394// :95:17: error: use of undefined value here causes illegal behavior2380// :95:17: error: use of undefined value here causes illegal behavior
2381// :95:17: note: when computing vector element at index '1'
2395// :95:17: error: use of undefined value here causes illegal behavior2382// :95:17: error: use of undefined value here causes illegal behavior
2383// :95:17: note: when computing vector element at index '1'
2396// :95:17: error: use of undefined value here causes illegal behavior2384// :95:17: error: use of undefined value here causes illegal behavior
2385// :95:17: note: when computing vector element at index '1'
2397// :95:17: error: use of undefined value here causes illegal behavior2386// :95:17: error: use of undefined value here causes illegal behavior
2387// :95:17: note: when computing vector element at index '1'
2398// :95:17: error: use of undefined value here causes illegal behavior2388// :95:17: error: use of undefined value here causes illegal behavior
2399// :95:17: note: when computing vector element at index '1'2389// :95:17: note: when computing vector element at index '1'
2400// :95:17: error: use of undefined value here causes illegal behavior2390// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2404,19 +2394,25 @@ const std = @import("std");...@@ -2404,19 +2394,25 @@ const std = @import("std");
2404// :95:17: error: use of undefined value here causes illegal behavior2394// :95:17: error: use of undefined value here causes illegal behavior
2405// :95:17: note: when computing vector element at index '1'2395// :95:17: note: when computing vector element at index '1'
2406// :95:17: error: use of undefined value here causes illegal behavior2396// :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'
2408// :95:17: error: use of undefined value here causes illegal behavior2398// :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'
2410// :95:17: error: use of undefined value here causes illegal behavior2400// :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'
2412// :95:17: error: use of undefined value here causes illegal behavior2402// :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'
2414// :95:17: error: use of undefined value here causes illegal behavior2404// :95:17: error: use of undefined value here causes illegal behavior
2405// :95:17: note: when computing vector element at index '1'
2415// :95:17: error: use of undefined value here causes illegal behavior2406// :95:17: error: use of undefined value here causes illegal behavior
2407// :95:17: note: when computing vector element at index '1'
2416// :95:17: error: use of undefined value here causes illegal behavior2408// :95:17: error: use of undefined value here causes illegal behavior
2409// :95:17: note: when computing vector element at index '1'
2417// :95:17: error: use of undefined value here causes illegal behavior2410// :95:17: error: use of undefined value here causes illegal behavior
2411// :95:17: note: when computing vector element at index '1'
2418// :95:17: error: use of undefined value here causes illegal behavior2412// :95:17: error: use of undefined value here causes illegal behavior
2413// :95:17: note: when computing vector element at index '1'
2419// :95:17: error: use of undefined value here causes illegal behavior2414// :95:17: error: use of undefined value here causes illegal behavior
2415// :95:17: note: when computing vector element at index '1'
2420// :95:17: error: use of undefined value here causes illegal behavior2416// :95:17: error: use of undefined value here causes illegal behavior
2421// :95:17: note: when computing vector element at index '1'2417// :95:17: note: when computing vector element at index '1'
2422// :95:17: error: use of undefined value here causes illegal behavior2418// :95:17: error: use of undefined value here causes illegal behavior
...@@ -2426,13 +2422,17 @@ const std = @import("std");...@@ -2426,13 +2422,17 @@ const std = @import("std");
2426// :95:17: error: use of undefined value here causes illegal behavior2422// :95:17: error: use of undefined value here causes illegal behavior
2427// :95:17: note: when computing vector element at index '1'2423// :95:17: note: when computing vector element at index '1'
2428// :95:17: error: use of undefined value here causes illegal behavior2424// :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'
2430// :95:17: error: use of undefined value here causes illegal behavior2426// :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'
2432// :95:17: error: use of undefined value here causes illegal behavior2428// :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'
2434// :95:17: error: use of undefined value here causes illegal behavior2430// :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'
2436// :99:27: error: use of undefined value here causes illegal behavior2436// :99:27: error: use of undefined value here causes illegal behavior
2437// :99:27: error: use of undefined value here causes illegal behavior2437// :99:27: error: use of undefined value here causes illegal behavior
2438// :99:27: error: use of undefined value here causes illegal behavior2438// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2440,21 +2440,13 @@ const std = @import("std");...@@ -2440,21 +2440,13 @@ const std = @import("std");
2440// :99:27: error: use of undefined value here causes illegal behavior2440// :99:27: error: use of undefined value here causes illegal behavior
2441// :99:27: error: use of undefined value here causes illegal behavior2441// :99:27: error: use of undefined value here causes illegal behavior
2442// :99:27: error: use of undefined value here causes illegal behavior2442// :99:27: error: use of undefined value here causes illegal behavior
2443// :99:27: note: when computing vector element at index '1'
2444// :99:27: error: use of undefined value here causes illegal behavior2443// :99:27: error: use of undefined value here causes illegal behavior
2445// :99:27: note: when computing vector element at index '1'
2446// :99:27: error: use of undefined value here causes illegal behavior2444// :99:27: error: use of undefined value here causes illegal behavior
2447// :99:27: note: when computing vector element at index '1'
2448// :99:27: error: use of undefined value here causes illegal behavior2445// :99:27: error: use of undefined value here causes illegal behavior
2449// :99:27: note: when computing vector element at index '1'
2450// :99:27: error: use of undefined value here causes illegal behavior2446// :99:27: error: use of undefined value here causes illegal behavior
2451// :99:27: note: when computing vector element at index '0'
2452// :99:27: error: use of undefined value here causes illegal behavior2447// :99:27: error: use of undefined value here causes illegal behavior
2453// :99:27: note: when computing vector element at index '0'
2454// :99:27: error: use of undefined value here causes illegal behavior2448// :99:27: error: use of undefined value here causes illegal behavior
2455// :99:27: note: when computing vector element at index '0'
2456// :99:27: error: use of undefined value here causes illegal behavior2449// :99:27: error: use of undefined value here causes illegal behavior
2457// :99:27: note: when computing vector element at index '0'
2458// :99:27: error: use of undefined value here causes illegal behavior2450// :99:27: error: use of undefined value here causes illegal behavior
2459// :99:27: error: use of undefined value here causes illegal behavior2451// :99:27: error: use of undefined value here causes illegal behavior
2460// :99:27: error: use of undefined value here causes illegal behavior2452// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2462,21 +2454,13 @@ const std = @import("std");...@@ -2462,21 +2454,13 @@ const std = @import("std");
2462// :99:27: error: use of undefined value here causes illegal behavior2454// :99:27: error: use of undefined value here causes illegal behavior
2463// :99:27: error: use of undefined value here causes illegal behavior2455// :99:27: error: use of undefined value here causes illegal behavior
2464// :99:27: error: use of undefined value here causes illegal behavior2456// :99:27: error: use of undefined value here causes illegal behavior
2465// :99:27: note: when computing vector element at index '1'
2466// :99:27: error: use of undefined value here causes illegal behavior2457// :99:27: error: use of undefined value here causes illegal behavior
2467// :99:27: note: when computing vector element at index '1'
2468// :99:27: error: use of undefined value here causes illegal behavior2458// :99:27: error: use of undefined value here causes illegal behavior
2469// :99:27: note: when computing vector element at index '1'
2470// :99:27: error: use of undefined value here causes illegal behavior2459// :99:27: error: use of undefined value here causes illegal behavior
2471// :99:27: note: when computing vector element at index '1'
2472// :99:27: error: use of undefined value here causes illegal behavior2460// :99:27: error: use of undefined value here causes illegal behavior
2473// :99:27: note: when computing vector element at index '0'
2474// :99:27: error: use of undefined value here causes illegal behavior2461// :99:27: error: use of undefined value here causes illegal behavior
2475// :99:27: note: when computing vector element at index '0'
2476// :99:27: error: use of undefined value here causes illegal behavior2462// :99:27: error: use of undefined value here causes illegal behavior
2477// :99:27: note: when computing vector element at index '0'
2478// :99:27: error: use of undefined value here causes illegal behavior2463// :99:27: error: use of undefined value here causes illegal behavior
2479// :99:27: note: when computing vector element at index '0'
2480// :99:27: error: use of undefined value here causes illegal behavior2464// :99:27: error: use of undefined value here causes illegal behavior
2481// :99:27: error: use of undefined value here causes illegal behavior2465// :99:27: error: use of undefined value here causes illegal behavior
2482// :99:27: error: use of undefined value here causes illegal behavior2466// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2484,21 +2468,13 @@ const std = @import("std");...@@ -2484,21 +2468,13 @@ const std = @import("std");
2484// :99:27: error: use of undefined value here causes illegal behavior2468// :99:27: error: use of undefined value here causes illegal behavior
2485// :99:27: error: use of undefined value here causes illegal behavior2469// :99:27: error: use of undefined value here causes illegal behavior
2486// :99:27: error: use of undefined value here causes illegal behavior2470// :99:27: error: use of undefined value here causes illegal behavior
2487// :99:27: note: when computing vector element at index '1'
2488// :99:27: error: use of undefined value here causes illegal behavior2471// :99:27: error: use of undefined value here causes illegal behavior
2489// :99:27: note: when computing vector element at index '1'
2490// :99:27: error: use of undefined value here causes illegal behavior2472// :99:27: error: use of undefined value here causes illegal behavior
2491// :99:27: note: when computing vector element at index '1'
2492// :99:27: error: use of undefined value here causes illegal behavior2473// :99:27: error: use of undefined value here causes illegal behavior
2493// :99:27: note: when computing vector element at index '1'
2494// :99:27: error: use of undefined value here causes illegal behavior2474// :99:27: error: use of undefined value here causes illegal behavior
2495// :99:27: note: when computing vector element at index '0'
2496// :99:27: error: use of undefined value here causes illegal behavior2475// :99:27: error: use of undefined value here causes illegal behavior
2497// :99:27: note: when computing vector element at index '0'
2498// :99:27: error: use of undefined value here causes illegal behavior2476// :99:27: error: use of undefined value here causes illegal behavior
2499// :99:27: note: when computing vector element at index '0'
2500// :99:27: error: use of undefined value here causes illegal behavior2477// :99:27: error: use of undefined value here causes illegal behavior
2501// :99:27: note: when computing vector element at index '0'
2502// :99:27: error: use of undefined value here causes illegal behavior2478// :99:27: error: use of undefined value here causes illegal behavior
2503// :99:27: error: use of undefined value here causes illegal behavior2479// :99:27: error: use of undefined value here causes illegal behavior
2504// :99:27: error: use of undefined value here causes illegal behavior2480// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2506,21 +2482,13 @@ const std = @import("std");...@@ -2506,21 +2482,13 @@ const std = @import("std");
2506// :99:27: error: use of undefined value here causes illegal behavior2482// :99:27: error: use of undefined value here causes illegal behavior
2507// :99:27: error: use of undefined value here causes illegal behavior2483// :99:27: error: use of undefined value here causes illegal behavior
2508// :99:27: error: use of undefined value here causes illegal behavior2484// :99:27: error: use of undefined value here causes illegal behavior
2509// :99:27: note: when computing vector element at index '1'
2510// :99:27: error: use of undefined value here causes illegal behavior2485// :99:27: error: use of undefined value here causes illegal behavior
2511// :99:27: note: when computing vector element at index '1'
2512// :99:27: error: use of undefined value here causes illegal behavior2486// :99:27: error: use of undefined value here causes illegal behavior
2513// :99:27: note: when computing vector element at index '1'
2514// :99:27: error: use of undefined value here causes illegal behavior2487// :99:27: error: use of undefined value here causes illegal behavior
2515// :99:27: note: when computing vector element at index '1'
2516// :99:27: error: use of undefined value here causes illegal behavior2488// :99:27: error: use of undefined value here causes illegal behavior
2517// :99:27: note: when computing vector element at index '0'
2518// :99:27: error: use of undefined value here causes illegal behavior2489// :99:27: error: use of undefined value here causes illegal behavior
2519// :99:27: note: when computing vector element at index '0'
2520// :99:27: error: use of undefined value here causes illegal behavior2490// :99:27: error: use of undefined value here causes illegal behavior
2521// :99:27: note: when computing vector element at index '0'
2522// :99:27: error: use of undefined value here causes illegal behavior2491// :99:27: error: use of undefined value here causes illegal behavior
2523// :99:27: note: when computing vector element at index '0'
2524// :99:27: error: use of undefined value here causes illegal behavior2492// :99:27: error: use of undefined value here causes illegal behavior
2525// :99:27: error: use of undefined value here causes illegal behavior2493// :99:27: error: use of undefined value here causes illegal behavior
2526// :99:27: error: use of undefined value here causes illegal behavior2494// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2528,13 +2496,9 @@ const std = @import("std");...@@ -2528,13 +2496,9 @@ const std = @import("std");
2528// :99:27: error: use of undefined value here causes illegal behavior2496// :99:27: error: use of undefined value here causes illegal behavior
2529// :99:27: error: use of undefined value here causes illegal behavior2497// :99:27: error: use of undefined value here causes illegal behavior
2530// :99:27: error: use of undefined value here causes illegal behavior2498// :99:27: error: use of undefined value here causes illegal behavior
2531// :99:27: note: when computing vector element at index '1'
2532// :99:27: error: use of undefined value here causes illegal behavior2499// :99:27: error: use of undefined value here causes illegal behavior
2533// :99:27: note: when computing vector element at index '1'
2534// :99:27: error: use of undefined value here causes illegal behavior2500// :99:27: error: use of undefined value here causes illegal behavior
2535// :99:27: note: when computing vector element at index '1'
2536// :99:27: error: use of undefined value here causes illegal behavior2501// :99:27: error: use of undefined value here causes illegal behavior
2537// :99:27: note: when computing vector element at index '1'
2538// :99:27: error: use of undefined value here causes illegal behavior2502// :99:27: error: use of undefined value here causes illegal behavior
2539// :99:27: note: when computing vector element at index '0'2503// :99:27: note: when computing vector element at index '0'
2540// :99:27: error: use of undefined value here causes illegal behavior2504// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2544,19 +2508,21 @@ const std = @import("std");...@@ -2544,19 +2508,21 @@ const std = @import("std");
2544// :99:27: error: use of undefined value here causes illegal behavior2508// :99:27: error: use of undefined value here causes illegal behavior
2545// :99:27: note: when computing vector element at index '0'2509// :99:27: note: when computing vector element at index '0'
2546// :99:27: error: use of undefined value here causes illegal behavior2510// :99:27: error: use of undefined value here causes illegal behavior
2511// :99:27: note: when computing vector element at index '0'
2547// :99:27: error: use of undefined value here causes illegal behavior2512// :99:27: error: use of undefined value here causes illegal behavior
2513// :99:27: note: when computing vector element at index '0'
2548// :99:27: error: use of undefined value here causes illegal behavior2514// :99:27: error: use of undefined value here causes illegal behavior
2515// :99:27: note: when computing vector element at index '0'
2549// :99:27: error: use of undefined value here causes illegal behavior2516// :99:27: error: use of undefined value here causes illegal behavior
2517// :99:27: note: when computing vector element at index '0'
2550// :99:27: error: use of undefined value here causes illegal behavior2518// :99:27: error: use of undefined value here causes illegal behavior
2519// :99:27: note: when computing vector element at index '0'
2551// :99:27: error: use of undefined value here causes illegal behavior2520// :99:27: error: use of undefined value here causes illegal behavior
2521// :99:27: note: when computing vector element at index '0'
2552// :99:27: error: use of undefined value here causes illegal behavior2522// :99:27: error: use of undefined value here causes illegal behavior
2553// :99:27: note: when computing vector element at index '1'2523// :99:27: note: when computing vector element at index '0'
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'
2558// :99:27: error: use of undefined value here causes illegal behavior2524// :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'
2560// :99:27: error: use of undefined value here causes illegal behavior2526// :99:27: error: use of undefined value here causes illegal behavior
2561// :99:27: note: when computing vector element at index '0'2527// :99:27: note: when computing vector element at index '0'
2562// :99:27: error: use of undefined value here causes illegal behavior2528// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2566,19 +2532,25 @@ const std = @import("std");...@@ -2566,19 +2532,25 @@ const std = @import("std");
2566// :99:27: error: use of undefined value here causes illegal behavior2532// :99:27: error: use of undefined value here causes illegal behavior
2567// :99:27: note: when computing vector element at index '0'2533// :99:27: note: when computing vector element at index '0'
2568// :99:27: error: use of undefined value here causes illegal behavior2534// :99:27: error: use of undefined value here causes illegal behavior
2535// :99:27: note: when computing vector element at index '0'
2569// :99:27: error: use of undefined value here causes illegal behavior2536// :99:27: error: use of undefined value here causes illegal behavior
2537// :99:27: note: when computing vector element at index '0'
2570// :99:27: error: use of undefined value here causes illegal behavior2538// :99:27: error: use of undefined value here causes illegal behavior
2539// :99:27: note: when computing vector element at index '0'
2571// :99:27: error: use of undefined value here causes illegal behavior2540// :99:27: error: use of undefined value here causes illegal behavior
2541// :99:27: note: when computing vector element at index '0'
2572// :99:27: error: use of undefined value here causes illegal behavior2542// :99:27: error: use of undefined value here causes illegal behavior
2543// :99:27: note: when computing vector element at index '0'
2573// :99:27: error: use of undefined value here causes illegal behavior2544// :99:27: error: use of undefined value here causes illegal behavior
2545// :99:27: note: when computing vector element at index '0'
2574// :99:27: error: use of undefined value here causes illegal behavior2546// :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'
2576// :99:27: error: use of undefined value here causes illegal behavior2548// :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'
2578// :99:27: error: use of undefined value here causes illegal behavior2550// :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'
2580// :99:27: error: use of undefined value here causes illegal behavior2552// :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'
2582// :99:27: error: use of undefined value here causes illegal behavior2554// :99:27: error: use of undefined value here causes illegal behavior
2583// :99:27: note: when computing vector element at index '0'2555// :99:27: note: when computing vector element at index '0'
2584// :99:27: error: use of undefined value here causes illegal behavior2556// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2588,19 +2560,25 @@ const std = @import("std");...@@ -2588,19 +2560,25 @@ const std = @import("std");
2588// :99:27: error: use of undefined value here causes illegal behavior2560// :99:27: error: use of undefined value here causes illegal behavior
2589// :99:27: note: when computing vector element at index '0'2561// :99:27: note: when computing vector element at index '0'
2590// :99:27: error: use of undefined value here causes illegal behavior2562// :99:27: error: use of undefined value here causes illegal behavior
2563// :99:27: note: when computing vector element at index '0'
2591// :99:27: error: use of undefined value here causes illegal behavior2564// :99:27: error: use of undefined value here causes illegal behavior
2565// :99:27: note: when computing vector element at index '0'
2592// :99:27: error: use of undefined value here causes illegal behavior2566// :99:27: error: use of undefined value here causes illegal behavior
2567// :99:27: note: when computing vector element at index '0'
2593// :99:27: error: use of undefined value here causes illegal behavior2568// :99:27: error: use of undefined value here causes illegal behavior
2569// :99:27: note: when computing vector element at index '0'
2594// :99:27: error: use of undefined value here causes illegal behavior2570// :99:27: error: use of undefined value here causes illegal behavior
2571// :99:27: note: when computing vector element at index '0'
2595// :99:27: error: use of undefined value here causes illegal behavior2572// :99:27: error: use of undefined value here causes illegal behavior
2573// :99:27: note: when computing vector element at index '0'
2596// :99:27: error: use of undefined value here causes illegal behavior2574// :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'
2598// :99:27: error: use of undefined value here causes illegal behavior2576// :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'
2600// :99:27: error: use of undefined value here causes illegal behavior2578// :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'
2602// :99:27: error: use of undefined value here causes illegal behavior2580// :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'
2604// :99:27: error: use of undefined value here causes illegal behavior2582// :99:27: error: use of undefined value here causes illegal behavior
2605// :99:27: note: when computing vector element at index '0'2583// :99:27: note: when computing vector element at index '0'
2606// :99:27: error: use of undefined value here causes illegal behavior2584// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2610,11 +2588,17 @@ const std = @import("std");...@@ -2610,11 +2588,17 @@ const std = @import("std");
2610// :99:27: error: use of undefined value here causes illegal behavior2588// :99:27: error: use of undefined value here causes illegal behavior
2611// :99:27: note: when computing vector element at index '0'2589// :99:27: note: when computing vector element at index '0'
2612// :99:27: error: use of undefined value here causes illegal behavior2590// :99:27: error: use of undefined value here causes illegal behavior
2591// :99:27: note: when computing vector element at index '1'
2613// :99:27: error: use of undefined value here causes illegal behavior2592// :99:27: error: use of undefined value here causes illegal behavior
2593// :99:27: note: when computing vector element at index '1'
2614// :99:27: error: use of undefined value here causes illegal behavior2594// :99:27: error: use of undefined value here causes illegal behavior
2595// :99:27: note: when computing vector element at index '1'
2615// :99:27: error: use of undefined value here causes illegal behavior2596// :99:27: error: use of undefined value here causes illegal behavior
2597// :99:27: note: when computing vector element at index '1'
2616// :99:27: error: use of undefined value here causes illegal behavior2598// :99:27: error: use of undefined value here causes illegal behavior
2599// :99:27: note: when computing vector element at index '1'
2617// :99:27: error: use of undefined value here causes illegal behavior2600// :99:27: error: use of undefined value here causes illegal behavior
2601// :99:27: note: when computing vector element at index '1'
2618// :99:27: error: use of undefined value here causes illegal behavior2602// :99:27: error: use of undefined value here causes illegal behavior
2619// :99:27: note: when computing vector element at index '1'2603// :99:27: note: when computing vector element at index '1'
2620// :99:27: error: use of undefined value here causes illegal behavior2604// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2624,19 +2608,25 @@ const std = @import("std");...@@ -2624,19 +2608,25 @@ const std = @import("std");
2624// :99:27: error: use of undefined value here causes illegal behavior2608// :99:27: error: use of undefined value here causes illegal behavior
2625// :99:27: note: when computing vector element at index '1'2609// :99:27: note: when computing vector element at index '1'
2626// :99:27: error: use of undefined value here causes illegal behavior2610// :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'
2628// :99:27: error: use of undefined value here causes illegal behavior2612// :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'
2630// :99:27: error: use of undefined value here causes illegal behavior2614// :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'
2632// :99:27: error: use of undefined value here causes illegal behavior2616// :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'
2634// :99:27: error: use of undefined value here causes illegal behavior2618// :99:27: error: use of undefined value here causes illegal behavior
2619// :99:27: note: when computing vector element at index '1'
2635// :99:27: error: use of undefined value here causes illegal behavior2620// :99:27: error: use of undefined value here causes illegal behavior
2621// :99:27: note: when computing vector element at index '1'
2636// :99:27: error: use of undefined value here causes illegal behavior2622// :99:27: error: use of undefined value here causes illegal behavior
2623// :99:27: note: when computing vector element at index '1'
2637// :99:27: error: use of undefined value here causes illegal behavior2624// :99:27: error: use of undefined value here causes illegal behavior
2625// :99:27: note: when computing vector element at index '1'
2638// :99:27: error: use of undefined value here causes illegal behavior2626// :99:27: error: use of undefined value here causes illegal behavior
2627// :99:27: note: when computing vector element at index '1'
2639// :99:27: error: use of undefined value here causes illegal behavior2628// :99:27: error: use of undefined value here causes illegal behavior
2629// :99:27: note: when computing vector element at index '1'
2640// :99:27: error: use of undefined value here causes illegal behavior2630// :99:27: error: use of undefined value here causes illegal behavior
2641// :99:27: note: when computing vector element at index '1'2631// :99:27: note: when computing vector element at index '1'
2642// :99:27: error: use of undefined value here causes illegal behavior2632// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2646,19 +2636,25 @@ const std = @import("std");...@@ -2646,19 +2636,25 @@ const std = @import("std");
2646// :99:27: error: use of undefined value here causes illegal behavior2636// :99:27: error: use of undefined value here causes illegal behavior
2647// :99:27: note: when computing vector element at index '1'2637// :99:27: note: when computing vector element at index '1'
2648// :99:27: error: use of undefined value here causes illegal behavior2638// :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'
2650// :99:27: error: use of undefined value here causes illegal behavior2640// :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'
2652// :99:27: error: use of undefined value here causes illegal behavior2642// :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'
2654// :99:27: error: use of undefined value here causes illegal behavior2644// :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'
2656// :99:27: error: use of undefined value here causes illegal behavior2646// :99:27: error: use of undefined value here causes illegal behavior
2647// :99:27: note: when computing vector element at index '1'
2657// :99:27: error: use of undefined value here causes illegal behavior2648// :99:27: error: use of undefined value here causes illegal behavior
2649// :99:27: note: when computing vector element at index '1'
2658// :99:27: error: use of undefined value here causes illegal behavior2650// :99:27: error: use of undefined value here causes illegal behavior
2651// :99:27: note: when computing vector element at index '1'
2659// :99:27: error: use of undefined value here causes illegal behavior2652// :99:27: error: use of undefined value here causes illegal behavior
2653// :99:27: note: when computing vector element at index '1'
2660// :99:27: error: use of undefined value here causes illegal behavior2654// :99:27: error: use of undefined value here causes illegal behavior
2655// :99:27: note: when computing vector element at index '1'
2661// :99:27: error: use of undefined value here causes illegal behavior2656// :99:27: error: use of undefined value here causes illegal behavior
2657// :99:27: note: when computing vector element at index '1'
2662// :99:27: error: use of undefined value here causes illegal behavior2658// :99:27: error: use of undefined value here causes illegal behavior
2663// :99:27: note: when computing vector element at index '1'2659// :99:27: note: when computing vector element at index '1'
2664// :99:27: error: use of undefined value here causes illegal behavior2660// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2668,13 +2664,17 @@ const std = @import("std");...@@ -2668,13 +2664,17 @@ const std = @import("std");
2668// :99:27: error: use of undefined value here causes illegal behavior2664// :99:27: error: use of undefined value here causes illegal behavior
2669// :99:27: note: when computing vector element at index '1'2665// :99:27: note: when computing vector element at index '1'
2670// :99:27: error: use of undefined value here causes illegal behavior2666// :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'
2672// :99:27: error: use of undefined value here causes illegal behavior2668// :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'
2674// :99:27: error: use of undefined value here causes illegal behavior2670// :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'
2676// :99:27: error: use of undefined value here causes illegal behavior2672// :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'
2678// :103:27: error: use of undefined value here causes illegal behavior2678// :103:27: error: use of undefined value here causes illegal behavior
2679// :103:27: error: use of undefined value here causes illegal behavior2679// :103:27: error: use of undefined value here causes illegal behavior
2680// :103:27: error: use of undefined value here causes illegal behavior2680// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2682,21 +2682,13 @@ const std = @import("std");...@@ -2682,21 +2682,13 @@ const std = @import("std");
2682// :103:27: error: use of undefined value here causes illegal behavior2682// :103:27: error: use of undefined value here causes illegal behavior
2683// :103:27: error: use of undefined value here causes illegal behavior2683// :103:27: error: use of undefined value here causes illegal behavior
2684// :103:27: error: use of undefined value here causes illegal behavior2684// :103:27: error: use of undefined value here causes illegal behavior
2685// :103:27: note: when computing vector element at index '1'
2686// :103:27: error: use of undefined value here causes illegal behavior2685// :103:27: error: use of undefined value here causes illegal behavior
2687// :103:27: note: when computing vector element at index '1'
2688// :103:27: error: use of undefined value here causes illegal behavior2686// :103:27: error: use of undefined value here causes illegal behavior
2689// :103:27: note: when computing vector element at index '1'
2690// :103:27: error: use of undefined value here causes illegal behavior2687// :103:27: error: use of undefined value here causes illegal behavior
2691// :103:27: note: when computing vector element at index '1'
2692// :103:27: error: use of undefined value here causes illegal behavior2688// :103:27: error: use of undefined value here causes illegal behavior
2693// :103:27: note: when computing vector element at index '0'
2694// :103:27: error: use of undefined value here causes illegal behavior2689// :103:27: error: use of undefined value here causes illegal behavior
2695// :103:27: note: when computing vector element at index '0'
2696// :103:27: error: use of undefined value here causes illegal behavior2690// :103:27: error: use of undefined value here causes illegal behavior
2697// :103:27: note: when computing vector element at index '0'
2698// :103:27: error: use of undefined value here causes illegal behavior2691// :103:27: error: use of undefined value here causes illegal behavior
2699// :103:27: note: when computing vector element at index '0'
2700// :103:27: error: use of undefined value here causes illegal behavior2692// :103:27: error: use of undefined value here causes illegal behavior
2701// :103:27: error: use of undefined value here causes illegal behavior2693// :103:27: error: use of undefined value here causes illegal behavior
2702// :103:27: error: use of undefined value here causes illegal behavior2694// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2704,21 +2696,13 @@ const std = @import("std");...@@ -2704,21 +2696,13 @@ const std = @import("std");
2704// :103:27: error: use of undefined value here causes illegal behavior2696// :103:27: error: use of undefined value here causes illegal behavior
2705// :103:27: error: use of undefined value here causes illegal behavior2697// :103:27: error: use of undefined value here causes illegal behavior
2706// :103:27: error: use of undefined value here causes illegal behavior2698// :103:27: error: use of undefined value here causes illegal behavior
2707// :103:27: note: when computing vector element at index '1'
2708// :103:27: error: use of undefined value here causes illegal behavior2699// :103:27: error: use of undefined value here causes illegal behavior
2709// :103:27: note: when computing vector element at index '1'
2710// :103:27: error: use of undefined value here causes illegal behavior2700// :103:27: error: use of undefined value here causes illegal behavior
2711// :103:27: note: when computing vector element at index '1'
2712// :103:27: error: use of undefined value here causes illegal behavior2701// :103:27: error: use of undefined value here causes illegal behavior
2713// :103:27: note: when computing vector element at index '1'
2714// :103:27: error: use of undefined value here causes illegal behavior2702// :103:27: error: use of undefined value here causes illegal behavior
2715// :103:27: note: when computing vector element at index '0'
2716// :103:27: error: use of undefined value here causes illegal behavior2703// :103:27: error: use of undefined value here causes illegal behavior
2717// :103:27: note: when computing vector element at index '0'
2718// :103:27: error: use of undefined value here causes illegal behavior2704// :103:27: error: use of undefined value here causes illegal behavior
2719// :103:27: note: when computing vector element at index '0'
2720// :103:27: error: use of undefined value here causes illegal behavior2705// :103:27: error: use of undefined value here causes illegal behavior
2721// :103:27: note: when computing vector element at index '0'
2722// :103:27: error: use of undefined value here causes illegal behavior2706// :103:27: error: use of undefined value here causes illegal behavior
2723// :103:27: error: use of undefined value here causes illegal behavior2707// :103:27: error: use of undefined value here causes illegal behavior
2724// :103:27: error: use of undefined value here causes illegal behavior2708// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2726,21 +2710,13 @@ const std = @import("std");...@@ -2726,21 +2710,13 @@ const std = @import("std");
2726// :103:27: error: use of undefined value here causes illegal behavior2710// :103:27: error: use of undefined value here causes illegal behavior
2727// :103:27: error: use of undefined value here causes illegal behavior2711// :103:27: error: use of undefined value here causes illegal behavior
2728// :103:27: error: use of undefined value here causes illegal behavior2712// :103:27: error: use of undefined value here causes illegal behavior
2729// :103:27: note: when computing vector element at index '1'
2730// :103:27: error: use of undefined value here causes illegal behavior2713// :103:27: error: use of undefined value here causes illegal behavior
2731// :103:27: note: when computing vector element at index '1'
2732// :103:27: error: use of undefined value here causes illegal behavior2714// :103:27: error: use of undefined value here causes illegal behavior
2733// :103:27: note: when computing vector element at index '1'
2734// :103:27: error: use of undefined value here causes illegal behavior2715// :103:27: error: use of undefined value here causes illegal behavior
2735// :103:27: note: when computing vector element at index '1'
2736// :103:27: error: use of undefined value here causes illegal behavior2716// :103:27: error: use of undefined value here causes illegal behavior
2737// :103:27: note: when computing vector element at index '0'
2738// :103:27: error: use of undefined value here causes illegal behavior2717// :103:27: error: use of undefined value here causes illegal behavior
2739// :103:27: note: when computing vector element at index '0'
2740// :103:27: error: use of undefined value here causes illegal behavior2718// :103:27: error: use of undefined value here causes illegal behavior
2741// :103:27: note: when computing vector element at index '0'
2742// :103:27: error: use of undefined value here causes illegal behavior2719// :103:27: error: use of undefined value here causes illegal behavior
2743// :103:27: note: when computing vector element at index '0'
2744// :103:27: error: use of undefined value here causes illegal behavior2720// :103:27: error: use of undefined value here causes illegal behavior
2745// :103:27: error: use of undefined value here causes illegal behavior2721// :103:27: error: use of undefined value here causes illegal behavior
2746// :103:27: error: use of undefined value here causes illegal behavior2722// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2748,21 +2724,13 @@ const std = @import("std");...@@ -2748,21 +2724,13 @@ const std = @import("std");
2748// :103:27: error: use of undefined value here causes illegal behavior2724// :103:27: error: use of undefined value here causes illegal behavior
2749// :103:27: error: use of undefined value here causes illegal behavior2725// :103:27: error: use of undefined value here causes illegal behavior
2750// :103:27: error: use of undefined value here causes illegal behavior2726// :103:27: error: use of undefined value here causes illegal behavior
2751// :103:27: note: when computing vector element at index '1'
2752// :103:27: error: use of undefined value here causes illegal behavior2727// :103:27: error: use of undefined value here causes illegal behavior
2753// :103:27: note: when computing vector element at index '1'
2754// :103:27: error: use of undefined value here causes illegal behavior2728// :103:27: error: use of undefined value here causes illegal behavior
2755// :103:27: note: when computing vector element at index '1'
2756// :103:27: error: use of undefined value here causes illegal behavior2729// :103:27: error: use of undefined value here causes illegal behavior
2757// :103:27: note: when computing vector element at index '1'
2758// :103:27: error: use of undefined value here causes illegal behavior2730// :103:27: error: use of undefined value here causes illegal behavior
2759// :103:27: note: when computing vector element at index '0'
2760// :103:27: error: use of undefined value here causes illegal behavior2731// :103:27: error: use of undefined value here causes illegal behavior
2761// :103:27: note: when computing vector element at index '0'
2762// :103:27: error: use of undefined value here causes illegal behavior2732// :103:27: error: use of undefined value here causes illegal behavior
2763// :103:27: note: when computing vector element at index '0'
2764// :103:27: error: use of undefined value here causes illegal behavior2733// :103:27: error: use of undefined value here causes illegal behavior
2765// :103:27: note: when computing vector element at index '0'
2766// :103:27: error: use of undefined value here causes illegal behavior2734// :103:27: error: use of undefined value here causes illegal behavior
2767// :103:27: error: use of undefined value here causes illegal behavior2735// :103:27: error: use of undefined value here causes illegal behavior
2768// :103:27: error: use of undefined value here causes illegal behavior2736// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2770,13 +2738,9 @@ const std = @import("std");...@@ -2770,13 +2738,9 @@ const std = @import("std");
2770// :103:27: error: use of undefined value here causes illegal behavior2738// :103:27: error: use of undefined value here causes illegal behavior
2771// :103:27: error: use of undefined value here causes illegal behavior2739// :103:27: error: use of undefined value here causes illegal behavior
2772// :103:27: error: use of undefined value here causes illegal behavior2740// :103:27: error: use of undefined value here causes illegal behavior
2773// :103:27: note: when computing vector element at index '1'
2774// :103:27: error: use of undefined value here causes illegal behavior2741// :103:27: error: use of undefined value here causes illegal behavior
2775// :103:27: note: when computing vector element at index '1'
2776// :103:27: error: use of undefined value here causes illegal behavior2742// :103:27: error: use of undefined value here causes illegal behavior
2777// :103:27: note: when computing vector element at index '1'
2778// :103:27: error: use of undefined value here causes illegal behavior2743// :103:27: error: use of undefined value here causes illegal behavior
2779// :103:27: note: when computing vector element at index '1'
2780// :103:27: error: use of undefined value here causes illegal behavior2744// :103:27: error: use of undefined value here causes illegal behavior
2781// :103:27: note: when computing vector element at index '0'2745// :103:27: note: when computing vector element at index '0'
2782// :103:27: error: use of undefined value here causes illegal behavior2746// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2786,19 +2750,21 @@ const std = @import("std");...@@ -2786,19 +2750,21 @@ const std = @import("std");
2786// :103:27: error: use of undefined value here causes illegal behavior2750// :103:27: error: use of undefined value here causes illegal behavior
2787// :103:27: note: when computing vector element at index '0'2751// :103:27: note: when computing vector element at index '0'
2788// :103:27: error: use of undefined value here causes illegal behavior2752// :103:27: error: use of undefined value here causes illegal behavior
2753// :103:27: note: when computing vector element at index '0'
2789// :103:27: error: use of undefined value here causes illegal behavior2754// :103:27: error: use of undefined value here causes illegal behavior
2755// :103:27: note: when computing vector element at index '0'
2790// :103:27: error: use of undefined value here causes illegal behavior2756// :103:27: error: use of undefined value here causes illegal behavior
2757// :103:27: note: when computing vector element at index '0'
2791// :103:27: error: use of undefined value here causes illegal behavior2758// :103:27: error: use of undefined value here causes illegal behavior
2759// :103:27: note: when computing vector element at index '0'
2792// :103:27: error: use of undefined value here causes illegal behavior2760// :103:27: error: use of undefined value here causes illegal behavior
2761// :103:27: note: when computing vector element at index '0'
2793// :103:27: error: use of undefined value here causes illegal behavior2762// :103:27: error: use of undefined value here causes illegal behavior
2763// :103:27: note: when computing vector element at index '0'
2794// :103:27: error: use of undefined value here causes illegal behavior2764// :103:27: error: use of undefined value here causes illegal behavior
2795// :103:27: note: when computing vector element at index '1'2765// :103:27: note: when computing vector element at index '0'
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'
2800// :103:27: error: use of undefined value here causes illegal behavior2766// :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'
2802// :103:27: error: use of undefined value here causes illegal behavior2768// :103:27: error: use of undefined value here causes illegal behavior
2803// :103:27: note: when computing vector element at index '0'2769// :103:27: note: when computing vector element at index '0'
2804// :103:27: error: use of undefined value here causes illegal behavior2770// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2808,19 +2774,25 @@ const std = @import("std");...@@ -2808,19 +2774,25 @@ const std = @import("std");
2808// :103:27: error: use of undefined value here causes illegal behavior2774// :103:27: error: use of undefined value here causes illegal behavior
2809// :103:27: note: when computing vector element at index '0'2775// :103:27: note: when computing vector element at index '0'
2810// :103:27: error: use of undefined value here causes illegal behavior2776// :103:27: error: use of undefined value here causes illegal behavior
2777// :103:27: note: when computing vector element at index '0'
2811// :103:27: error: use of undefined value here causes illegal behavior2778// :103:27: error: use of undefined value here causes illegal behavior
2779// :103:27: note: when computing vector element at index '0'
2812// :103:27: error: use of undefined value here causes illegal behavior2780// :103:27: error: use of undefined value here causes illegal behavior
2781// :103:27: note: when computing vector element at index '0'
2813// :103:27: error: use of undefined value here causes illegal behavior2782// :103:27: error: use of undefined value here causes illegal behavior
2783// :103:27: note: when computing vector element at index '0'
2814// :103:27: error: use of undefined value here causes illegal behavior2784// :103:27: error: use of undefined value here causes illegal behavior
2785// :103:27: note: when computing vector element at index '0'
2815// :103:27: error: use of undefined value here causes illegal behavior2786// :103:27: error: use of undefined value here causes illegal behavior
2787// :103:27: note: when computing vector element at index '0'
2816// :103:27: error: use of undefined value here causes illegal behavior2788// :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'
2818// :103:27: error: use of undefined value here causes illegal behavior2790// :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'
2820// :103:27: error: use of undefined value here causes illegal behavior2792// :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'
2822// :103:27: error: use of undefined value here causes illegal behavior2794// :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'
2824// :103:27: error: use of undefined value here causes illegal behavior2796// :103:27: error: use of undefined value here causes illegal behavior
2825// :103:27: note: when computing vector element at index '0'2797// :103:27: note: when computing vector element at index '0'
2826// :103:27: error: use of undefined value here causes illegal behavior2798// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2830,19 +2802,25 @@ const std = @import("std");...@@ -2830,19 +2802,25 @@ const std = @import("std");
2830// :103:27: error: use of undefined value here causes illegal behavior2802// :103:27: error: use of undefined value here causes illegal behavior
2831// :103:27: note: when computing vector element at index '0'2803// :103:27: note: when computing vector element at index '0'
2832// :103:27: error: use of undefined value here causes illegal behavior2804// :103:27: error: use of undefined value here causes illegal behavior
2805// :103:27: note: when computing vector element at index '0'
2833// :103:27: error: use of undefined value here causes illegal behavior2806// :103:27: error: use of undefined value here causes illegal behavior
2807// :103:27: note: when computing vector element at index '0'
2834// :103:27: error: use of undefined value here causes illegal behavior2808// :103:27: error: use of undefined value here causes illegal behavior
2809// :103:27: note: when computing vector element at index '0'
2835// :103:27: error: use of undefined value here causes illegal behavior2810// :103:27: error: use of undefined value here causes illegal behavior
2811// :103:27: note: when computing vector element at index '0'
2836// :103:27: error: use of undefined value here causes illegal behavior2812// :103:27: error: use of undefined value here causes illegal behavior
2813// :103:27: note: when computing vector element at index '0'
2837// :103:27: error: use of undefined value here causes illegal behavior2814// :103:27: error: use of undefined value here causes illegal behavior
2815// :103:27: note: when computing vector element at index '0'
2838// :103:27: error: use of undefined value here causes illegal behavior2816// :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'
2840// :103:27: error: use of undefined value here causes illegal behavior2818// :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'
2842// :103:27: error: use of undefined value here causes illegal behavior2820// :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'
2844// :103:27: error: use of undefined value here causes illegal behavior2822// :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'
2846// :103:27: error: use of undefined value here causes illegal behavior2824// :103:27: error: use of undefined value here causes illegal behavior
2847// :103:27: note: when computing vector element at index '0'2825// :103:27: note: when computing vector element at index '0'
2848// :103:27: error: use of undefined value here causes illegal behavior2826// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2852,11 +2830,17 @@ const std = @import("std");...@@ -2852,11 +2830,17 @@ const std = @import("std");
2852// :103:27: error: use of undefined value here causes illegal behavior2830// :103:27: error: use of undefined value here causes illegal behavior
2853// :103:27: note: when computing vector element at index '0'2831// :103:27: note: when computing vector element at index '0'
2854// :103:27: error: use of undefined value here causes illegal behavior2832// :103:27: error: use of undefined value here causes illegal behavior
2833// :103:27: note: when computing vector element at index '1'
2855// :103:27: error: use of undefined value here causes illegal behavior2834// :103:27: error: use of undefined value here causes illegal behavior
2835// :103:27: note: when computing vector element at index '1'
2856// :103:27: error: use of undefined value here causes illegal behavior2836// :103:27: error: use of undefined value here causes illegal behavior
2837// :103:27: note: when computing vector element at index '1'
2857// :103:27: error: use of undefined value here causes illegal behavior2838// :103:27: error: use of undefined value here causes illegal behavior
2839// :103:27: note: when computing vector element at index '1'
2858// :103:27: error: use of undefined value here causes illegal behavior2840// :103:27: error: use of undefined value here causes illegal behavior
2841// :103:27: note: when computing vector element at index '1'
2859// :103:27: error: use of undefined value here causes illegal behavior2842// :103:27: error: use of undefined value here causes illegal behavior
2843// :103:27: note: when computing vector element at index '1'
2860// :103:27: error: use of undefined value here causes illegal behavior2844// :103:27: error: use of undefined value here causes illegal behavior
2861// :103:27: note: when computing vector element at index '1'2845// :103:27: note: when computing vector element at index '1'
2862// :103:27: error: use of undefined value here causes illegal behavior2846// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2866,19 +2850,25 @@ const std = @import("std");...@@ -2866,19 +2850,25 @@ const std = @import("std");
2866// :103:27: error: use of undefined value here causes illegal behavior2850// :103:27: error: use of undefined value here causes illegal behavior
2867// :103:27: note: when computing vector element at index '1'2851// :103:27: note: when computing vector element at index '1'
2868// :103:27: error: use of undefined value here causes illegal behavior2852// :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'
2870// :103:27: error: use of undefined value here causes illegal behavior2854// :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'
2872// :103:27: error: use of undefined value here causes illegal behavior2856// :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'
2874// :103:27: error: use of undefined value here causes illegal behavior2858// :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'
2876// :103:27: error: use of undefined value here causes illegal behavior2860// :103:27: error: use of undefined value here causes illegal behavior
2861// :103:27: note: when computing vector element at index '1'
2877// :103:27: error: use of undefined value here causes illegal behavior2862// :103:27: error: use of undefined value here causes illegal behavior
2863// :103:27: note: when computing vector element at index '1'
2878// :103:27: error: use of undefined value here causes illegal behavior2864// :103:27: error: use of undefined value here causes illegal behavior
2865// :103:27: note: when computing vector element at index '1'
2879// :103:27: error: use of undefined value here causes illegal behavior2866// :103:27: error: use of undefined value here causes illegal behavior
2867// :103:27: note: when computing vector element at index '1'
2880// :103:27: error: use of undefined value here causes illegal behavior2868// :103:27: error: use of undefined value here causes illegal behavior
2869// :103:27: note: when computing vector element at index '1'
2881// :103:27: error: use of undefined value here causes illegal behavior2870// :103:27: error: use of undefined value here causes illegal behavior
2871// :103:27: note: when computing vector element at index '1'
2882// :103:27: error: use of undefined value here causes illegal behavior2872// :103:27: error: use of undefined value here causes illegal behavior
2883// :103:27: note: when computing vector element at index '1'2873// :103:27: note: when computing vector element at index '1'
2884// :103:27: error: use of undefined value here causes illegal behavior2874// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2888,19 +2878,25 @@ const std = @import("std");...@@ -2888,19 +2878,25 @@ const std = @import("std");
2888// :103:27: error: use of undefined value here causes illegal behavior2878// :103:27: error: use of undefined value here causes illegal behavior
2889// :103:27: note: when computing vector element at index '1'2879// :103:27: note: when computing vector element at index '1'
2890// :103:27: error: use of undefined value here causes illegal behavior2880// :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'
2892// :103:27: error: use of undefined value here causes illegal behavior2882// :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'
2894// :103:27: error: use of undefined value here causes illegal behavior2884// :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'
2896// :103:27: error: use of undefined value here causes illegal behavior2886// :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'
2898// :103:27: error: use of undefined value here causes illegal behavior2888// :103:27: error: use of undefined value here causes illegal behavior
2889// :103:27: note: when computing vector element at index '1'
2899// :103:27: error: use of undefined value here causes illegal behavior2890// :103:27: error: use of undefined value here causes illegal behavior
2891// :103:27: note: when computing vector element at index '1'
2900// :103:27: error: use of undefined value here causes illegal behavior2892// :103:27: error: use of undefined value here causes illegal behavior
2893// :103:27: note: when computing vector element at index '1'
2901// :103:27: error: use of undefined value here causes illegal behavior2894// :103:27: error: use of undefined value here causes illegal behavior
2895// :103:27: note: when computing vector element at index '1'
2902// :103:27: error: use of undefined value here causes illegal behavior2896// :103:27: error: use of undefined value here causes illegal behavior
2897// :103:27: note: when computing vector element at index '1'
2903// :103:27: error: use of undefined value here causes illegal behavior2898// :103:27: error: use of undefined value here causes illegal behavior
2899// :103:27: note: when computing vector element at index '1'
2904// :103:27: error: use of undefined value here causes illegal behavior2900// :103:27: error: use of undefined value here causes illegal behavior
2905// :103:27: note: when computing vector element at index '1'2901// :103:27: note: when computing vector element at index '1'
2906// :103:27: error: use of undefined value here causes illegal behavior2902// :103:27: error: use of undefined value here causes illegal behavior
...@@ -2910,13 +2906,17 @@ const std = @import("std");...@@ -2910,13 +2906,17 @@ const std = @import("std");
2910// :103:27: error: use of undefined value here causes illegal behavior2906// :103:27: error: use of undefined value here causes illegal behavior
2911// :103:27: note: when computing vector element at index '1'2907// :103:27: note: when computing vector element at index '1'
2912// :103:27: error: use of undefined value here causes illegal behavior2908// :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'
2914// :103:27: error: use of undefined value here causes illegal behavior2910// :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'
2916// :103:27: error: use of undefined value here causes illegal behavior2912// :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'
2918// :103:27: error: use of undefined value here causes illegal behavior2914// :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'
2920// :107:27: error: use of undefined value here causes illegal behavior2920// :107:27: error: use of undefined value here causes illegal behavior
2921// :107:27: error: use of undefined value here causes illegal behavior2921// :107:27: error: use of undefined value here causes illegal behavior
2922// :107:27: error: use of undefined value here causes illegal behavior2922// :107:27: error: use of undefined value here causes illegal behavior
...@@ -2924,21 +2924,13 @@ const std = @import("std");...@@ -2924,21 +2924,13 @@ const std = @import("std");
2924// :107:27: error: use of undefined value here causes illegal behavior2924// :107:27: error: use of undefined value here causes illegal behavior
2925// :107:27: error: use of undefined value here causes illegal behavior2925// :107:27: error: use of undefined value here causes illegal behavior
2926// :107:27: error: use of undefined value here causes illegal behavior2926// :107:27: error: use of undefined value here causes illegal behavior
2927// :107:27: note: when computing vector element at index '1'
2928// :107:27: error: use of undefined value here causes illegal behavior2927// :107:27: error: use of undefined value here causes illegal behavior
2929// :107:27: note: when computing vector element at index '1'
2930// :107:27: error: use of undefined value here causes illegal behavior2928// :107:27: error: use of undefined value here causes illegal behavior
2931// :107:27: note: when computing vector element at index '1'
2932// :107:27: error: use of undefined value here causes illegal behavior2929// :107:27: error: use of undefined value here causes illegal behavior
2933// :107:27: note: when computing vector element at index '1'
2934// :107:27: error: use of undefined value here causes illegal behavior2930// :107:27: error: use of undefined value here causes illegal behavior
2935// :107:27: note: when computing vector element at index '0'
2936// :107:27: error: use of undefined value here causes illegal behavior2931// :107:27: error: use of undefined value here causes illegal behavior
2937// :107:27: note: when computing vector element at index '0'
2938// :107:27: error: use of undefined value here causes illegal behavior2932// :107:27: error: use of undefined value here causes illegal behavior
2939// :107:27: note: when computing vector element at index '0'
2940// :107:27: error: use of undefined value here causes illegal behavior2933// :107:27: error: use of undefined value here causes illegal behavior
2941// :107:27: note: when computing vector element at index '0'
2942// :107:27: error: use of undefined value here causes illegal behavior2934// :107:27: error: use of undefined value here causes illegal behavior
2943// :107:27: error: use of undefined value here causes illegal behavior2935// :107:27: error: use of undefined value here causes illegal behavior
2944// :107:27: error: use of undefined value here causes illegal behavior2936// :107:27: error: use of undefined value here causes illegal behavior
...@@ -2946,21 +2938,13 @@ const std = @import("std");...@@ -2946,21 +2938,13 @@ const std = @import("std");
2946// :107:27: error: use of undefined value here causes illegal behavior2938// :107:27: error: use of undefined value here causes illegal behavior
2947// :107:27: error: use of undefined value here causes illegal behavior2939// :107:27: error: use of undefined value here causes illegal behavior
2948// :107:27: error: use of undefined value here causes illegal behavior2940// :107:27: error: use of undefined value here causes illegal behavior
2949// :107:27: note: when computing vector element at index '1'
2950// :107:27: error: use of undefined value here causes illegal behavior2941// :107:27: error: use of undefined value here causes illegal behavior
2951// :107:27: note: when computing vector element at index '1'
2952// :107:27: error: use of undefined value here causes illegal behavior2942// :107:27: error: use of undefined value here causes illegal behavior
2953// :107:27: note: when computing vector element at index '1'
2954// :107:27: error: use of undefined value here causes illegal behavior2943// :107:27: error: use of undefined value here causes illegal behavior
2955// :107:27: note: when computing vector element at index '1'
2956// :107:27: error: use of undefined value here causes illegal behavior2944// :107:27: error: use of undefined value here causes illegal behavior
2957// :107:27: note: when computing vector element at index '0'
2958// :107:27: error: use of undefined value here causes illegal behavior2945// :107:27: error: use of undefined value here causes illegal behavior
2959// :107:27: note: when computing vector element at index '0'
2960// :107:27: error: use of undefined value here causes illegal behavior2946// :107:27: error: use of undefined value here causes illegal behavior
2961// :107:27: note: when computing vector element at index '0'
2962// :107:27: error: use of undefined value here causes illegal behavior2947// :107:27: error: use of undefined value here causes illegal behavior
2963// :107:27: note: when computing vector element at index '0'
2964// :107:27: error: use of undefined value here causes illegal behavior2948// :107:27: error: use of undefined value here causes illegal behavior
2965// :107:27: error: use of undefined value here causes illegal behavior2949// :107:27: error: use of undefined value here causes illegal behavior
2966// :107:27: error: use of undefined value here causes illegal behavior2950// :107:27: error: use of undefined value here causes illegal behavior
...@@ -2968,21 +2952,13 @@ const std = @import("std");...@@ -2968,21 +2952,13 @@ const std = @import("std");
2968// :107:27: error: use of undefined value here causes illegal behavior2952// :107:27: error: use of undefined value here causes illegal behavior
2969// :107:27: error: use of undefined value here causes illegal behavior2953// :107:27: error: use of undefined value here causes illegal behavior
2970// :107:27: error: use of undefined value here causes illegal behavior2954// :107:27: error: use of undefined value here causes illegal behavior
2971// :107:27: note: when computing vector element at index '1'
2972// :107:27: error: use of undefined value here causes illegal behavior2955// :107:27: error: use of undefined value here causes illegal behavior
2973// :107:27: note: when computing vector element at index '1'
2974// :107:27: error: use of undefined value here causes illegal behavior2956// :107:27: error: use of undefined value here causes illegal behavior
2975// :107:27: note: when computing vector element at index '1'
2976// :107:27: error: use of undefined value here causes illegal behavior2957// :107:27: error: use of undefined value here causes illegal behavior
2977// :107:27: note: when computing vector element at index '1'
2978// :107:27: error: use of undefined value here causes illegal behavior2958// :107:27: error: use of undefined value here causes illegal behavior
2979// :107:27: note: when computing vector element at index '0'
2980// :107:27: error: use of undefined value here causes illegal behavior2959// :107:27: error: use of undefined value here causes illegal behavior
2981// :107:27: note: when computing vector element at index '0'
2982// :107:27: error: use of undefined value here causes illegal behavior2960// :107:27: error: use of undefined value here causes illegal behavior
2983// :107:27: note: when computing vector element at index '0'
2984// :107:27: error: use of undefined value here causes illegal behavior2961// :107:27: error: use of undefined value here causes illegal behavior
2985// :107:27: note: when computing vector element at index '0'
2986// :107:27: error: use of undefined value here causes illegal behavior2962// :107:27: error: use of undefined value here causes illegal behavior
2987// :107:27: error: use of undefined value here causes illegal behavior2963// :107:27: error: use of undefined value here causes illegal behavior
2988// :107:27: error: use of undefined value here causes illegal behavior2964// :107:27: error: use of undefined value here causes illegal behavior
...@@ -2990,21 +2966,13 @@ const std = @import("std");...@@ -2990,21 +2966,13 @@ const std = @import("std");
2990// :107:27: error: use of undefined value here causes illegal behavior2966// :107:27: error: use of undefined value here causes illegal behavior
2991// :107:27: error: use of undefined value here causes illegal behavior2967// :107:27: error: use of undefined value here causes illegal behavior
2992// :107:27: error: use of undefined value here causes illegal behavior2968// :107:27: error: use of undefined value here causes illegal behavior
2993// :107:27: note: when computing vector element at index '1'
2994// :107:27: error: use of undefined value here causes illegal behavior2969// :107:27: error: use of undefined value here causes illegal behavior
2995// :107:27: note: when computing vector element at index '1'
2996// :107:27: error: use of undefined value here causes illegal behavior2970// :107:27: error: use of undefined value here causes illegal behavior
2997// :107:27: note: when computing vector element at index '1'
2998// :107:27: error: use of undefined value here causes illegal behavior2971// :107:27: error: use of undefined value here causes illegal behavior
2999// :107:27: note: when computing vector element at index '1'
3000// :107:27: error: use of undefined value here causes illegal behavior2972// :107:27: error: use of undefined value here causes illegal behavior
3001// :107:27: note: when computing vector element at index '0'
3002// :107:27: error: use of undefined value here causes illegal behavior2973// :107:27: error: use of undefined value here causes illegal behavior
3003// :107:27: note: when computing vector element at index '0'
3004// :107:27: error: use of undefined value here causes illegal behavior2974// :107:27: error: use of undefined value here causes illegal behavior
3005// :107:27: note: when computing vector element at index '0'
3006// :107:27: error: use of undefined value here causes illegal behavior2975// :107:27: error: use of undefined value here causes illegal behavior
3007// :107:27: note: when computing vector element at index '0'
3008// :107:27: error: use of undefined value here causes illegal behavior2976// :107:27: error: use of undefined value here causes illegal behavior
3009// :107:27: error: use of undefined value here causes illegal behavior2977// :107:27: error: use of undefined value here causes illegal behavior
3010// :107:27: error: use of undefined value here causes illegal behavior2978// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3012,13 +2980,9 @@ const std = @import("std");...@@ -3012,13 +2980,9 @@ const std = @import("std");
3012// :107:27: error: use of undefined value here causes illegal behavior2980// :107:27: error: use of undefined value here causes illegal behavior
3013// :107:27: error: use of undefined value here causes illegal behavior2981// :107:27: error: use of undefined value here causes illegal behavior
3014// :107:27: error: use of undefined value here causes illegal behavior2982// :107:27: error: use of undefined value here causes illegal behavior
3015// :107:27: note: when computing vector element at index '1'
3016// :107:27: error: use of undefined value here causes illegal behavior2983// :107:27: error: use of undefined value here causes illegal behavior
3017// :107:27: note: when computing vector element at index '1'
3018// :107:27: error: use of undefined value here causes illegal behavior2984// :107:27: error: use of undefined value here causes illegal behavior
3019// :107:27: note: when computing vector element at index '1'
3020// :107:27: error: use of undefined value here causes illegal behavior2985// :107:27: error: use of undefined value here causes illegal behavior
3021// :107:27: note: when computing vector element at index '1'
3022// :107:27: error: use of undefined value here causes illegal behavior2986// :107:27: error: use of undefined value here causes illegal behavior
3023// :107:27: note: when computing vector element at index '0'2987// :107:27: note: when computing vector element at index '0'
3024// :107:27: error: use of undefined value here causes illegal behavior2988// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3028,19 +2992,21 @@ const std = @import("std");...@@ -3028,19 +2992,21 @@ const std = @import("std");
3028// :107:27: error: use of undefined value here causes illegal behavior2992// :107:27: error: use of undefined value here causes illegal behavior
3029// :107:27: note: when computing vector element at index '0'2993// :107:27: note: when computing vector element at index '0'
3030// :107:27: error: use of undefined value here causes illegal behavior2994// :107:27: error: use of undefined value here causes illegal behavior
2995// :107:27: note: when computing vector element at index '0'
3031// :107:27: error: use of undefined value here causes illegal behavior2996// :107:27: error: use of undefined value here causes illegal behavior
2997// :107:27: note: when computing vector element at index '0'
3032// :107:27: error: use of undefined value here causes illegal behavior2998// :107:27: error: use of undefined value here causes illegal behavior
2999// :107:27: note: when computing vector element at index '0'
3033// :107:27: error: use of undefined value here causes illegal behavior3000// :107:27: error: use of undefined value here causes illegal behavior
3001// :107:27: note: when computing vector element at index '0'
3034// :107:27: error: use of undefined value here causes illegal behavior3002// :107:27: error: use of undefined value here causes illegal behavior
3003// :107:27: note: when computing vector element at index '0'
3035// :107:27: error: use of undefined value here causes illegal behavior3004// :107:27: error: use of undefined value here causes illegal behavior
3005// :107:27: note: when computing vector element at index '0'
3036// :107:27: error: use of undefined value here causes illegal behavior3006// :107:27: error: use of undefined value here causes illegal behavior
3037// :107:27: note: when computing vector element at index '1'3007// :107:27: note: when computing vector element at index '0'
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'
3042// :107:27: error: use of undefined value here causes illegal behavior3008// :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'
3044// :107:27: error: use of undefined value here causes illegal behavior3010// :107:27: error: use of undefined value here causes illegal behavior
3045// :107:27: note: when computing vector element at index '0'3011// :107:27: note: when computing vector element at index '0'
3046// :107:27: error: use of undefined value here causes illegal behavior3012// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3050,19 +3016,25 @@ const std = @import("std");...@@ -3050,19 +3016,25 @@ const std = @import("std");
3050// :107:27: error: use of undefined value here causes illegal behavior3016// :107:27: error: use of undefined value here causes illegal behavior
3051// :107:27: note: when computing vector element at index '0'3017// :107:27: note: when computing vector element at index '0'
3052// :107:27: error: use of undefined value here causes illegal behavior3018// :107:27: error: use of undefined value here causes illegal behavior
3019// :107:27: note: when computing vector element at index '0'
3053// :107:27: error: use of undefined value here causes illegal behavior3020// :107:27: error: use of undefined value here causes illegal behavior
3021// :107:27: note: when computing vector element at index '0'
3054// :107:27: error: use of undefined value here causes illegal behavior3022// :107:27: error: use of undefined value here causes illegal behavior
3023// :107:27: note: when computing vector element at index '0'
3055// :107:27: error: use of undefined value here causes illegal behavior3024// :107:27: error: use of undefined value here causes illegal behavior
3025// :107:27: note: when computing vector element at index '0'
3056// :107:27: error: use of undefined value here causes illegal behavior3026// :107:27: error: use of undefined value here causes illegal behavior
3027// :107:27: note: when computing vector element at index '0'
3057// :107:27: error: use of undefined value here causes illegal behavior3028// :107:27: error: use of undefined value here causes illegal behavior
3029// :107:27: note: when computing vector element at index '0'
3058// :107:27: error: use of undefined value here causes illegal behavior3030// :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'
3060// :107:27: error: use of undefined value here causes illegal behavior3032// :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'
3062// :107:27: error: use of undefined value here causes illegal behavior3034// :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'
3064// :107:27: error: use of undefined value here causes illegal behavior3036// :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'
3066// :107:27: error: use of undefined value here causes illegal behavior3038// :107:27: error: use of undefined value here causes illegal behavior
3067// :107:27: note: when computing vector element at index '0'3039// :107:27: note: when computing vector element at index '0'
3068// :107:27: error: use of undefined value here causes illegal behavior3040// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3072,19 +3044,25 @@ const std = @import("std");...@@ -3072,19 +3044,25 @@ const std = @import("std");
3072// :107:27: error: use of undefined value here causes illegal behavior3044// :107:27: error: use of undefined value here causes illegal behavior
3073// :107:27: note: when computing vector element at index '0'3045// :107:27: note: when computing vector element at index '0'
3074// :107:27: error: use of undefined value here causes illegal behavior3046// :107:27: error: use of undefined value here causes illegal behavior
3047// :107:27: note: when computing vector element at index '0'
3075// :107:27: error: use of undefined value here causes illegal behavior3048// :107:27: error: use of undefined value here causes illegal behavior
3049// :107:27: note: when computing vector element at index '0'
3076// :107:27: error: use of undefined value here causes illegal behavior3050// :107:27: error: use of undefined value here causes illegal behavior
3051// :107:27: note: when computing vector element at index '0'
3077// :107:27: error: use of undefined value here causes illegal behavior3052// :107:27: error: use of undefined value here causes illegal behavior
3053// :107:27: note: when computing vector element at index '0'
3078// :107:27: error: use of undefined value here causes illegal behavior3054// :107:27: error: use of undefined value here causes illegal behavior
3055// :107:27: note: when computing vector element at index '0'
3079// :107:27: error: use of undefined value here causes illegal behavior3056// :107:27: error: use of undefined value here causes illegal behavior
3057// :107:27: note: when computing vector element at index '0'
3080// :107:27: error: use of undefined value here causes illegal behavior3058// :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'
3082// :107:27: error: use of undefined value here causes illegal behavior3060// :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'
3084// :107:27: error: use of undefined value here causes illegal behavior3062// :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'
3086// :107:27: error: use of undefined value here causes illegal behavior3064// :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'
3088// :107:27: error: use of undefined value here causes illegal behavior3066// :107:27: error: use of undefined value here causes illegal behavior
3089// :107:27: note: when computing vector element at index '0'3067// :107:27: note: when computing vector element at index '0'
3090// :107:27: error: use of undefined value here causes illegal behavior3068// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3094,11 +3072,17 @@ const std = @import("std");...@@ -3094,11 +3072,17 @@ const std = @import("std");
3094// :107:27: error: use of undefined value here causes illegal behavior3072// :107:27: error: use of undefined value here causes illegal behavior
3095// :107:27: note: when computing vector element at index '0'3073// :107:27: note: when computing vector element at index '0'
3096// :107:27: error: use of undefined value here causes illegal behavior3074// :107:27: error: use of undefined value here causes illegal behavior
3075// :107:27: note: when computing vector element at index '1'
3097// :107:27: error: use of undefined value here causes illegal behavior3076// :107:27: error: use of undefined value here causes illegal behavior
3077// :107:27: note: when computing vector element at index '1'
3098// :107:27: error: use of undefined value here causes illegal behavior3078// :107:27: error: use of undefined value here causes illegal behavior
3079// :107:27: note: when computing vector element at index '1'
3099// :107:27: error: use of undefined value here causes illegal behavior3080// :107:27: error: use of undefined value here causes illegal behavior
3081// :107:27: note: when computing vector element at index '1'
3100// :107:27: error: use of undefined value here causes illegal behavior3082// :107:27: error: use of undefined value here causes illegal behavior
3083// :107:27: note: when computing vector element at index '1'
3101// :107:27: error: use of undefined value here causes illegal behavior3084// :107:27: error: use of undefined value here causes illegal behavior
3085// :107:27: note: when computing vector element at index '1'
3102// :107:27: error: use of undefined value here causes illegal behavior3086// :107:27: error: use of undefined value here causes illegal behavior
3103// :107:27: note: when computing vector element at index '1'3087// :107:27: note: when computing vector element at index '1'
3104// :107:27: error: use of undefined value here causes illegal behavior3088// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3108,19 +3092,25 @@ const std = @import("std");...@@ -3108,19 +3092,25 @@ const std = @import("std");
3108// :107:27: error: use of undefined value here causes illegal behavior3092// :107:27: error: use of undefined value here causes illegal behavior
3109// :107:27: note: when computing vector element at index '1'3093// :107:27: note: when computing vector element at index '1'
3110// :107:27: error: use of undefined value here causes illegal behavior3094// :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'
3112// :107:27: error: use of undefined value here causes illegal behavior3096// :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'
3114// :107:27: error: use of undefined value here causes illegal behavior3098// :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'
3116// :107:27: error: use of undefined value here causes illegal behavior3100// :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'
3118// :107:27: error: use of undefined value here causes illegal behavior3102// :107:27: error: use of undefined value here causes illegal behavior
3103// :107:27: note: when computing vector element at index '1'
3119// :107:27: error: use of undefined value here causes illegal behavior3104// :107:27: error: use of undefined value here causes illegal behavior
3105// :107:27: note: when computing vector element at index '1'
3120// :107:27: error: use of undefined value here causes illegal behavior3106// :107:27: error: use of undefined value here causes illegal behavior
3107// :107:27: note: when computing vector element at index '1'
3121// :107:27: error: use of undefined value here causes illegal behavior3108// :107:27: error: use of undefined value here causes illegal behavior
3109// :107:27: note: when computing vector element at index '1'
3122// :107:27: error: use of undefined value here causes illegal behavior3110// :107:27: error: use of undefined value here causes illegal behavior
3111// :107:27: note: when computing vector element at index '1'
3123// :107:27: error: use of undefined value here causes illegal behavior3112// :107:27: error: use of undefined value here causes illegal behavior
3113// :107:27: note: when computing vector element at index '1'
3124// :107:27: error: use of undefined value here causes illegal behavior3114// :107:27: error: use of undefined value here causes illegal behavior
3125// :107:27: note: when computing vector element at index '1'3115// :107:27: note: when computing vector element at index '1'
3126// :107:27: error: use of undefined value here causes illegal behavior3116// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3130,19 +3120,29 @@ const std = @import("std");...@@ -3130,19 +3120,29 @@ const std = @import("std");
3130// :107:27: error: use of undefined value here causes illegal behavior3120// :107:27: error: use of undefined value here causes illegal behavior
3131// :107:27: note: when computing vector element at index '1'3121// :107:27: note: when computing vector element at index '1'
3132// :107:27: error: use of undefined value here causes illegal behavior3122// :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'
3134// :107:27: error: use of undefined value here causes illegal behavior3124// :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'
3136// :107:27: error: use of undefined value here causes illegal behavior3126// :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'
3138// :107:27: error: use of undefined value here causes illegal behavior3128// :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'
3140// :107:27: error: use of undefined value here causes illegal behavior3134// :107:27: error: use of undefined value here causes illegal behavior
3135// :107:27: note: when computing vector element at index '1'
3141// :107:27: error: use of undefined value here causes illegal behavior3136// :107:27: error: use of undefined value here causes illegal behavior
3137// :107:27: note: when computing vector element at index '1'
3142// :107:27: error: use of undefined value here causes illegal behavior3138// :107:27: error: use of undefined value here causes illegal behavior
3139// :107:27: note: when computing vector element at index '1'
3143// :107:27: error: use of undefined value here causes illegal behavior3140// :107:27: error: use of undefined value here causes illegal behavior
3141// :107:27: note: when computing vector element at index '1'
3144// :107:27: error: use of undefined value here causes illegal behavior3142// :107:27: error: use of undefined value here causes illegal behavior
3143// :107:27: note: when computing vector element at index '1'
3145// :107:27: error: use of undefined value here causes illegal behavior3144// :107:27: error: use of undefined value here causes illegal behavior
3145// :107:27: note: when computing vector element at index '1'
3146// :107:27: error: use of undefined value here causes illegal behavior3146// :107:27: error: use of undefined value here causes illegal behavior
3147// :107:27: note: when computing vector element at index '1'3147// :107:27: note: when computing vector element at index '1'
3148// :107:27: error: use of undefined value here causes illegal behavior3148// :107:27: error: use of undefined value here causes illegal behavior
...@@ -3152,13 +3152,13 @@ const std = @import("std");...@@ -3152,13 +3152,13 @@ const std = @import("std");
3152// :107:27: error: use of undefined value here causes illegal behavior3152// :107:27: error: use of undefined value here causes illegal behavior
3153// :107:27: note: when computing vector element at index '1'3153// :107:27: note: when computing vector element at index '1'
3154// :107:27: error: use of undefined value here causes illegal behavior3154// :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'
3156// :107:27: error: use of undefined value here causes illegal behavior3156// :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'
3158// :107:27: error: use of undefined value here causes illegal behavior3158// :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'
3160// :107:27: error: use of undefined value here causes illegal behavior3160// :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'
3162// :111:22: error: use of undefined value here causes illegal behavior3162// :111:22: error: use of undefined value here causes illegal behavior
3163// :111:22: error: use of undefined value here causes illegal behavior3163// :111:22: error: use of undefined value here causes illegal behavior
3164// :111:22: error: use of undefined value here causes illegal behavior3164// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3166,21 +3166,13 @@ const std = @import("std");...@@ -3166,21 +3166,13 @@ const std = @import("std");
3166// :111:22: error: use of undefined value here causes illegal behavior3166// :111:22: error: use of undefined value here causes illegal behavior
3167// :111:22: error: use of undefined value here causes illegal behavior3167// :111:22: error: use of undefined value here causes illegal behavior
3168// :111:22: error: use of undefined value here causes illegal behavior3168// :111:22: error: use of undefined value here causes illegal behavior
3169// :111:22: note: when computing vector element at index '1'
3170// :111:22: error: use of undefined value here causes illegal behavior3169// :111:22: error: use of undefined value here causes illegal behavior
3171// :111:22: note: when computing vector element at index '1'
3172// :111:22: error: use of undefined value here causes illegal behavior3170// :111:22: error: use of undefined value here causes illegal behavior
3173// :111:22: note: when computing vector element at index '1'
3174// :111:22: error: use of undefined value here causes illegal behavior3171// :111:22: error: use of undefined value here causes illegal behavior
3175// :111:22: note: when computing vector element at index '1'
3176// :111:22: error: use of undefined value here causes illegal behavior3172// :111:22: error: use of undefined value here causes illegal behavior
3177// :111:22: note: when computing vector element at index '0'
3178// :111:22: error: use of undefined value here causes illegal behavior3173// :111:22: error: use of undefined value here causes illegal behavior
3179// :111:22: note: when computing vector element at index '0'
3180// :111:22: error: use of undefined value here causes illegal behavior3174// :111:22: error: use of undefined value here causes illegal behavior
3181// :111:22: note: when computing vector element at index '0'
3182// :111:22: error: use of undefined value here causes illegal behavior3175// :111:22: error: use of undefined value here causes illegal behavior
3183// :111:22: note: when computing vector element at index '0'
3184// :111:22: error: use of undefined value here causes illegal behavior3176// :111:22: error: use of undefined value here causes illegal behavior
3185// :111:22: error: use of undefined value here causes illegal behavior3177// :111:22: error: use of undefined value here causes illegal behavior
3186// :111:22: error: use of undefined value here causes illegal behavior3178// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3188,21 +3180,13 @@ const std = @import("std");...@@ -3188,21 +3180,13 @@ const std = @import("std");
3188// :111:22: error: use of undefined value here causes illegal behavior3180// :111:22: error: use of undefined value here causes illegal behavior
3189// :111:22: error: use of undefined value here causes illegal behavior3181// :111:22: error: use of undefined value here causes illegal behavior
3190// :111:22: error: use of undefined value here causes illegal behavior3182// :111:22: error: use of undefined value here causes illegal behavior
3191// :111:22: note: when computing vector element at index '1'
3192// :111:22: error: use of undefined value here causes illegal behavior3183// :111:22: error: use of undefined value here causes illegal behavior
3193// :111:22: note: when computing vector element at index '1'
3194// :111:22: error: use of undefined value here causes illegal behavior3184// :111:22: error: use of undefined value here causes illegal behavior
3195// :111:22: note: when computing vector element at index '1'
3196// :111:22: error: use of undefined value here causes illegal behavior3185// :111:22: error: use of undefined value here causes illegal behavior
3197// :111:22: note: when computing vector element at index '1'
3198// :111:22: error: use of undefined value here causes illegal behavior3186// :111:22: error: use of undefined value here causes illegal behavior
3199// :111:22: note: when computing vector element at index '0'
3200// :111:22: error: use of undefined value here causes illegal behavior3187// :111:22: error: use of undefined value here causes illegal behavior
3201// :111:22: note: when computing vector element at index '0'
3202// :111:22: error: use of undefined value here causes illegal behavior3188// :111:22: error: use of undefined value here causes illegal behavior
3203// :111:22: note: when computing vector element at index '0'
3204// :111:22: error: use of undefined value here causes illegal behavior3189// :111:22: error: use of undefined value here causes illegal behavior
3205// :111:22: note: when computing vector element at index '0'
3206// :111:22: error: use of undefined value here causes illegal behavior3190// :111:22: error: use of undefined value here causes illegal behavior
3207// :111:22: error: use of undefined value here causes illegal behavior3191// :111:22: error: use of undefined value here causes illegal behavior
3208// :111:22: error: use of undefined value here causes illegal behavior3192// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3210,21 +3194,13 @@ const std = @import("std");...@@ -3210,21 +3194,13 @@ const std = @import("std");
3210// :111:22: error: use of undefined value here causes illegal behavior3194// :111:22: error: use of undefined value here causes illegal behavior
3211// :111:22: error: use of undefined value here causes illegal behavior3195// :111:22: error: use of undefined value here causes illegal behavior
3212// :111:22: error: use of undefined value here causes illegal behavior3196// :111:22: error: use of undefined value here causes illegal behavior
3213// :111:22: note: when computing vector element at index '1'
3214// :111:22: error: use of undefined value here causes illegal behavior3197// :111:22: error: use of undefined value here causes illegal behavior
3215// :111:22: note: when computing vector element at index '1'
3216// :111:22: error: use of undefined value here causes illegal behavior3198// :111:22: error: use of undefined value here causes illegal behavior
3217// :111:22: note: when computing vector element at index '1'
3218// :111:22: error: use of undefined value here causes illegal behavior3199// :111:22: error: use of undefined value here causes illegal behavior
3219// :111:22: note: when computing vector element at index '1'
3220// :111:22: error: use of undefined value here causes illegal behavior3200// :111:22: error: use of undefined value here causes illegal behavior
3221// :111:22: note: when computing vector element at index '0'
3222// :111:22: error: use of undefined value here causes illegal behavior3201// :111:22: error: use of undefined value here causes illegal behavior
3223// :111:22: note: when computing vector element at index '0'
3224// :111:22: error: use of undefined value here causes illegal behavior3202// :111:22: error: use of undefined value here causes illegal behavior
3225// :111:22: note: when computing vector element at index '0'
3226// :111:22: error: use of undefined value here causes illegal behavior3203// :111:22: error: use of undefined value here causes illegal behavior
3227// :111:22: note: when computing vector element at index '0'
3228// :111:22: error: use of undefined value here causes illegal behavior3204// :111:22: error: use of undefined value here causes illegal behavior
3229// :111:22: error: use of undefined value here causes illegal behavior3205// :111:22: error: use of undefined value here causes illegal behavior
3230// :111:22: error: use of undefined value here causes illegal behavior3206// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3232,21 +3208,13 @@ const std = @import("std");...@@ -3232,21 +3208,13 @@ const std = @import("std");
3232// :111:22: error: use of undefined value here causes illegal behavior3208// :111:22: error: use of undefined value here causes illegal behavior
3233// :111:22: error: use of undefined value here causes illegal behavior3209// :111:22: error: use of undefined value here causes illegal behavior
3234// :111:22: error: use of undefined value here causes illegal behavior3210// :111:22: error: use of undefined value here causes illegal behavior
3235// :111:22: note: when computing vector element at index '1'
3236// :111:22: error: use of undefined value here causes illegal behavior3211// :111:22: error: use of undefined value here causes illegal behavior
3237// :111:22: note: when computing vector element at index '1'
3238// :111:22: error: use of undefined value here causes illegal behavior3212// :111:22: error: use of undefined value here causes illegal behavior
3239// :111:22: note: when computing vector element at index '1'
3240// :111:22: error: use of undefined value here causes illegal behavior3213// :111:22: error: use of undefined value here causes illegal behavior
3241// :111:22: note: when computing vector element at index '1'
3242// :111:22: error: use of undefined value here causes illegal behavior3214// :111:22: error: use of undefined value here causes illegal behavior
3243// :111:22: note: when computing vector element at index '0'
3244// :111:22: error: use of undefined value here causes illegal behavior3215// :111:22: error: use of undefined value here causes illegal behavior
3245// :111:22: note: when computing vector element at index '0'
3246// :111:22: error: use of undefined value here causes illegal behavior3216// :111:22: error: use of undefined value here causes illegal behavior
3247// :111:22: note: when computing vector element at index '0'
3248// :111:22: error: use of undefined value here causes illegal behavior3217// :111:22: error: use of undefined value here causes illegal behavior
3249// :111:22: note: when computing vector element at index '0'
3250// :111:22: error: use of undefined value here causes illegal behavior3218// :111:22: error: use of undefined value here causes illegal behavior
3251// :111:22: error: use of undefined value here causes illegal behavior3219// :111:22: error: use of undefined value here causes illegal behavior
3252// :111:22: error: use of undefined value here causes illegal behavior3220// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3254,13 +3222,9 @@ const std = @import("std");...@@ -3254,13 +3222,9 @@ const std = @import("std");
3254// :111:22: error: use of undefined value here causes illegal behavior3222// :111:22: error: use of undefined value here causes illegal behavior
3255// :111:22: error: use of undefined value here causes illegal behavior3223// :111:22: error: use of undefined value here causes illegal behavior
3256// :111:22: error: use of undefined value here causes illegal behavior3224// :111:22: error: use of undefined value here causes illegal behavior
3257// :111:22: note: when computing vector element at index '1'
3258// :111:22: error: use of undefined value here causes illegal behavior3225// :111:22: error: use of undefined value here causes illegal behavior
3259// :111:22: note: when computing vector element at index '1'
3260// :111:22: error: use of undefined value here causes illegal behavior3226// :111:22: error: use of undefined value here causes illegal behavior
3261// :111:22: note: when computing vector element at index '1'
3262// :111:22: error: use of undefined value here causes illegal behavior3227// :111:22: error: use of undefined value here causes illegal behavior
3263// :111:22: note: when computing vector element at index '1'
3264// :111:22: error: use of undefined value here causes illegal behavior3228// :111:22: error: use of undefined value here causes illegal behavior
3265// :111:22: note: when computing vector element at index '0'3229// :111:22: note: when computing vector element at index '0'
3266// :111:22: error: use of undefined value here causes illegal behavior3230// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3270,19 +3234,21 @@ const std = @import("std");...@@ -3270,19 +3234,21 @@ const std = @import("std");
3270// :111:22: error: use of undefined value here causes illegal behavior3234// :111:22: error: use of undefined value here causes illegal behavior
3271// :111:22: note: when computing vector element at index '0'3235// :111:22: note: when computing vector element at index '0'
3272// :111:22: error: use of undefined value here causes illegal behavior3236// :111:22: error: use of undefined value here causes illegal behavior
3237// :111:22: note: when computing vector element at index '0'
3273// :111:22: error: use of undefined value here causes illegal behavior3238// :111:22: error: use of undefined value here causes illegal behavior
3239// :111:22: note: when computing vector element at index '0'
3274// :111:22: error: use of undefined value here causes illegal behavior3240// :111:22: error: use of undefined value here causes illegal behavior
3241// :111:22: note: when computing vector element at index '0'
3275// :111:22: error: use of undefined value here causes illegal behavior3242// :111:22: error: use of undefined value here causes illegal behavior
3243// :111:22: note: when computing vector element at index '0'
3276// :111:22: error: use of undefined value here causes illegal behavior3244// :111:22: error: use of undefined value here causes illegal behavior
3245// :111:22: note: when computing vector element at index '0'
3277// :111:22: error: use of undefined value here causes illegal behavior3246// :111:22: error: use of undefined value here causes illegal behavior
3247// :111:22: note: when computing vector element at index '0'
3278// :111:22: error: use of undefined value here causes illegal behavior3248// :111:22: error: use of undefined value here causes illegal behavior
3279// :111:22: note: when computing vector element at index '1'3249// :111:22: note: when computing vector element at index '0'
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'
3284// :111:22: error: use of undefined value here causes illegal behavior3250// :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'
3286// :111:22: error: use of undefined value here causes illegal behavior3252// :111:22: error: use of undefined value here causes illegal behavior
3287// :111:22: note: when computing vector element at index '0'3253// :111:22: note: when computing vector element at index '0'
3288// :111:22: error: use of undefined value here causes illegal behavior3254// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3292,19 +3258,25 @@ const std = @import("std");...@@ -3292,19 +3258,25 @@ const std = @import("std");
3292// :111:22: error: use of undefined value here causes illegal behavior3258// :111:22: error: use of undefined value here causes illegal behavior
3293// :111:22: note: when computing vector element at index '0'3259// :111:22: note: when computing vector element at index '0'
3294// :111:22: error: use of undefined value here causes illegal behavior3260// :111:22: error: use of undefined value here causes illegal behavior
3261// :111:22: note: when computing vector element at index '0'
3295// :111:22: error: use of undefined value here causes illegal behavior3262// :111:22: error: use of undefined value here causes illegal behavior
3263// :111:22: note: when computing vector element at index '0'
3296// :111:22: error: use of undefined value here causes illegal behavior3264// :111:22: error: use of undefined value here causes illegal behavior
3265// :111:22: note: when computing vector element at index '0'
3297// :111:22: error: use of undefined value here causes illegal behavior3266// :111:22: error: use of undefined value here causes illegal behavior
3267// :111:22: note: when computing vector element at index '0'
3298// :111:22: error: use of undefined value here causes illegal behavior3268// :111:22: error: use of undefined value here causes illegal behavior
3269// :111:22: note: when computing vector element at index '0'
3299// :111:22: error: use of undefined value here causes illegal behavior3270// :111:22: error: use of undefined value here causes illegal behavior
3271// :111:22: note: when computing vector element at index '0'
3300// :111:22: error: use of undefined value here causes illegal behavior3272// :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'
3302// :111:22: error: use of undefined value here causes illegal behavior3274// :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'
3304// :111:22: error: use of undefined value here causes illegal behavior3276// :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'
3306// :111:22: error: use of undefined value here causes illegal behavior3278// :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'
3308// :111:22: error: use of undefined value here causes illegal behavior3280// :111:22: error: use of undefined value here causes illegal behavior
3309// :111:22: note: when computing vector element at index '0'3281// :111:22: note: when computing vector element at index '0'
3310// :111:22: error: use of undefined value here causes illegal behavior3282// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3314,19 +3286,25 @@ const std = @import("std");...@@ -3314,19 +3286,25 @@ const std = @import("std");
3314// :111:22: error: use of undefined value here causes illegal behavior3286// :111:22: error: use of undefined value here causes illegal behavior
3315// :111:22: note: when computing vector element at index '0'3287// :111:22: note: when computing vector element at index '0'
3316// :111:22: error: use of undefined value here causes illegal behavior3288// :111:22: error: use of undefined value here causes illegal behavior
3289// :111:22: note: when computing vector element at index '0'
3317// :111:22: error: use of undefined value here causes illegal behavior3290// :111:22: error: use of undefined value here causes illegal behavior
3291// :111:22: note: when computing vector element at index '0'
3318// :111:22: error: use of undefined value here causes illegal behavior3292// :111:22: error: use of undefined value here causes illegal behavior
3293// :111:22: note: when computing vector element at index '0'
3319// :111:22: error: use of undefined value here causes illegal behavior3294// :111:22: error: use of undefined value here causes illegal behavior
3295// :111:22: note: when computing vector element at index '0'
3320// :111:22: error: use of undefined value here causes illegal behavior3296// :111:22: error: use of undefined value here causes illegal behavior
3297// :111:22: note: when computing vector element at index '0'
3321// :111:22: error: use of undefined value here causes illegal behavior3298// :111:22: error: use of undefined value here causes illegal behavior
3299// :111:22: note: when computing vector element at index '0'
3322// :111:22: error: use of undefined value here causes illegal behavior3300// :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'
3324// :111:22: error: use of undefined value here causes illegal behavior3302// :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'
3326// :111:22: error: use of undefined value here causes illegal behavior3304// :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'
3328// :111:22: error: use of undefined value here causes illegal behavior3306// :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'
3330// :111:22: error: use of undefined value here causes illegal behavior3308// :111:22: error: use of undefined value here causes illegal behavior
3331// :111:22: note: when computing vector element at index '0'3309// :111:22: note: when computing vector element at index '0'
3332// :111:22: error: use of undefined value here causes illegal behavior3310// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3336,11 +3314,17 @@ const std = @import("std");...@@ -3336,11 +3314,17 @@ const std = @import("std");
3336// :111:22: error: use of undefined value here causes illegal behavior3314// :111:22: error: use of undefined value here causes illegal behavior
3337// :111:22: note: when computing vector element at index '0'3315// :111:22: note: when computing vector element at index '0'
3338// :111:22: error: use of undefined value here causes illegal behavior3316// :111:22: error: use of undefined value here causes illegal behavior
3317// :111:22: note: when computing vector element at index '1'
3339// :111:22: error: use of undefined value here causes illegal behavior3318// :111:22: error: use of undefined value here causes illegal behavior
3319// :111:22: note: when computing vector element at index '1'
3340// :111:22: error: use of undefined value here causes illegal behavior3320// :111:22: error: use of undefined value here causes illegal behavior
3321// :111:22: note: when computing vector element at index '1'
3341// :111:22: error: use of undefined value here causes illegal behavior3322// :111:22: error: use of undefined value here causes illegal behavior
3323// :111:22: note: when computing vector element at index '1'
3342// :111:22: error: use of undefined value here causes illegal behavior3324// :111:22: error: use of undefined value here causes illegal behavior
3325// :111:22: note: when computing vector element at index '1'
3343// :111:22: error: use of undefined value here causes illegal behavior3326// :111:22: error: use of undefined value here causes illegal behavior
3327// :111:22: note: when computing vector element at index '1'
3344// :111:22: error: use of undefined value here causes illegal behavior3328// :111:22: error: use of undefined value here causes illegal behavior
3345// :111:22: note: when computing vector element at index '1'3329// :111:22: note: when computing vector element at index '1'
3346// :111:22: error: use of undefined value here causes illegal behavior3330// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3350,19 +3334,25 @@ const std = @import("std");...@@ -3350,19 +3334,25 @@ const std = @import("std");
3350// :111:22: error: use of undefined value here causes illegal behavior3334// :111:22: error: use of undefined value here causes illegal behavior
3351// :111:22: note: when computing vector element at index '1'3335// :111:22: note: when computing vector element at index '1'
3352// :111:22: error: use of undefined value here causes illegal behavior3336// :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'
3354// :111:22: error: use of undefined value here causes illegal behavior3338// :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'
3356// :111:22: error: use of undefined value here causes illegal behavior3340// :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'
3358// :111:22: error: use of undefined value here causes illegal behavior3342// :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'
3360// :111:22: error: use of undefined value here causes illegal behavior3344// :111:22: error: use of undefined value here causes illegal behavior
3345// :111:22: note: when computing vector element at index '1'
3361// :111:22: error: use of undefined value here causes illegal behavior3346// :111:22: error: use of undefined value here causes illegal behavior
3347// :111:22: note: when computing vector element at index '1'
3362// :111:22: error: use of undefined value here causes illegal behavior3348// :111:22: error: use of undefined value here causes illegal behavior
3349// :111:22: note: when computing vector element at index '1'
3363// :111:22: error: use of undefined value here causes illegal behavior3350// :111:22: error: use of undefined value here causes illegal behavior
3351// :111:22: note: when computing vector element at index '1'
3364// :111:22: error: use of undefined value here causes illegal behavior3352// :111:22: error: use of undefined value here causes illegal behavior
3353// :111:22: note: when computing vector element at index '1'
3365// :111:22: error: use of undefined value here causes illegal behavior3354// :111:22: error: use of undefined value here causes illegal behavior
3355// :111:22: note: when computing vector element at index '1'
3366// :111:22: error: use of undefined value here causes illegal behavior3356// :111:22: error: use of undefined value here causes illegal behavior
3367// :111:22: note: when computing vector element at index '1'3357// :111:22: note: when computing vector element at index '1'
3368// :111:22: error: use of undefined value here causes illegal behavior3358// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3372,19 +3362,25 @@ const std = @import("std");...@@ -3372,19 +3362,25 @@ const std = @import("std");
3372// :111:22: error: use of undefined value here causes illegal behavior3362// :111:22: error: use of undefined value here causes illegal behavior
3373// :111:22: note: when computing vector element at index '1'3363// :111:22: note: when computing vector element at index '1'
3374// :111:22: error: use of undefined value here causes illegal behavior3364// :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'
3376// :111:22: error: use of undefined value here causes illegal behavior3366// :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'
3378// :111:22: error: use of undefined value here causes illegal behavior3368// :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'
3380// :111:22: error: use of undefined value here causes illegal behavior3370// :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'
3382// :111:22: error: use of undefined value here causes illegal behavior3372// :111:22: error: use of undefined value here causes illegal behavior
3373// :111:22: note: when computing vector element at index '1'
3383// :111:22: error: use of undefined value here causes illegal behavior3374// :111:22: error: use of undefined value here causes illegal behavior
3375// :111:22: note: when computing vector element at index '1'
3384// :111:22: error: use of undefined value here causes illegal behavior3376// :111:22: error: use of undefined value here causes illegal behavior
3377// :111:22: note: when computing vector element at index '1'
3385// :111:22: error: use of undefined value here causes illegal behavior3378// :111:22: error: use of undefined value here causes illegal behavior
3379// :111:22: note: when computing vector element at index '1'
3386// :111:22: error: use of undefined value here causes illegal behavior3380// :111:22: error: use of undefined value here causes illegal behavior
3381// :111:22: note: when computing vector element at index '1'
3387// :111:22: error: use of undefined value here causes illegal behavior3382// :111:22: error: use of undefined value here causes illegal behavior
3383// :111:22: note: when computing vector element at index '1'
3388// :111:22: error: use of undefined value here causes illegal behavior3384// :111:22: error: use of undefined value here causes illegal behavior
3389// :111:22: note: when computing vector element at index '1'3385// :111:22: note: when computing vector element at index '1'
3390// :111:22: error: use of undefined value here causes illegal behavior3386// :111:22: error: use of undefined value here causes illegal behavior
...@@ -3394,13 +3390,17 @@ const std = @import("std");...@@ -3394,13 +3390,17 @@ const std = @import("std");
3394// :111:22: error: use of undefined value here causes illegal behavior3390// :111:22: error: use of undefined value here causes illegal behavior
3395// :111:22: note: when computing vector element at index '1'3391// :111:22: note: when computing vector element at index '1'
3396// :111:22: error: use of undefined value here causes illegal behavior3392// :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'
3398// :111:22: error: use of undefined value here causes illegal behavior3394// :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'
3400// :111:22: error: use of undefined value here causes illegal behavior3396// :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'
3402// :111:22: error: use of undefined value here causes illegal behavior3398// :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'
3404// :115:22: error: use of undefined value here causes illegal behavior3404// :115:22: error: use of undefined value here causes illegal behavior
3405// :115:22: error: use of undefined value here causes illegal behavior3405// :115:22: error: use of undefined value here causes illegal behavior
3406// :115:22: error: use of undefined value here causes illegal behavior3406// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3408,21 +3408,13 @@ const std = @import("std");...@@ -3408,21 +3408,13 @@ const std = @import("std");
3408// :115:22: error: use of undefined value here causes illegal behavior3408// :115:22: error: use of undefined value here causes illegal behavior
3409// :115:22: error: use of undefined value here causes illegal behavior3409// :115:22: error: use of undefined value here causes illegal behavior
3410// :115:22: error: use of undefined value here causes illegal behavior3410// :115:22: error: use of undefined value here causes illegal behavior
3411// :115:22: note: when computing vector element at index '1'
3412// :115:22: error: use of undefined value here causes illegal behavior3411// :115:22: error: use of undefined value here causes illegal behavior
3413// :115:22: note: when computing vector element at index '1'
3414// :115:22: error: use of undefined value here causes illegal behavior3412// :115:22: error: use of undefined value here causes illegal behavior
3415// :115:22: note: when computing vector element at index '1'
3416// :115:22: error: use of undefined value here causes illegal behavior3413// :115:22: error: use of undefined value here causes illegal behavior
3417// :115:22: note: when computing vector element at index '1'
3418// :115:22: error: use of undefined value here causes illegal behavior3414// :115:22: error: use of undefined value here causes illegal behavior
3419// :115:22: note: when computing vector element at index '0'
3420// :115:22: error: use of undefined value here causes illegal behavior3415// :115:22: error: use of undefined value here causes illegal behavior
3421// :115:22: note: when computing vector element at index '0'
3422// :115:22: error: use of undefined value here causes illegal behavior3416// :115:22: error: use of undefined value here causes illegal behavior
3423// :115:22: note: when computing vector element at index '0'
3424// :115:22: error: use of undefined value here causes illegal behavior3417// :115:22: error: use of undefined value here causes illegal behavior
3425// :115:22: note: when computing vector element at index '0'
3426// :115:22: error: use of undefined value here causes illegal behavior3418// :115:22: error: use of undefined value here causes illegal behavior
3427// :115:22: error: use of undefined value here causes illegal behavior3419// :115:22: error: use of undefined value here causes illegal behavior
3428// :115:22: error: use of undefined value here causes illegal behavior3420// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3430,21 +3422,13 @@ const std = @import("std");...@@ -3430,21 +3422,13 @@ const std = @import("std");
3430// :115:22: error: use of undefined value here causes illegal behavior3422// :115:22: error: use of undefined value here causes illegal behavior
3431// :115:22: error: use of undefined value here causes illegal behavior3423// :115:22: error: use of undefined value here causes illegal behavior
3432// :115:22: error: use of undefined value here causes illegal behavior3424// :115:22: error: use of undefined value here causes illegal behavior
3433// :115:22: note: when computing vector element at index '1'
3434// :115:22: error: use of undefined value here causes illegal behavior3425// :115:22: error: use of undefined value here causes illegal behavior
3435// :115:22: note: when computing vector element at index '1'
3436// :115:22: error: use of undefined value here causes illegal behavior3426// :115:22: error: use of undefined value here causes illegal behavior
3437// :115:22: note: when computing vector element at index '1'
3438// :115:22: error: use of undefined value here causes illegal behavior3427// :115:22: error: use of undefined value here causes illegal behavior
3439// :115:22: note: when computing vector element at index '1'
3440// :115:22: error: use of undefined value here causes illegal behavior3428// :115:22: error: use of undefined value here causes illegal behavior
3441// :115:22: note: when computing vector element at index '0'
3442// :115:22: error: use of undefined value here causes illegal behavior3429// :115:22: error: use of undefined value here causes illegal behavior
3443// :115:22: note: when computing vector element at index '0'
3444// :115:22: error: use of undefined value here causes illegal behavior3430// :115:22: error: use of undefined value here causes illegal behavior
3445// :115:22: note: when computing vector element at index '0'
3446// :115:22: error: use of undefined value here causes illegal behavior3431// :115:22: error: use of undefined value here causes illegal behavior
3447// :115:22: note: when computing vector element at index '0'
3448// :115:22: error: use of undefined value here causes illegal behavior3432// :115:22: error: use of undefined value here causes illegal behavior
3449// :115:22: error: use of undefined value here causes illegal behavior3433// :115:22: error: use of undefined value here causes illegal behavior
3450// :115:22: error: use of undefined value here causes illegal behavior3434// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3452,21 +3436,13 @@ const std = @import("std");...@@ -3452,21 +3436,13 @@ const std = @import("std");
3452// :115:22: error: use of undefined value here causes illegal behavior3436// :115:22: error: use of undefined value here causes illegal behavior
3453// :115:22: error: use of undefined value here causes illegal behavior3437// :115:22: error: use of undefined value here causes illegal behavior
3454// :115:22: error: use of undefined value here causes illegal behavior3438// :115:22: error: use of undefined value here causes illegal behavior
3455// :115:22: note: when computing vector element at index '1'
3456// :115:22: error: use of undefined value here causes illegal behavior3439// :115:22: error: use of undefined value here causes illegal behavior
3457// :115:22: note: when computing vector element at index '1'
3458// :115:22: error: use of undefined value here causes illegal behavior3440// :115:22: error: use of undefined value here causes illegal behavior
3459// :115:22: note: when computing vector element at index '1'
3460// :115:22: error: use of undefined value here causes illegal behavior3441// :115:22: error: use of undefined value here causes illegal behavior
3461// :115:22: note: when computing vector element at index '1'
3462// :115:22: error: use of undefined value here causes illegal behavior3442// :115:22: error: use of undefined value here causes illegal behavior
3463// :115:22: note: when computing vector element at index '0'
3464// :115:22: error: use of undefined value here causes illegal behavior3443// :115:22: error: use of undefined value here causes illegal behavior
3465// :115:22: note: when computing vector element at index '0'
3466// :115:22: error: use of undefined value here causes illegal behavior3444// :115:22: error: use of undefined value here causes illegal behavior
3467// :115:22: note: when computing vector element at index '0'
3468// :115:22: error: use of undefined value here causes illegal behavior3445// :115:22: error: use of undefined value here causes illegal behavior
3469// :115:22: note: when computing vector element at index '0'
3470// :115:22: error: use of undefined value here causes illegal behavior3446// :115:22: error: use of undefined value here causes illegal behavior
3471// :115:22: error: use of undefined value here causes illegal behavior3447// :115:22: error: use of undefined value here causes illegal behavior
3472// :115:22: error: use of undefined value here causes illegal behavior3448// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3474,21 +3450,13 @@ const std = @import("std");...@@ -3474,21 +3450,13 @@ const std = @import("std");
3474// :115:22: error: use of undefined value here causes illegal behavior3450// :115:22: error: use of undefined value here causes illegal behavior
3475// :115:22: error: use of undefined value here causes illegal behavior3451// :115:22: error: use of undefined value here causes illegal behavior
3476// :115:22: error: use of undefined value here causes illegal behavior3452// :115:22: error: use of undefined value here causes illegal behavior
3477// :115:22: note: when computing vector element at index '1'
3478// :115:22: error: use of undefined value here causes illegal behavior3453// :115:22: error: use of undefined value here causes illegal behavior
3479// :115:22: note: when computing vector element at index '1'
3480// :115:22: error: use of undefined value here causes illegal behavior3454// :115:22: error: use of undefined value here causes illegal behavior
3481// :115:22: note: when computing vector element at index '1'
3482// :115:22: error: use of undefined value here causes illegal behavior3455// :115:22: error: use of undefined value here causes illegal behavior
3483// :115:22: note: when computing vector element at index '1'
3484// :115:22: error: use of undefined value here causes illegal behavior3456// :115:22: error: use of undefined value here causes illegal behavior
3485// :115:22: note: when computing vector element at index '0'
3486// :115:22: error: use of undefined value here causes illegal behavior3457// :115:22: error: use of undefined value here causes illegal behavior
3487// :115:22: note: when computing vector element at index '0'
3488// :115:22: error: use of undefined value here causes illegal behavior3458// :115:22: error: use of undefined value here causes illegal behavior
3489// :115:22: note: when computing vector element at index '0'
3490// :115:22: error: use of undefined value here causes illegal behavior3459// :115:22: error: use of undefined value here causes illegal behavior
3491// :115:22: note: when computing vector element at index '0'
3492// :115:22: error: use of undefined value here causes illegal behavior3460// :115:22: error: use of undefined value here causes illegal behavior
3493// :115:22: error: use of undefined value here causes illegal behavior3461// :115:22: error: use of undefined value here causes illegal behavior
3494// :115:22: error: use of undefined value here causes illegal behavior3462// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3496,13 +3464,9 @@ const std = @import("std");...@@ -3496,13 +3464,9 @@ const std = @import("std");
3496// :115:22: error: use of undefined value here causes illegal behavior3464// :115:22: error: use of undefined value here causes illegal behavior
3497// :115:22: error: use of undefined value here causes illegal behavior3465// :115:22: error: use of undefined value here causes illegal behavior
3498// :115:22: error: use of undefined value here causes illegal behavior3466// :115:22: error: use of undefined value here causes illegal behavior
3499// :115:22: note: when computing vector element at index '1'
3500// :115:22: error: use of undefined value here causes illegal behavior3467// :115:22: error: use of undefined value here causes illegal behavior
3501// :115:22: note: when computing vector element at index '1'
3502// :115:22: error: use of undefined value here causes illegal behavior3468// :115:22: error: use of undefined value here causes illegal behavior
3503// :115:22: note: when computing vector element at index '1'
3504// :115:22: error: use of undefined value here causes illegal behavior3469// :115:22: error: use of undefined value here causes illegal behavior
3505// :115:22: note: when computing vector element at index '1'
3506// :115:22: error: use of undefined value here causes illegal behavior3470// :115:22: error: use of undefined value here causes illegal behavior
3507// :115:22: note: when computing vector element at index '0'3471// :115:22: note: when computing vector element at index '0'
3508// :115:22: error: use of undefined value here causes illegal behavior3472// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3512,19 +3476,21 @@ const std = @import("std");...@@ -3512,19 +3476,21 @@ const std = @import("std");
3512// :115:22: error: use of undefined value here causes illegal behavior3476// :115:22: error: use of undefined value here causes illegal behavior
3513// :115:22: note: when computing vector element at index '0'3477// :115:22: note: when computing vector element at index '0'
3514// :115:22: error: use of undefined value here causes illegal behavior3478// :115:22: error: use of undefined value here causes illegal behavior
3479// :115:22: note: when computing vector element at index '0'
3515// :115:22: error: use of undefined value here causes illegal behavior3480// :115:22: error: use of undefined value here causes illegal behavior
3481// :115:22: note: when computing vector element at index '0'
3516// :115:22: error: use of undefined value here causes illegal behavior3482// :115:22: error: use of undefined value here causes illegal behavior
3483// :115:22: note: when computing vector element at index '0'
3517// :115:22: error: use of undefined value here causes illegal behavior3484// :115:22: error: use of undefined value here causes illegal behavior
3485// :115:22: note: when computing vector element at index '0'
3518// :115:22: error: use of undefined value here causes illegal behavior3486// :115:22: error: use of undefined value here causes illegal behavior
3487// :115:22: note: when computing vector element at index '0'
3519// :115:22: error: use of undefined value here causes illegal behavior3488// :115:22: error: use of undefined value here causes illegal behavior
3489// :115:22: note: when computing vector element at index '0'
3520// :115:22: error: use of undefined value here causes illegal behavior3490// :115:22: error: use of undefined value here causes illegal behavior
3521// :115:22: note: when computing vector element at index '1'3491// :115:22: note: when computing vector element at index '0'
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'
3526// :115:22: error: use of undefined value here causes illegal behavior3492// :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'
3528// :115:22: error: use of undefined value here causes illegal behavior3494// :115:22: error: use of undefined value here causes illegal behavior
3529// :115:22: note: when computing vector element at index '0'3495// :115:22: note: when computing vector element at index '0'
3530// :115:22: error: use of undefined value here causes illegal behavior3496// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3534,19 +3500,25 @@ const std = @import("std");...@@ -3534,19 +3500,25 @@ const std = @import("std");
3534// :115:22: error: use of undefined value here causes illegal behavior3500// :115:22: error: use of undefined value here causes illegal behavior
3535// :115:22: note: when computing vector element at index '0'3501// :115:22: note: when computing vector element at index '0'
3536// :115:22: error: use of undefined value here causes illegal behavior3502// :115:22: error: use of undefined value here causes illegal behavior
3503// :115:22: note: when computing vector element at index '0'
3537// :115:22: error: use of undefined value here causes illegal behavior3504// :115:22: error: use of undefined value here causes illegal behavior
3505// :115:22: note: when computing vector element at index '0'
3538// :115:22: error: use of undefined value here causes illegal behavior3506// :115:22: error: use of undefined value here causes illegal behavior
3507// :115:22: note: when computing vector element at index '0'
3539// :115:22: error: use of undefined value here causes illegal behavior3508// :115:22: error: use of undefined value here causes illegal behavior
3509// :115:22: note: when computing vector element at index '0'
3540// :115:22: error: use of undefined value here causes illegal behavior3510// :115:22: error: use of undefined value here causes illegal behavior
3511// :115:22: note: when computing vector element at index '0'
3541// :115:22: error: use of undefined value here causes illegal behavior3512// :115:22: error: use of undefined value here causes illegal behavior
3513// :115:22: note: when computing vector element at index '0'
3542// :115:22: error: use of undefined value here causes illegal behavior3514// :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'
3544// :115:22: error: use of undefined value here causes illegal behavior3516// :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'
3546// :115:22: error: use of undefined value here causes illegal behavior3518// :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'
3548// :115:22: error: use of undefined value here causes illegal behavior3520// :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'
3550// :115:22: error: use of undefined value here causes illegal behavior3522// :115:22: error: use of undefined value here causes illegal behavior
3551// :115:22: note: when computing vector element at index '0'3523// :115:22: note: when computing vector element at index '0'
3552// :115:22: error: use of undefined value here causes illegal behavior3524// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3556,19 +3528,25 @@ const std = @import("std");...@@ -3556,19 +3528,25 @@ const std = @import("std");
3556// :115:22: error: use of undefined value here causes illegal behavior3528// :115:22: error: use of undefined value here causes illegal behavior
3557// :115:22: note: when computing vector element at index '0'3529// :115:22: note: when computing vector element at index '0'
3558// :115:22: error: use of undefined value here causes illegal behavior3530// :115:22: error: use of undefined value here causes illegal behavior
3531// :115:22: note: when computing vector element at index '0'
3559// :115:22: error: use of undefined value here causes illegal behavior3532// :115:22: error: use of undefined value here causes illegal behavior
3533// :115:22: note: when computing vector element at index '0'
3560// :115:22: error: use of undefined value here causes illegal behavior3534// :115:22: error: use of undefined value here causes illegal behavior
3535// :115:22: note: when computing vector element at index '0'
3561// :115:22: error: use of undefined value here causes illegal behavior3536// :115:22: error: use of undefined value here causes illegal behavior
3537// :115:22: note: when computing vector element at index '0'
3562// :115:22: error: use of undefined value here causes illegal behavior3538// :115:22: error: use of undefined value here causes illegal behavior
3539// :115:22: note: when computing vector element at index '0'
3563// :115:22: error: use of undefined value here causes illegal behavior3540// :115:22: error: use of undefined value here causes illegal behavior
3541// :115:22: note: when computing vector element at index '0'
3564// :115:22: error: use of undefined value here causes illegal behavior3542// :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'
3566// :115:22: error: use of undefined value here causes illegal behavior3544// :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'
3568// :115:22: error: use of undefined value here causes illegal behavior3546// :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'
3570// :115:22: error: use of undefined value here causes illegal behavior3548// :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'
3572// :115:22: error: use of undefined value here causes illegal behavior3550// :115:22: error: use of undefined value here causes illegal behavior
3573// :115:22: note: when computing vector element at index '0'3551// :115:22: note: when computing vector element at index '0'
3574// :115:22: error: use of undefined value here causes illegal behavior3552// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3578,11 +3556,17 @@ const std = @import("std");...@@ -3578,11 +3556,17 @@ const std = @import("std");
3578// :115:22: error: use of undefined value here causes illegal behavior3556// :115:22: error: use of undefined value here causes illegal behavior
3579// :115:22: note: when computing vector element at index '0'3557// :115:22: note: when computing vector element at index '0'
3580// :115:22: error: use of undefined value here causes illegal behavior3558// :115:22: error: use of undefined value here causes illegal behavior
3559// :115:22: note: when computing vector element at index '1'
3581// :115:22: error: use of undefined value here causes illegal behavior3560// :115:22: error: use of undefined value here causes illegal behavior
3561// :115:22: note: when computing vector element at index '1'
3582// :115:22: error: use of undefined value here causes illegal behavior3562// :115:22: error: use of undefined value here causes illegal behavior
3563// :115:22: note: when computing vector element at index '1'
3583// :115:22: error: use of undefined value here causes illegal behavior3564// :115:22: error: use of undefined value here causes illegal behavior
3565// :115:22: note: when computing vector element at index '1'
3584// :115:22: error: use of undefined value here causes illegal behavior3566// :115:22: error: use of undefined value here causes illegal behavior
3567// :115:22: note: when computing vector element at index '1'
3585// :115:22: error: use of undefined value here causes illegal behavior3568// :115:22: error: use of undefined value here causes illegal behavior
3569// :115:22: note: when computing vector element at index '1'
3586// :115:22: error: use of undefined value here causes illegal behavior3570// :115:22: error: use of undefined value here causes illegal behavior
3587// :115:22: note: when computing vector element at index '1'3571// :115:22: note: when computing vector element at index '1'
3588// :115:22: error: use of undefined value here causes illegal behavior3572// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3592,19 +3576,25 @@ const std = @import("std");...@@ -3592,19 +3576,25 @@ const std = @import("std");
3592// :115:22: error: use of undefined value here causes illegal behavior3576// :115:22: error: use of undefined value here causes illegal behavior
3593// :115:22: note: when computing vector element at index '1'3577// :115:22: note: when computing vector element at index '1'
3594// :115:22: error: use of undefined value here causes illegal behavior3578// :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'
3596// :115:22: error: use of undefined value here causes illegal behavior3580// :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'
3598// :115:22: error: use of undefined value here causes illegal behavior3582// :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'
3600// :115:22: error: use of undefined value here causes illegal behavior3584// :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'
3602// :115:22: error: use of undefined value here causes illegal behavior3586// :115:22: error: use of undefined value here causes illegal behavior
3587// :115:22: note: when computing vector element at index '1'
3603// :115:22: error: use of undefined value here causes illegal behavior3588// :115:22: error: use of undefined value here causes illegal behavior
3589// :115:22: note: when computing vector element at index '1'
3604// :115:22: error: use of undefined value here causes illegal behavior3590// :115:22: error: use of undefined value here causes illegal behavior
3591// :115:22: note: when computing vector element at index '1'
3605// :115:22: error: use of undefined value here causes illegal behavior3592// :115:22: error: use of undefined value here causes illegal behavior
3593// :115:22: note: when computing vector element at index '1'
3606// :115:22: error: use of undefined value here causes illegal behavior3594// :115:22: error: use of undefined value here causes illegal behavior
3595// :115:22: note: when computing vector element at index '1'
3607// :115:22: error: use of undefined value here causes illegal behavior3596// :115:22: error: use of undefined value here causes illegal behavior
3597// :115:22: note: when computing vector element at index '1'
3608// :115:22: error: use of undefined value here causes illegal behavior3598// :115:22: error: use of undefined value here causes illegal behavior
3609// :115:22: note: when computing vector element at index '1'3599// :115:22: note: when computing vector element at index '1'
3610// :115:22: error: use of undefined value here causes illegal behavior3600// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3614,19 +3604,27 @@ const std = @import("std");...@@ -3614,19 +3604,27 @@ const std = @import("std");
3614// :115:22: error: use of undefined value here causes illegal behavior3604// :115:22: error: use of undefined value here causes illegal behavior
3615// :115:22: note: when computing vector element at index '1'3605// :115:22: note: when computing vector element at index '1'
3616// :115:22: error: use of undefined value here causes illegal behavior3606// :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'
3618// :115:22: error: use of undefined value here causes illegal behavior3608// :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'
3620// :115:22: error: use of undefined value here causes illegal behavior3610// :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'
3622// :115:22: error: use of undefined value here causes illegal behavior3612// :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'
3624// :115:22: error: use of undefined value here causes illegal behavior3616// :115:22: error: use of undefined value here causes illegal behavior
3617// :115:22: note: when computing vector element at index '1'
3625// :115:22: error: use of undefined value here causes illegal behavior3618// :115:22: error: use of undefined value here causes illegal behavior
3619// :115:22: note: when computing vector element at index '1'
3626// :115:22: error: use of undefined value here causes illegal behavior3620// :115:22: error: use of undefined value here causes illegal behavior
3621// :115:22: note: when computing vector element at index '1'
3627// :115:22: error: use of undefined value here causes illegal behavior3622// :115:22: error: use of undefined value here causes illegal behavior
3623// :115:22: note: when computing vector element at index '1'
3628// :115:22: error: use of undefined value here causes illegal behavior3624// :115:22: error: use of undefined value here causes illegal behavior
3625// :115:22: note: when computing vector element at index '1'
3629// :115:22: error: use of undefined value here causes illegal behavior3626// :115:22: error: use of undefined value here causes illegal behavior
3627// :115:22: note: when computing vector element at index '1'
3630// :115:22: error: use of undefined value here causes illegal behavior3628// :115:22: error: use of undefined value here causes illegal behavior
3631// :115:22: note: when computing vector element at index '1'3629// :115:22: note: when computing vector element at index '1'
3632// :115:22: error: use of undefined value here causes illegal behavior3630// :115:22: error: use of undefined value here causes illegal behavior
...@@ -3636,37 +3634,32 @@ const std = @import("std");...@@ -3636,37 +3634,32 @@ const std = @import("std");
3636// :115:22: error: use of undefined value here causes illegal behavior3634// :115:22: error: use of undefined value here causes illegal behavior
3637// :115:22: note: when computing vector element at index '1'3635// :115:22: note: when computing vector element at index '1'
3638// :115:22: error: use of undefined value here causes illegal behavior3636// :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'
3640// :115:22: error: use of undefined value here causes illegal behavior3638// :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'
3642// :115:22: error: use of undefined value here causes illegal behavior3640// :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'
3644// :115:22: error: use of undefined value here causes illegal behavior3642// :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
3646// :121:17: error: use of undefined value here causes illegal behavior3647// :121:17: error: use of undefined value here causes illegal behavior
3647// :121:17: error: use of undefined value here causes illegal behavior3648// :121:17: error: use of undefined value here causes illegal behavior
3648// :121:17: note: when computing vector element at index '0'
3649// :121:17: error: use of undefined value here causes illegal behavior3649// :121:17: error: use of undefined value here causes illegal behavior
3650// :121:17: note: when computing vector element at index '0'
3651// :121:17: error: use of undefined value here causes illegal behavior3650// :121:17: error: use of undefined value here causes illegal behavior
3652// :121:17: note: when computing vector element at index '0'
3653// :121:17: error: use of undefined value here causes illegal behavior3651// :121:17: error: use of undefined value here causes illegal behavior
3654// :121:17: note: when computing vector element at index '1'
3655// :121:17: error: use of undefined value here causes illegal behavior3652// :121:17: error: use of undefined value here causes illegal behavior
3656// :121:17: note: when computing vector element at index '0'
3657// :121:17: error: use of undefined value here causes illegal behavior3653// :121:17: error: use of undefined value here causes illegal behavior
3658// :121:17: note: when computing vector element at index '0'
3659// :121:17: error: use of undefined value here causes illegal behavior3654// :121:17: error: use of undefined value here causes illegal behavior
3660// :121:17: note: when computing vector element at index '0'
3661// :121:17: error: use of undefined value here causes illegal behavior3655// :121:17: error: use of undefined value here causes illegal behavior
3662// :121:17: error: use of undefined value here causes illegal behavior3656// :121:17: error: use of undefined value here causes illegal behavior
3663// :121:17: note: when computing vector element at index '0'
3664// :121:17: error: use of undefined value here causes illegal behavior3657// :121:17: error: use of undefined value here causes illegal behavior
3665// :121:17: note: when computing vector element at index '0'3658// :121:17: note: when computing vector element at index '0'
3666// :121:17: error: use of undefined value here causes illegal behavior3659// :121:17: error: use of undefined value here causes illegal behavior
3667// :121:17: note: when computing vector element at index '0'3660// :121:17: note: when computing vector element at index '0'
3668// :121:17: error: use of undefined value here causes illegal behavior3661// :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'
3670// :121:17: error: use of undefined value here causes illegal behavior3663// :121:17: error: use of undefined value here causes illegal behavior
3671// :121:17: note: when computing vector element at index '0'3664// :121:17: note: when computing vector element at index '0'
3672// :121:17: error: use of undefined value here causes illegal behavior3665// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3674,6 +3667,7 @@ const std = @import("std");...@@ -3674,6 +3667,7 @@ const std = @import("std");
3674// :121:17: error: use of undefined value here causes illegal behavior3667// :121:17: error: use of undefined value here causes illegal behavior
3675// :121:17: note: when computing vector element at index '0'3668// :121:17: note: when computing vector element at index '0'
3676// :121:17: error: use of undefined value here causes illegal behavior3669// :121:17: error: use of undefined value here causes illegal behavior
3670// :121:17: note: when computing vector element at index '0'
3677// :121:17: error: use of undefined value here causes illegal behavior3671// :121:17: error: use of undefined value here causes illegal behavior
3678// :121:17: note: when computing vector element at index '0'3672// :121:17: note: when computing vector element at index '0'
3679// :121:17: error: use of undefined value here causes illegal behavior3673// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3681,7 +3675,7 @@ const std = @import("std");...@@ -3681,7 +3675,7 @@ const std = @import("std");
3681// :121:17: error: use of undefined value here causes illegal behavior3675// :121:17: error: use of undefined value here causes illegal behavior
3682// :121:17: note: when computing vector element at index '0'3676// :121:17: note: when computing vector element at index '0'
3683// :121:17: error: use of undefined value here causes illegal behavior3677// :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'
3685// :121:17: error: use of undefined value here causes illegal behavior3679// :121:17: error: use of undefined value here causes illegal behavior
3686// :121:17: note: when computing vector element at index '0'3680// :121:17: note: when computing vector element at index '0'
3687// :121:17: error: use of undefined value here causes illegal behavior3681// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3689,6 +3683,7 @@ const std = @import("std");...@@ -3689,6 +3683,7 @@ const std = @import("std");
3689// :121:17: error: use of undefined value here causes illegal behavior3683// :121:17: error: use of undefined value here causes illegal behavior
3690// :121:17: note: when computing vector element at index '0'3684// :121:17: note: when computing vector element at index '0'
3691// :121:17: error: use of undefined value here causes illegal behavior3685// :121:17: error: use of undefined value here causes illegal behavior
3686// :121:17: note: when computing vector element at index '0'
3692// :121:17: error: use of undefined value here causes illegal behavior3687// :121:17: error: use of undefined value here causes illegal behavior
3693// :121:17: note: when computing vector element at index '0'3688// :121:17: note: when computing vector element at index '0'
3694// :121:17: error: use of undefined value here causes illegal behavior3689// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3696,7 +3691,7 @@ const std = @import("std");...@@ -3696,7 +3691,7 @@ const std = @import("std");
3696// :121:17: error: use of undefined value here causes illegal behavior3691// :121:17: error: use of undefined value here causes illegal behavior
3697// :121:17: note: when computing vector element at index '0'3692// :121:17: note: when computing vector element at index '0'
3698// :121:17: error: use of undefined value here causes illegal behavior3693// :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'
3700// :121:17: error: use of undefined value here causes illegal behavior3695// :121:17: error: use of undefined value here causes illegal behavior
3701// :121:17: note: when computing vector element at index '0'3696// :121:17: note: when computing vector element at index '0'
3702// :121:17: error: use of undefined value here causes illegal behavior3697// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3704,6 +3699,7 @@ const std = @import("std");...@@ -3704,6 +3699,7 @@ const std = @import("std");
3704// :121:17: error: use of undefined value here causes illegal behavior3699// :121:17: error: use of undefined value here causes illegal behavior
3705// :121:17: note: when computing vector element at index '0'3700// :121:17: note: when computing vector element at index '0'
3706// :121:17: error: use of undefined value here causes illegal behavior3701// :121:17: error: use of undefined value here causes illegal behavior
3702// :121:17: note: when computing vector element at index '0'
3707// :121:17: error: use of undefined value here causes illegal behavior3703// :121:17: error: use of undefined value here causes illegal behavior
3708// :121:17: note: when computing vector element at index '0'3704// :121:17: note: when computing vector element at index '0'
3709// :121:17: error: use of undefined value here causes illegal behavior3705// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3711,7 +3707,7 @@ const std = @import("std");...@@ -3711,7 +3707,7 @@ const std = @import("std");
3711// :121:17: error: use of undefined value here causes illegal behavior3707// :121:17: error: use of undefined value here causes illegal behavior
3712// :121:17: note: when computing vector element at index '0'3708// :121:17: note: when computing vector element at index '0'
3713// :121:17: error: use of undefined value here causes illegal behavior3709// :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'
3715// :121:17: error: use of undefined value here causes illegal behavior3711// :121:17: error: use of undefined value here causes illegal behavior
3716// :121:17: note: when computing vector element at index '0'3712// :121:17: note: when computing vector element at index '0'
3717// :121:17: error: use of undefined value here causes illegal behavior3713// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3719,6 +3715,7 @@ const std = @import("std");...@@ -3719,6 +3715,7 @@ const std = @import("std");
3719// :121:17: error: use of undefined value here causes illegal behavior3715// :121:17: error: use of undefined value here causes illegal behavior
3720// :121:17: note: when computing vector element at index '0'3716// :121:17: note: when computing vector element at index '0'
3721// :121:17: error: use of undefined value here causes illegal behavior3717// :121:17: error: use of undefined value here causes illegal behavior
3718// :121:17: note: when computing vector element at index '0'
3722// :121:17: error: use of undefined value here causes illegal behavior3719// :121:17: error: use of undefined value here causes illegal behavior
3723// :121:17: note: when computing vector element at index '0'3720// :121:17: note: when computing vector element at index '0'
3724// :121:17: error: use of undefined value here causes illegal behavior3721// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3726,7 +3723,7 @@ const std = @import("std");...@@ -3726,7 +3723,7 @@ const std = @import("std");
3726// :121:17: error: use of undefined value here causes illegal behavior3723// :121:17: error: use of undefined value here causes illegal behavior
3727// :121:17: note: when computing vector element at index '0'3724// :121:17: note: when computing vector element at index '0'
3728// :121:17: error: use of undefined value here causes illegal behavior3725// :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'
3730// :121:17: error: use of undefined value here causes illegal behavior3727// :121:17: error: use of undefined value here causes illegal behavior
3731// :121:17: note: when computing vector element at index '0'3728// :121:17: note: when computing vector element at index '0'
3732// :121:17: error: use of undefined value here causes illegal behavior3729// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3734,6 +3731,7 @@ const std = @import("std");...@@ -3734,6 +3731,7 @@ const std = @import("std");
3734// :121:17: error: use of undefined value here causes illegal behavior3731// :121:17: error: use of undefined value here causes illegal behavior
3735// :121:17: note: when computing vector element at index '0'3732// :121:17: note: when computing vector element at index '0'
3736// :121:17: error: use of undefined value here causes illegal behavior3733// :121:17: error: use of undefined value here causes illegal behavior
3734// :121:17: note: when computing vector element at index '0'
3737// :121:17: error: use of undefined value here causes illegal behavior3735// :121:17: error: use of undefined value here causes illegal behavior
3738// :121:17: note: when computing vector element at index '0'3736// :121:17: note: when computing vector element at index '0'
3739// :121:17: error: use of undefined value here causes illegal behavior3737// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3741,7 +3739,7 @@ const std = @import("std");...@@ -3741,7 +3739,7 @@ const std = @import("std");
3741// :121:17: error: use of undefined value here causes illegal behavior3739// :121:17: error: use of undefined value here causes illegal behavior
3742// :121:17: note: when computing vector element at index '0'3740// :121:17: note: when computing vector element at index '0'
3743// :121:17: error: use of undefined value here causes illegal behavior3741// :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'
3745// :121:17: error: use of undefined value here causes illegal behavior3743// :121:17: error: use of undefined value here causes illegal behavior
3746// :121:17: note: when computing vector element at index '0'3744// :121:17: note: when computing vector element at index '0'
3747// :121:17: error: use of undefined value here causes illegal behavior3745// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3749,6 +3747,7 @@ const std = @import("std");...@@ -3749,6 +3747,7 @@ const std = @import("std");
3749// :121:17: error: use of undefined value here causes illegal behavior3747// :121:17: error: use of undefined value here causes illegal behavior
3750// :121:17: note: when computing vector element at index '0'3748// :121:17: note: when computing vector element at index '0'
3751// :121:17: error: use of undefined value here causes illegal behavior3749// :121:17: error: use of undefined value here causes illegal behavior
3750// :121:17: note: when computing vector element at index '0'
3752// :121:17: error: use of undefined value here causes illegal behavior3751// :121:17: error: use of undefined value here causes illegal behavior
3753// :121:17: note: when computing vector element at index '0'3752// :121:17: note: when computing vector element at index '0'
3754// :121:17: error: use of undefined value here causes illegal behavior3753// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3756,7 +3755,7 @@ const std = @import("std");...@@ -3756,7 +3755,7 @@ const std = @import("std");
3756// :121:17: error: use of undefined value here causes illegal behavior3755// :121:17: error: use of undefined value here causes illegal behavior
3757// :121:17: note: when computing vector element at index '0'3756// :121:17: note: when computing vector element at index '0'
3758// :121:17: error: use of undefined value here causes illegal behavior3757// :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'
3760// :121:17: error: use of undefined value here causes illegal behavior3759// :121:17: error: use of undefined value here causes illegal behavior
3761// :121:17: note: when computing vector element at index '0'3760// :121:17: note: when computing vector element at index '0'
3762// :121:17: error: use of undefined value here causes illegal behavior3761// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3764,6 +3763,7 @@ const std = @import("std");...@@ -3764,6 +3763,7 @@ const std = @import("std");
3764// :121:17: error: use of undefined value here causes illegal behavior3763// :121:17: error: use of undefined value here causes illegal behavior
3765// :121:17: note: when computing vector element at index '0'3764// :121:17: note: when computing vector element at index '0'
3766// :121:17: error: use of undefined value here causes illegal behavior3765// :121:17: error: use of undefined value here causes illegal behavior
3766// :121:17: note: when computing vector element at index '0'
3767// :121:17: error: use of undefined value here causes illegal behavior3767// :121:17: error: use of undefined value here causes illegal behavior
3768// :121:17: note: when computing vector element at index '0'3768// :121:17: note: when computing vector element at index '0'
3769// :121:17: error: use of undefined value here causes illegal behavior3769// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3771,7 +3771,7 @@ const std = @import("std");...@@ -3771,7 +3771,7 @@ const std = @import("std");
3771// :121:17: error: use of undefined value here causes illegal behavior3771// :121:17: error: use of undefined value here causes illegal behavior
3772// :121:17: note: when computing vector element at index '0'3772// :121:17: note: when computing vector element at index '0'
3773// :121:17: error: use of undefined value here causes illegal behavior3773// :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'
3775// :121:17: error: use of undefined value here causes illegal behavior3775// :121:17: error: use of undefined value here causes illegal behavior
3776// :121:17: note: when computing vector element at index '0'3776// :121:17: note: when computing vector element at index '0'
3777// :121:17: error: use of undefined value here causes illegal behavior3777// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3779,6 +3779,7 @@ const std = @import("std");...@@ -3779,6 +3779,7 @@ const std = @import("std");
3779// :121:17: error: use of undefined value here causes illegal behavior3779// :121:17: error: use of undefined value here causes illegal behavior
3780// :121:17: note: when computing vector element at index '0'3780// :121:17: note: when computing vector element at index '0'
3781// :121:17: error: use of undefined value here causes illegal behavior3781// :121:17: error: use of undefined value here causes illegal behavior
3782// :121:17: note: when computing vector element at index '0'
3782// :121:17: error: use of undefined value here causes illegal behavior3783// :121:17: error: use of undefined value here causes illegal behavior
3783// :121:17: note: when computing vector element at index '0'3784// :121:17: note: when computing vector element at index '0'
3784// :121:17: error: use of undefined value here causes illegal behavior3785// :121:17: error: use of undefined value here causes illegal behavior
...@@ -3788,126 +3789,120 @@ const std = @import("std");...@@ -3788,126 +3789,120 @@ const std = @import("std");
3788// :121:17: error: use of undefined value here causes illegal behavior3789// :121:17: error: use of undefined value here causes illegal behavior
3789// :121:17: note: when computing vector element at index '1'3790// :121:17: note: when computing vector element at index '1'
3790// :121:17: error: use of undefined value here causes illegal behavior3791// :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: note: when computing vector element at index '1'
3792// :121:17: error: use of undefined value here causes illegal behavior
3793// :121:17: note: when computing vector element at index '0'
3794// :121:17: error: use of undefined value here causes illegal behavior3793// :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'
3796// :121:17: error: use of undefined value here causes illegal behavior3795// :121:17: error: use of undefined value here causes illegal behavior
3796// :121:17: note: when computing vector element at index '1'
3797// :121:17: error: use of undefined value here causes illegal behavior3797// :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'
3799// :121:17: error: use of undefined value here causes illegal behavior3799// :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'
3801// :121:17: error: use of undefined value here causes illegal behavior3801// :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'
3803// :121:17: error: use of undefined value here causes illegal behavior3803// :121:17: error: use of undefined value here causes illegal behavior
3804// :121:17: note: when computing vector element at index '1'3804// :121:17: note: when computing vector element at index '1'
3805// :121:17: error: use of undefined value here causes illegal behavior3805// :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'
3807// :121:17: error: use of undefined value here causes illegal behavior3807// :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'
3809// :121:17: error: use of undefined value here causes illegal behavior3809// :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'
3811// :121:21: error: use of undefined value here causes illegal behavior3811// :121:21: error: use of undefined value here causes illegal behavior
3812// :121:21: error: use of undefined value here causes illegal behavior3812// :121:21: error: use of undefined value here causes illegal behavior
3813// :121:21: note: when computing vector element at index '0'
3814// :121:21: error: use of undefined value here causes illegal behavior3813// :121:21: error: use of undefined value here causes illegal behavior
3815// :121:21: note: when computing vector element at index '0'
3816// :121:21: error: use of undefined value here causes illegal behavior3814// :121:21: error: use of undefined value here causes illegal behavior
3817// :121:21: note: when computing vector element at index '1'
3818// :121:21: error: use of undefined value here causes illegal behavior3815// :121:21: error: use of undefined value here causes illegal behavior
3819// :121:21: note: when computing vector element at index '0'
3820// :121:21: error: use of undefined value here causes illegal behavior3816// :121:21: error: use of undefined value here causes illegal behavior
3821// :121:21: note: when computing vector element at index '0'
3822// :121:21: error: use of undefined value here causes illegal behavior3817// :121:21: error: use of undefined value here causes illegal behavior
3823// :121:21: error: use of undefined value here causes illegal behavior3818// :121:21: error: use of undefined value here causes illegal behavior
3824// :121:21: note: when computing vector element at index '0'
3825// :121:21: error: use of undefined value here causes illegal behavior3819// :121:21: error: use of undefined value here causes illegal behavior
3826// :121:21: note: when computing vector element at index '0'
3827// :121:21: error: use of undefined value here causes illegal behavior3820// :121:21: error: use of undefined value here causes illegal behavior
3828// :121:21: note: when computing vector element at index '1'
3829// :121:21: error: use of undefined value here causes illegal behavior3821// :121:21: error: use of undefined value here causes illegal behavior
3830// :121:21: note: when computing vector element at index '0'
3831// :121:21: error: use of undefined value here causes illegal behavior3822// :121:21: error: use of undefined value here causes illegal behavior
3832// :121:21: note: when computing vector element at index '0'3823// :121:21: note: when computing vector element at index '0'
3833// :121:21: error: use of undefined value here causes illegal behavior3824// :121:21: error: use of undefined value here causes illegal behavior
3834// :121:21: error: use of undefined value here causes illegal behavior
3835// :121:21: note: when computing vector element at index '0'3825// :121:21: note: when computing vector element at index '0'
3836// :121:21: error: use of undefined value here causes illegal behavior3826// :121:21: error: use of undefined value here causes illegal behavior
3837// :121:21: note: when computing vector element at index '0'3827// :121:21: note: when computing vector element at index '0'
3838// :121:21: error: use of undefined value here causes illegal behavior3828// :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
3841// :121:21: note: when computing vector element at index '0'3829// :121:21: note: when computing vector element at index '0'
3842// :121:21: error: use of undefined value here causes illegal behavior3830// :121:21: error: use of undefined value here causes illegal behavior
3843// :121:21: note: when computing vector element at index '0'3831// :121:21: note: when computing vector element at index '0'
3844// :121:21: error: use of undefined value here causes illegal behavior3832// :121:21: error: use of undefined value here causes illegal behavior
3833// :121:21: note: when computing vector element at index '0'
3845// :121:21: error: use of undefined value here causes illegal behavior3834// :121:21: error: use of undefined value here causes illegal behavior
3846// :121:21: note: when computing vector element at index '0'3835// :121:21: note: when computing vector element at index '0'
3847// :121:21: error: use of undefined value here causes illegal behavior3836// :121:21: error: use of undefined value here causes illegal behavior
3848// :121:21: note: when computing vector element at index '0'3837// :121:21: note: when computing vector element at index '0'
3849// :121:21: error: use of undefined value here causes illegal behavior3838// :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'
3851// :121:21: error: use of undefined value here causes illegal behavior3840// :121:21: error: use of undefined value here causes illegal behavior
3852// :121:21: note: when computing vector element at index '0'3841// :121:21: note: when computing vector element at index '0'
3853// :121:21: error: use of undefined value here causes illegal behavior3842// :121:21: error: use of undefined value here causes illegal behavior
3854// :121:21: note: when computing vector element at index '0'3843// :121:21: note: when computing vector element at index '0'
3855// :121:21: error: use of undefined value here causes illegal behavior3844// :121:21: error: use of undefined value here causes illegal behavior
3845// :121:21: note: when computing vector element at index '0'
3856// :121:21: error: use of undefined value here causes illegal behavior3846// :121:21: error: use of undefined value here causes illegal behavior
3857// :121:21: note: when computing vector element at index '0'3847// :121:21: note: when computing vector element at index '0'
3858// :121:21: error: use of undefined value here causes illegal behavior3848// :121:21: error: use of undefined value here causes illegal behavior
3859// :121:21: note: when computing vector element at index '0'3849// :121:21: note: when computing vector element at index '0'
3860// :121:21: error: use of undefined value here causes illegal behavior3850// :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'
3862// :121:21: error: use of undefined value here causes illegal behavior3852// :121:21: error: use of undefined value here causes illegal behavior
3863// :121:21: note: when computing vector element at index '0'3853// :121:21: note: when computing vector element at index '0'
3864// :121:21: error: use of undefined value here causes illegal behavior3854// :121:21: error: use of undefined value here causes illegal behavior
3865// :121:21: note: when computing vector element at index '0'3855// :121:21: note: when computing vector element at index '0'
3866// :121:21: error: use of undefined value here causes illegal behavior3856// :121:21: error: use of undefined value here causes illegal behavior
3857// :121:21: note: when computing vector element at index '0'
3867// :121:21: error: use of undefined value here causes illegal behavior3858// :121:21: error: use of undefined value here causes illegal behavior
3868// :121:21: note: when computing vector element at index '0'3859// :121:21: note: when computing vector element at index '0'
3869// :121:21: error: use of undefined value here causes illegal behavior3860// :121:21: error: use of undefined value here causes illegal behavior
3870// :121:21: note: when computing vector element at index '0'3861// :121:21: note: when computing vector element at index '0'
3871// :121:21: error: use of undefined value here causes illegal behavior3862// :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'
3873// :121:21: error: use of undefined value here causes illegal behavior3864// :121:21: error: use of undefined value here causes illegal behavior
3874// :121:21: note: when computing vector element at index '0'3865// :121:21: note: when computing vector element at index '0'
3875// :121:21: error: use of undefined value here causes illegal behavior3866// :121:21: error: use of undefined value here causes illegal behavior
3876// :121:21: note: when computing vector element at index '0'3867// :121:21: note: when computing vector element at index '0'
3877// :121:21: error: use of undefined value here causes illegal behavior3868// :121:21: error: use of undefined value here causes illegal behavior
3869// :121:21: note: when computing vector element at index '0'
3878// :121:21: error: use of undefined value here causes illegal behavior3870// :121:21: error: use of undefined value here causes illegal behavior
3879// :121:21: note: when computing vector element at index '0'3871// :121:21: note: when computing vector element at index '0'
3880// :121:21: error: use of undefined value here causes illegal behavior3872// :121:21: error: use of undefined value here causes illegal behavior
3881// :121:21: note: when computing vector element at index '0'3873// :121:21: note: when computing vector element at index '0'
3882// :121:21: error: use of undefined value here causes illegal behavior3874// :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'
3884// :121:21: error: use of undefined value here causes illegal behavior3876// :121:21: error: use of undefined value here causes illegal behavior
3885// :121:21: note: when computing vector element at index '0'3877// :121:21: note: when computing vector element at index '0'
3886// :121:21: error: use of undefined value here causes illegal behavior3878// :121:21: error: use of undefined value here causes illegal behavior
3887// :121:21: note: when computing vector element at index '0'3879// :121:21: note: when computing vector element at index '0'
3888// :121:21: error: use of undefined value here causes illegal behavior3880// :121:21: error: use of undefined value here causes illegal behavior
3881// :121:21: note: when computing vector element at index '0'
3889// :121:21: error: use of undefined value here causes illegal behavior3882// :121:21: error: use of undefined value here causes illegal behavior
3890// :121:21: note: when computing vector element at index '0'3883// :121:21: note: when computing vector element at index '0'
3891// :121:21: error: use of undefined value here causes illegal behavior3884// :121:21: error: use of undefined value here causes illegal behavior
3892// :121:21: note: when computing vector element at index '0'3885// :121:21: note: when computing vector element at index '0'
3893// :121:21: error: use of undefined value here causes illegal behavior3886// :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'
3895// :121:21: error: use of undefined value here causes illegal behavior3888// :121:21: error: use of undefined value here causes illegal behavior
3896// :121:21: note: when computing vector element at index '0'3889// :121:21: note: when computing vector element at index '0'
3897// :121:21: error: use of undefined value here causes illegal behavior3890// :121:21: error: use of undefined value here causes illegal behavior
3898// :121:21: note: when computing vector element at index '0'3891// :121:21: note: when computing vector element at index '0'
3899// :121:21: error: use of undefined value here causes illegal behavior3892// :121:21: error: use of undefined value here causes illegal behavior
3893// :121:21: note: when computing vector element at index '0'
3900// :121:21: error: use of undefined value here causes illegal behavior3894// :121:21: error: use of undefined value here causes illegal behavior
3901// :121:21: note: when computing vector element at index '0'3895// :121:21: note: when computing vector element at index '0'
3902// :121:21: error: use of undefined value here causes illegal behavior3896// :121:21: error: use of undefined value here causes illegal behavior
3903// :121:21: note: when computing vector element at index '0'3897// :121:21: note: when computing vector element at index '0'
3904// :121:21: error: use of undefined value here causes illegal behavior3898// :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'
3906// :121:21: error: use of undefined value here causes illegal behavior3900// :121:21: error: use of undefined value here causes illegal behavior
3907// :121:21: note: when computing vector element at index '0'3901// :121:21: note: when computing vector element at index '0'
3908// :121:21: error: use of undefined value here causes illegal behavior3902// :121:21: error: use of undefined value here causes illegal behavior
3909// :121:21: note: when computing vector element at index '0'3903// :121:21: note: when computing vector element at index '0'
3910// :121:21: error: use of undefined value here causes illegal behavior3904// :121:21: error: use of undefined value here causes illegal behavior
3905// :121:21: note: when computing vector element at index '0'
3911// :121:21: error: use of undefined value here causes illegal behavior3906// :121:21: error: use of undefined value here causes illegal behavior
3912// :121:21: note: when computing vector element at index '0'3907// :121:21: note: when computing vector element at index '0'
3913// :121:21: error: use of undefined value here causes illegal behavior3908// :121:21: error: use of undefined value here causes illegal behavior
...@@ -3915,44 +3910,42 @@ const std = @import("std");...@@ -3915,44 +3910,42 @@ const std = @import("std");
3915// :121:21: error: use of undefined value here causes illegal behavior3910// :121:21: error: use of undefined value here causes illegal behavior
3916// :121:21: note: when computing vector element at index '1'3911// :121:21: note: when computing vector element at index '1'
3917// :121:21: error: use of undefined value here causes illegal behavior3912// :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'
3919// :121:21: error: use of undefined value here causes illegal behavior3914// :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'
3921// :121:21: error: use of undefined value here causes illegal behavior3916// :121:21: error: use of undefined value here causes illegal behavior
3917// :121:21: note: when computing vector element at index '1'
3922// :121:21: error: use of undefined value here causes illegal behavior3918// :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'
3924// :121:21: error: use of undefined value here causes illegal behavior3920// :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'
3926// :121:21: error: use of undefined value here causes illegal behavior3922// :121:21: error: use of undefined value here causes illegal behavior
3927// :121:21: note: when computing vector element at index '1'3923// :121:21: note: when computing vector element at index '1'
3928// :121:21: error: use of undefined value here causes illegal behavior3924// :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'
3930// :121:21: error: use of undefined value here causes illegal behavior3926// :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
3932// :125:27: error: use of undefined value here causes illegal behavior3933// :125:27: error: use of undefined value here causes illegal behavior
3933// :125:27: error: use of undefined value here causes illegal behavior3934// :125:27: error: use of undefined value here causes illegal behavior
3934// :125:27: note: when computing vector element at index '0'
3935// :125:27: error: use of undefined value here causes illegal behavior3935// :125:27: error: use of undefined value here causes illegal behavior
3936// :125:27: note: when computing vector element at index '0'
3937// :125:27: error: use of undefined value here causes illegal behavior3936// :125:27: error: use of undefined value here causes illegal behavior
3938// :125:27: note: when computing vector element at index '0'
3939// :125:27: error: use of undefined value here causes illegal behavior3937// :125:27: error: use of undefined value here causes illegal behavior
3940// :125:27: note: when computing vector element at index '1'
3941// :125:27: error: use of undefined value here causes illegal behavior3938// :125:27: error: use of undefined value here causes illegal behavior
3942// :125:27: note: when computing vector element at index '0'
3943// :125:27: error: use of undefined value here causes illegal behavior3939// :125:27: error: use of undefined value here causes illegal behavior
3944// :125:27: note: when computing vector element at index '0'
3945// :125:27: error: use of undefined value here causes illegal behavior3940// :125:27: error: use of undefined value here causes illegal behavior
3946// :125:27: note: when computing vector element at index '0'
3947// :125:27: error: use of undefined value here causes illegal behavior3941// :125:27: error: use of undefined value here causes illegal behavior
3948// :125:27: error: use of undefined value here causes illegal behavior3942// :125:27: error: use of undefined value here causes illegal behavior
3949// :125:27: note: when computing vector element at index '0'
3950// :125:27: error: use of undefined value here causes illegal behavior3943// :125:27: error: use of undefined value here causes illegal behavior
3951// :125:27: note: when computing vector element at index '0'3944// :125:27: note: when computing vector element at index '0'
3952// :125:27: error: use of undefined value here causes illegal behavior3945// :125:27: error: use of undefined value here causes illegal behavior
3953// :125:27: note: when computing vector element at index '0'3946// :125:27: note: when computing vector element at index '0'
3954// :125:27: error: use of undefined value here causes illegal behavior3947// :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'
3956// :125:27: error: use of undefined value here causes illegal behavior3949// :125:27: error: use of undefined value here causes illegal behavior
3957// :125:27: note: when computing vector element at index '0'3950// :125:27: note: when computing vector element at index '0'
3958// :125:27: error: use of undefined value here causes illegal behavior3951// :125:27: error: use of undefined value here causes illegal behavior
...@@ -3960,6 +3953,7 @@ const std = @import("std");...@@ -3960,6 +3953,7 @@ const std = @import("std");
3960// :125:27: error: use of undefined value here causes illegal behavior3953// :125:27: error: use of undefined value here causes illegal behavior
3961// :125:27: note: when computing vector element at index '0'3954// :125:27: note: when computing vector element at index '0'
3962// :125:27: error: use of undefined value here causes illegal behavior3955// :125:27: error: use of undefined value here causes illegal behavior
3956// :125:27: note: when computing vector element at index '0'
3963// :125:27: error: use of undefined value here causes illegal behavior3957// :125:27: error: use of undefined value here causes illegal behavior
3964// :125:27: note: when computing vector element at index '0'3958// :125:27: note: when computing vector element at index '0'
3965// :125:27: error: use of undefined value here causes illegal behavior3959// :125:27: error: use of undefined value here causes illegal behavior
...@@ -3967,7 +3961,7 @@ const std = @import("std");...@@ -3967,7 +3961,7 @@ const std = @import("std");
3967// :125:27: error: use of undefined value here causes illegal behavior3961// :125:27: error: use of undefined value here causes illegal behavior
3968// :125:27: note: when computing vector element at index '0'3962// :125:27: note: when computing vector element at index '0'
3969// :125:27: error: use of undefined value here causes illegal behavior3963// :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'
3971// :125:27: error: use of undefined value here causes illegal behavior3965// :125:27: error: use of undefined value here causes illegal behavior
3972// :125:27: note: when computing vector element at index '0'3966// :125:27: note: when computing vector element at index '0'
3973// :125:27: error: use of undefined value here causes illegal behavior3967// :125:27: error: use of undefined value here causes illegal behavior
...@@ -3975,6 +3969,7 @@ const std = @import("std");...@@ -3975,6 +3969,7 @@ const std = @import("std");
3975// :125:27: error: use of undefined value here causes illegal behavior3969// :125:27: error: use of undefined value here causes illegal behavior
3976// :125:27: note: when computing vector element at index '0'3970// :125:27: note: when computing vector element at index '0'
3977// :125:27: error: use of undefined value here causes illegal behavior3971// :125:27: error: use of undefined value here causes illegal behavior
3972// :125:27: note: when computing vector element at index '0'
3978// :125:27: error: use of undefined value here causes illegal behavior3973// :125:27: error: use of undefined value here causes illegal behavior
3979// :125:27: note: when computing vector element at index '0'3974// :125:27: note: when computing vector element at index '0'
3980// :125:27: error: use of undefined value here causes illegal behavior3975// :125:27: error: use of undefined value here causes illegal behavior
...@@ -3982,7 +3977,7 @@ const std = @import("std");...@@ -3982,7 +3977,7 @@ const std = @import("std");
3982// :125:27: error: use of undefined value here causes illegal behavior3977// :125:27: error: use of undefined value here causes illegal behavior
3983// :125:27: note: when computing vector element at index '0'3978// :125:27: note: when computing vector element at index '0'
3984// :125:27: error: use of undefined value here causes illegal behavior3979// :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'
3986// :125:27: error: use of undefined value here causes illegal behavior3981// :125:27: error: use of undefined value here causes illegal behavior
3987// :125:27: note: when computing vector element at index '0'3982// :125:27: note: when computing vector element at index '0'
3988// :125:27: error: use of undefined value here causes illegal behavior3983// :125:27: error: use of undefined value here causes illegal behavior
...@@ -3990,6 +3985,7 @@ const std = @import("std");...@@ -3990,6 +3985,7 @@ const std = @import("std");
3990// :125:27: error: use of undefined value here causes illegal behavior3985// :125:27: error: use of undefined value here causes illegal behavior
3991// :125:27: note: when computing vector element at index '0'3986// :125:27: note: when computing vector element at index '0'
3992// :125:27: error: use of undefined value here causes illegal behavior3987// :125:27: error: use of undefined value here causes illegal behavior
3988// :125:27: note: when computing vector element at index '0'
3993// :125:27: error: use of undefined value here causes illegal behavior3989// :125:27: error: use of undefined value here causes illegal behavior
3994// :125:27: note: when computing vector element at index '0'3990// :125:27: note: when computing vector element at index '0'
3995// :125:27: error: use of undefined value here causes illegal behavior3991// :125:27: error: use of undefined value here causes illegal behavior
...@@ -3997,7 +3993,7 @@ const std = @import("std");...@@ -3997,7 +3993,7 @@ const std = @import("std");
3997// :125:27: error: use of undefined value here causes illegal behavior3993// :125:27: error: use of undefined value here causes illegal behavior
3998// :125:27: note: when computing vector element at index '0'3994// :125:27: note: when computing vector element at index '0'
3999// :125:27: error: use of undefined value here causes illegal behavior3995// :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'
4001// :125:27: error: use of undefined value here causes illegal behavior3997// :125:27: error: use of undefined value here causes illegal behavior
4002// :125:27: note: when computing vector element at index '0'3998// :125:27: note: when computing vector element at index '0'
4003// :125:27: error: use of undefined value here causes illegal behavior3999// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4005,6 +4001,7 @@ const std = @import("std");...@@ -4005,6 +4001,7 @@ const std = @import("std");
4005// :125:27: error: use of undefined value here causes illegal behavior4001// :125:27: error: use of undefined value here causes illegal behavior
4006// :125:27: note: when computing vector element at index '0'4002// :125:27: note: when computing vector element at index '0'
4007// :125:27: error: use of undefined value here causes illegal behavior4003// :125:27: error: use of undefined value here causes illegal behavior
4004// :125:27: note: when computing vector element at index '0'
4008// :125:27: error: use of undefined value here causes illegal behavior4005// :125:27: error: use of undefined value here causes illegal behavior
4009// :125:27: note: when computing vector element at index '0'4006// :125:27: note: when computing vector element at index '0'
4010// :125:27: error: use of undefined value here causes illegal behavior4007// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4012,7 +4009,7 @@ const std = @import("std");...@@ -4012,7 +4009,7 @@ const std = @import("std");
4012// :125:27: error: use of undefined value here causes illegal behavior4009// :125:27: error: use of undefined value here causes illegal behavior
4013// :125:27: note: when computing vector element at index '0'4010// :125:27: note: when computing vector element at index '0'
4014// :125:27: error: use of undefined value here causes illegal behavior4011// :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'
4016// :125:27: error: use of undefined value here causes illegal behavior4013// :125:27: error: use of undefined value here causes illegal behavior
4017// :125:27: note: when computing vector element at index '0'4014// :125:27: note: when computing vector element at index '0'
4018// :125:27: error: use of undefined value here causes illegal behavior4015// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4020,6 +4017,7 @@ const std = @import("std");...@@ -4020,6 +4017,7 @@ const std = @import("std");
4020// :125:27: error: use of undefined value here causes illegal behavior4017// :125:27: error: use of undefined value here causes illegal behavior
4021// :125:27: note: when computing vector element at index '0'4018// :125:27: note: when computing vector element at index '0'
4022// :125:27: error: use of undefined value here causes illegal behavior4019// :125:27: error: use of undefined value here causes illegal behavior
4020// :125:27: note: when computing vector element at index '0'
4023// :125:27: error: use of undefined value here causes illegal behavior4021// :125:27: error: use of undefined value here causes illegal behavior
4024// :125:27: note: when computing vector element at index '0'4022// :125:27: note: when computing vector element at index '0'
4025// :125:27: error: use of undefined value here causes illegal behavior4023// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4027,7 +4025,7 @@ const std = @import("std");...@@ -4027,7 +4025,7 @@ const std = @import("std");
4027// :125:27: error: use of undefined value here causes illegal behavior4025// :125:27: error: use of undefined value here causes illegal behavior
4028// :125:27: note: when computing vector element at index '0'4026// :125:27: note: when computing vector element at index '0'
4029// :125:27: error: use of undefined value here causes illegal behavior4027// :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'
4031// :125:27: error: use of undefined value here causes illegal behavior4029// :125:27: error: use of undefined value here causes illegal behavior
4032// :125:27: note: when computing vector element at index '0'4030// :125:27: note: when computing vector element at index '0'
4033// :125:27: error: use of undefined value here causes illegal behavior4031// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4035,6 +4033,7 @@ const std = @import("std");...@@ -4035,6 +4033,7 @@ const std = @import("std");
4035// :125:27: error: use of undefined value here causes illegal behavior4033// :125:27: error: use of undefined value here causes illegal behavior
4036// :125:27: note: when computing vector element at index '0'4034// :125:27: note: when computing vector element at index '0'
4037// :125:27: error: use of undefined value here causes illegal behavior4035// :125:27: error: use of undefined value here causes illegal behavior
4036// :125:27: note: when computing vector element at index '0'
4038// :125:27: error: use of undefined value here causes illegal behavior4037// :125:27: error: use of undefined value here causes illegal behavior
4039// :125:27: note: when computing vector element at index '0'4038// :125:27: note: when computing vector element at index '0'
4040// :125:27: error: use of undefined value here causes illegal behavior4039// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4042,7 +4041,7 @@ const std = @import("std");...@@ -4042,7 +4041,7 @@ const std = @import("std");
4042// :125:27: error: use of undefined value here causes illegal behavior4041// :125:27: error: use of undefined value here causes illegal behavior
4043// :125:27: note: when computing vector element at index '0'4042// :125:27: note: when computing vector element at index '0'
4044// :125:27: error: use of undefined value here causes illegal behavior4043// :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'
4046// :125:27: error: use of undefined value here causes illegal behavior4045// :125:27: error: use of undefined value here causes illegal behavior
4047// :125:27: note: when computing vector element at index '0'4046// :125:27: note: when computing vector element at index '0'
4048// :125:27: error: use of undefined value here causes illegal behavior4047// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4050,6 +4049,7 @@ const std = @import("std");...@@ -4050,6 +4049,7 @@ const std = @import("std");
4050// :125:27: error: use of undefined value here causes illegal behavior4049// :125:27: error: use of undefined value here causes illegal behavior
4051// :125:27: note: when computing vector element at index '0'4050// :125:27: note: when computing vector element at index '0'
4052// :125:27: error: use of undefined value here causes illegal behavior4051// :125:27: error: use of undefined value here causes illegal behavior
4052// :125:27: note: when computing vector element at index '0'
4053// :125:27: error: use of undefined value here causes illegal behavior4053// :125:27: error: use of undefined value here causes illegal behavior
4054// :125:27: note: when computing vector element at index '0'4054// :125:27: note: when computing vector element at index '0'
4055// :125:27: error: use of undefined value here causes illegal behavior4055// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4057,7 +4057,7 @@ const std = @import("std");...@@ -4057,7 +4057,7 @@ const std = @import("std");
4057// :125:27: error: use of undefined value here causes illegal behavior4057// :125:27: error: use of undefined value here causes illegal behavior
4058// :125:27: note: when computing vector element at index '0'4058// :125:27: note: when computing vector element at index '0'
4059// :125:27: error: use of undefined value here causes illegal behavior4059// :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'
4061// :125:27: error: use of undefined value here causes illegal behavior4061// :125:27: error: use of undefined value here causes illegal behavior
4062// :125:27: note: when computing vector element at index '0'4062// :125:27: note: when computing vector element at index '0'
4063// :125:27: error: use of undefined value here causes illegal behavior4063// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4065,6 +4065,7 @@ const std = @import("std");...@@ -4065,6 +4065,7 @@ const std = @import("std");
4065// :125:27: error: use of undefined value here causes illegal behavior4065// :125:27: error: use of undefined value here causes illegal behavior
4066// :125:27: note: when computing vector element at index '0'4066// :125:27: note: when computing vector element at index '0'
4067// :125:27: error: use of undefined value here causes illegal behavior4067// :125:27: error: use of undefined value here causes illegal behavior
4068// :125:27: note: when computing vector element at index '0'
4068// :125:27: error: use of undefined value here causes illegal behavior4069// :125:27: error: use of undefined value here causes illegal behavior
4069// :125:27: note: when computing vector element at index '0'4070// :125:27: note: when computing vector element at index '0'
4070// :125:27: error: use of undefined value here causes illegal behavior4071// :125:27: error: use of undefined value here causes illegal behavior
...@@ -4074,126 +4075,120 @@ const std = @import("std");...@@ -4074,126 +4075,120 @@ const std = @import("std");
4074// :125:27: error: use of undefined value here causes illegal behavior4075// :125:27: error: use of undefined value here causes illegal behavior
4075// :125:27: note: when computing vector element at index '1'4076// :125:27: note: when computing vector element at index '1'
4076// :125:27: error: use of undefined value here causes illegal behavior4077// :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: note: when computing vector element at index '1'
4078// :125:27: error: use of undefined value here causes illegal behavior
4079// :125:27: note: when computing vector element at index '0'
4080// :125:27: error: use of undefined value here causes illegal behavior4079// :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'
4082// :125:27: error: use of undefined value here causes illegal behavior4081// :125:27: error: use of undefined value here causes illegal behavior
4082// :125:27: note: when computing vector element at index '1'
4083// :125:27: error: use of undefined value here causes illegal behavior4083// :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'
4085// :125:27: error: use of undefined value here causes illegal behavior4085// :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'
4087// :125:27: error: use of undefined value here causes illegal behavior4087// :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'
4089// :125:27: error: use of undefined value here causes illegal behavior4089// :125:27: error: use of undefined value here causes illegal behavior
4090// :125:27: note: when computing vector element at index '1'4090// :125:27: note: when computing vector element at index '1'
4091// :125:27: error: use of undefined value here causes illegal behavior4091// :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'
4093// :125:27: error: use of undefined value here causes illegal behavior4093// :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'
4095// :125:27: error: use of undefined value here causes illegal behavior4095// :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'
4097// :125:30: error: use of undefined value here causes illegal behavior4097// :125:30: error: use of undefined value here causes illegal behavior
4098// :125:30: error: use of undefined value here causes illegal behavior4098// :125:30: error: use of undefined value here causes illegal behavior
4099// :125:30: note: when computing vector element at index '0'
4100// :125:30: error: use of undefined value here causes illegal behavior4099// :125:30: error: use of undefined value here causes illegal behavior
4101// :125:30: note: when computing vector element at index '0'
4102// :125:30: error: use of undefined value here causes illegal behavior4100// :125:30: error: use of undefined value here causes illegal behavior
4103// :125:30: note: when computing vector element at index '1'
4104// :125:30: error: use of undefined value here causes illegal behavior4101// :125:30: error: use of undefined value here causes illegal behavior
4105// :125:30: note: when computing vector element at index '0'
4106// :125:30: error: use of undefined value here causes illegal behavior4102// :125:30: error: use of undefined value here causes illegal behavior
4107// :125:30: note: when computing vector element at index '0'
4108// :125:30: error: use of undefined value here causes illegal behavior4103// :125:30: error: use of undefined value here causes illegal behavior
4109// :125:30: error: use of undefined value here causes illegal behavior4104// :125:30: error: use of undefined value here causes illegal behavior
4110// :125:30: note: when computing vector element at index '0'
4111// :125:30: error: use of undefined value here causes illegal behavior4105// :125:30: error: use of undefined value here causes illegal behavior
4112// :125:30: note: when computing vector element at index '0'
4113// :125:30: error: use of undefined value here causes illegal behavior4106// :125:30: error: use of undefined value here causes illegal behavior
4114// :125:30: note: when computing vector element at index '1'
4115// :125:30: error: use of undefined value here causes illegal behavior4107// :125:30: error: use of undefined value here causes illegal behavior
4116// :125:30: note: when computing vector element at index '0'
4117// :125:30: error: use of undefined value here causes illegal behavior4108// :125:30: error: use of undefined value here causes illegal behavior
4118// :125:30: note: when computing vector element at index '0'4109// :125:30: note: when computing vector element at index '0'
4119// :125:30: error: use of undefined value here causes illegal behavior4110// :125:30: error: use of undefined value here causes illegal behavior
4120// :125:30: error: use of undefined value here causes illegal behavior
4121// :125:30: note: when computing vector element at index '0'4111// :125:30: note: when computing vector element at index '0'
4122// :125:30: error: use of undefined value here causes illegal behavior4112// :125:30: error: use of undefined value here causes illegal behavior
4123// :125:30: note: when computing vector element at index '0'4113// :125:30: note: when computing vector element at index '0'
4124// :125:30: error: use of undefined value here causes illegal behavior4114// :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
4127// :125:30: note: when computing vector element at index '0'4115// :125:30: note: when computing vector element at index '0'
4128// :125:30: error: use of undefined value here causes illegal behavior4116// :125:30: error: use of undefined value here causes illegal behavior
4129// :125:30: note: when computing vector element at index '0'4117// :125:30: note: when computing vector element at index '0'
4130// :125:30: error: use of undefined value here causes illegal behavior4118// :125:30: error: use of undefined value here causes illegal behavior
4119// :125:30: note: when computing vector element at index '0'
4131// :125:30: error: use of undefined value here causes illegal behavior4120// :125:30: error: use of undefined value here causes illegal behavior
4132// :125:30: note: when computing vector element at index '0'4121// :125:30: note: when computing vector element at index '0'
4133// :125:30: error: use of undefined value here causes illegal behavior4122// :125:30: error: use of undefined value here causes illegal behavior
4134// :125:30: note: when computing vector element at index '0'4123// :125:30: note: when computing vector element at index '0'
4135// :125:30: error: use of undefined value here causes illegal behavior4124// :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'
4137// :125:30: error: use of undefined value here causes illegal behavior4126// :125:30: error: use of undefined value here causes illegal behavior
4138// :125:30: note: when computing vector element at index '0'4127// :125:30: note: when computing vector element at index '0'
4139// :125:30: error: use of undefined value here causes illegal behavior4128// :125:30: error: use of undefined value here causes illegal behavior
4140// :125:30: note: when computing vector element at index '0'4129// :125:30: note: when computing vector element at index '0'
4141// :125:30: error: use of undefined value here causes illegal behavior4130// :125:30: error: use of undefined value here causes illegal behavior
4131// :125:30: note: when computing vector element at index '0'
4142// :125:30: error: use of undefined value here causes illegal behavior4132// :125:30: error: use of undefined value here causes illegal behavior
4143// :125:30: note: when computing vector element at index '0'4133// :125:30: note: when computing vector element at index '0'
4144// :125:30: error: use of undefined value here causes illegal behavior4134// :125:30: error: use of undefined value here causes illegal behavior
4145// :125:30: note: when computing vector element at index '0'4135// :125:30: note: when computing vector element at index '0'
4146// :125:30: error: use of undefined value here causes illegal behavior4136// :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'
4148// :125:30: error: use of undefined value here causes illegal behavior4138// :125:30: error: use of undefined value here causes illegal behavior
4149// :125:30: note: when computing vector element at index '0'4139// :125:30: note: when computing vector element at index '0'
4150// :125:30: error: use of undefined value here causes illegal behavior4140// :125:30: error: use of undefined value here causes illegal behavior
4151// :125:30: note: when computing vector element at index '0'4141// :125:30: note: when computing vector element at index '0'
4152// :125:30: error: use of undefined value here causes illegal behavior4142// :125:30: error: use of undefined value here causes illegal behavior
4143// :125:30: note: when computing vector element at index '0'
4153// :125:30: error: use of undefined value here causes illegal behavior4144// :125:30: error: use of undefined value here causes illegal behavior
4154// :125:30: note: when computing vector element at index '0'4145// :125:30: note: when computing vector element at index '0'
4155// :125:30: error: use of undefined value here causes illegal behavior4146// :125:30: error: use of undefined value here causes illegal behavior
4156// :125:30: note: when computing vector element at index '0'4147// :125:30: note: when computing vector element at index '0'
4157// :125:30: error: use of undefined value here causes illegal behavior4148// :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'
4159// :125:30: error: use of undefined value here causes illegal behavior4150// :125:30: error: use of undefined value here causes illegal behavior
4160// :125:30: note: when computing vector element at index '0'4151// :125:30: note: when computing vector element at index '0'
4161// :125:30: error: use of undefined value here causes illegal behavior4152// :125:30: error: use of undefined value here causes illegal behavior
4162// :125:30: note: when computing vector element at index '0'4153// :125:30: note: when computing vector element at index '0'
4163// :125:30: error: use of undefined value here causes illegal behavior4154// :125:30: error: use of undefined value here causes illegal behavior
4155// :125:30: note: when computing vector element at index '0'
4164// :125:30: error: use of undefined value here causes illegal behavior4156// :125:30: error: use of undefined value here causes illegal behavior
4165// :125:30: note: when computing vector element at index '0'4157// :125:30: note: when computing vector element at index '0'
4166// :125:30: error: use of undefined value here causes illegal behavior4158// :125:30: error: use of undefined value here causes illegal behavior
4167// :125:30: note: when computing vector element at index '0'4159// :125:30: note: when computing vector element at index '0'
4168// :125:30: error: use of undefined value here causes illegal behavior4160// :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'
4170// :125:30: error: use of undefined value here causes illegal behavior4162// :125:30: error: use of undefined value here causes illegal behavior
4171// :125:30: note: when computing vector element at index '0'4163// :125:30: note: when computing vector element at index '0'
4172// :125:30: error: use of undefined value here causes illegal behavior4164// :125:30: error: use of undefined value here causes illegal behavior
4173// :125:30: note: when computing vector element at index '0'4165// :125:30: note: when computing vector element at index '0'
4174// :125:30: error: use of undefined value here causes illegal behavior4166// :125:30: error: use of undefined value here causes illegal behavior
4167// :125:30: note: when computing vector element at index '0'
4175// :125:30: error: use of undefined value here causes illegal behavior4168// :125:30: error: use of undefined value here causes illegal behavior
4176// :125:30: note: when computing vector element at index '0'4169// :125:30: note: when computing vector element at index '0'
4177// :125:30: error: use of undefined value here causes illegal behavior4170// :125:30: error: use of undefined value here causes illegal behavior
4178// :125:30: note: when computing vector element at index '0'4171// :125:30: note: when computing vector element at index '0'
4179// :125:30: error: use of undefined value here causes illegal behavior4172// :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'
4181// :125:30: error: use of undefined value here causes illegal behavior4174// :125:30: error: use of undefined value here causes illegal behavior
4182// :125:30: note: when computing vector element at index '0'4175// :125:30: note: when computing vector element at index '0'
4183// :125:30: error: use of undefined value here causes illegal behavior4176// :125:30: error: use of undefined value here causes illegal behavior
4184// :125:30: note: when computing vector element at index '0'4177// :125:30: note: when computing vector element at index '0'
4185// :125:30: error: use of undefined value here causes illegal behavior4178// :125:30: error: use of undefined value here causes illegal behavior
4179// :125:30: note: when computing vector element at index '0'
4186// :125:30: error: use of undefined value here causes illegal behavior4180// :125:30: error: use of undefined value here causes illegal behavior
4187// :125:30: note: when computing vector element at index '0'4181// :125:30: note: when computing vector element at index '0'
4188// :125:30: error: use of undefined value here causes illegal behavior4182// :125:30: error: use of undefined value here causes illegal behavior
4189// :125:30: note: when computing vector element at index '0'4183// :125:30: note: when computing vector element at index '0'
4190// :125:30: error: use of undefined value here causes illegal behavior4184// :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'
4192// :125:30: error: use of undefined value here causes illegal behavior4186// :125:30: error: use of undefined value here causes illegal behavior
4193// :125:30: note: when computing vector element at index '0'4187// :125:30: note: when computing vector element at index '0'
4194// :125:30: error: use of undefined value here causes illegal behavior4188// :125:30: error: use of undefined value here causes illegal behavior
4195// :125:30: note: when computing vector element at index '0'4189// :125:30: note: when computing vector element at index '0'
4196// :125:30: error: use of undefined value here causes illegal behavior4190// :125:30: error: use of undefined value here causes illegal behavior
4191// :125:30: note: when computing vector element at index '0'
4197// :125:30: error: use of undefined value here causes illegal behavior4192// :125:30: error: use of undefined value here causes illegal behavior
4198// :125:30: note: when computing vector element at index '0'4193// :125:30: note: when computing vector element at index '0'
4199// :125:30: error: use of undefined value here causes illegal behavior4194// :125:30: error: use of undefined value here causes illegal behavior
...@@ -4201,44 +4196,42 @@ const std = @import("std");...@@ -4201,44 +4196,42 @@ const std = @import("std");
4201// :125:30: error: use of undefined value here causes illegal behavior4196// :125:30: error: use of undefined value here causes illegal behavior
4202// :125:30: note: when computing vector element at index '1'4197// :125:30: note: when computing vector element at index '1'
4203// :125:30: error: use of undefined value here causes illegal behavior4198// :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'
4205// :125:30: error: use of undefined value here causes illegal behavior4200// :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'
4207// :125:30: error: use of undefined value here causes illegal behavior4202// :125:30: error: use of undefined value here causes illegal behavior
4203// :125:30: note: when computing vector element at index '1'
4208// :125:30: error: use of undefined value here causes illegal behavior4204// :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'
4210// :125:30: error: use of undefined value here causes illegal behavior4206// :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'
4212// :125:30: error: use of undefined value here causes illegal behavior4208// :125:30: error: use of undefined value here causes illegal behavior
4213// :125:30: note: when computing vector element at index '1'4209// :125:30: note: when computing vector element at index '1'
4214// :125:30: error: use of undefined value here causes illegal behavior4210// :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'
4216// :125:30: error: use of undefined value here causes illegal behavior4212// :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
4218// :129:27: error: use of undefined value here causes illegal behavior4219// :129:27: error: use of undefined value here causes illegal behavior
4219// :129:27: error: use of undefined value here causes illegal behavior4220// :129:27: error: use of undefined value here causes illegal behavior
4220// :129:27: note: when computing vector element at index '0'
4221// :129:27: error: use of undefined value here causes illegal behavior4221// :129:27: error: use of undefined value here causes illegal behavior
4222// :129:27: note: when computing vector element at index '0'
4223// :129:27: error: use of undefined value here causes illegal behavior4222// :129:27: error: use of undefined value here causes illegal behavior
4224// :129:27: note: when computing vector element at index '0'
4225// :129:27: error: use of undefined value here causes illegal behavior4223// :129:27: error: use of undefined value here causes illegal behavior
4226// :129:27: note: when computing vector element at index '1'
4227// :129:27: error: use of undefined value here causes illegal behavior4224// :129:27: error: use of undefined value here causes illegal behavior
4228// :129:27: note: when computing vector element at index '0'
4229// :129:27: error: use of undefined value here causes illegal behavior4225// :129:27: error: use of undefined value here causes illegal behavior
4230// :129:27: note: when computing vector element at index '0'
4231// :129:27: error: use of undefined value here causes illegal behavior4226// :129:27: error: use of undefined value here causes illegal behavior
4232// :129:27: note: when computing vector element at index '0'
4233// :129:27: error: use of undefined value here causes illegal behavior4227// :129:27: error: use of undefined value here causes illegal behavior
4234// :129:27: error: use of undefined value here causes illegal behavior4228// :129:27: error: use of undefined value here causes illegal behavior
4235// :129:27: note: when computing vector element at index '0'
4236// :129:27: error: use of undefined value here causes illegal behavior4229// :129:27: error: use of undefined value here causes illegal behavior
4237// :129:27: note: when computing vector element at index '0'4230// :129:27: note: when computing vector element at index '0'
4238// :129:27: error: use of undefined value here causes illegal behavior4231// :129:27: error: use of undefined value here causes illegal behavior
4239// :129:27: note: when computing vector element at index '0'4232// :129:27: note: when computing vector element at index '0'
4240// :129:27: error: use of undefined value here causes illegal behavior4233// :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'
4242// :129:27: error: use of undefined value here causes illegal behavior4235// :129:27: error: use of undefined value here causes illegal behavior
4243// :129:27: note: when computing vector element at index '0'4236// :129:27: note: when computing vector element at index '0'
4244// :129:27: error: use of undefined value here causes illegal behavior4237// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4246,6 +4239,7 @@ const std = @import("std");...@@ -4246,6 +4239,7 @@ const std = @import("std");
4246// :129:27: error: use of undefined value here causes illegal behavior4239// :129:27: error: use of undefined value here causes illegal behavior
4247// :129:27: note: when computing vector element at index '0'4240// :129:27: note: when computing vector element at index '0'
4248// :129:27: error: use of undefined value here causes illegal behavior4241// :129:27: error: use of undefined value here causes illegal behavior
4242// :129:27: note: when computing vector element at index '0'
4249// :129:27: error: use of undefined value here causes illegal behavior4243// :129:27: error: use of undefined value here causes illegal behavior
4250// :129:27: note: when computing vector element at index '0'4244// :129:27: note: when computing vector element at index '0'
4251// :129:27: error: use of undefined value here causes illegal behavior4245// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4253,7 +4247,7 @@ const std = @import("std");...@@ -4253,7 +4247,7 @@ const std = @import("std");
4253// :129:27: error: use of undefined value here causes illegal behavior4247// :129:27: error: use of undefined value here causes illegal behavior
4254// :129:27: note: when computing vector element at index '0'4248// :129:27: note: when computing vector element at index '0'
4255// :129:27: error: use of undefined value here causes illegal behavior4249// :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'
4257// :129:27: error: use of undefined value here causes illegal behavior4251// :129:27: error: use of undefined value here causes illegal behavior
4258// :129:27: note: when computing vector element at index '0'4252// :129:27: note: when computing vector element at index '0'
4259// :129:27: error: use of undefined value here causes illegal behavior4253// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4261,6 +4255,7 @@ const std = @import("std");...@@ -4261,6 +4255,7 @@ const std = @import("std");
4261// :129:27: error: use of undefined value here causes illegal behavior4255// :129:27: error: use of undefined value here causes illegal behavior
4262// :129:27: note: when computing vector element at index '0'4256// :129:27: note: when computing vector element at index '0'
4263// :129:27: error: use of undefined value here causes illegal behavior4257// :129:27: error: use of undefined value here causes illegal behavior
4258// :129:27: note: when computing vector element at index '0'
4264// :129:27: error: use of undefined value here causes illegal behavior4259// :129:27: error: use of undefined value here causes illegal behavior
4265// :129:27: note: when computing vector element at index '0'4260// :129:27: note: when computing vector element at index '0'
4266// :129:27: error: use of undefined value here causes illegal behavior4261// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4268,7 +4263,7 @@ const std = @import("std");...@@ -4268,7 +4263,7 @@ const std = @import("std");
4268// :129:27: error: use of undefined value here causes illegal behavior4263// :129:27: error: use of undefined value here causes illegal behavior
4269// :129:27: note: when computing vector element at index '0'4264// :129:27: note: when computing vector element at index '0'
4270// :129:27: error: use of undefined value here causes illegal behavior4265// :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'
4272// :129:27: error: use of undefined value here causes illegal behavior4267// :129:27: error: use of undefined value here causes illegal behavior
4273// :129:27: note: when computing vector element at index '0'4268// :129:27: note: when computing vector element at index '0'
4274// :129:27: error: use of undefined value here causes illegal behavior4269// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4276,6 +4271,7 @@ const std = @import("std");...@@ -4276,6 +4271,7 @@ const std = @import("std");
4276// :129:27: error: use of undefined value here causes illegal behavior4271// :129:27: error: use of undefined value here causes illegal behavior
4277// :129:27: note: when computing vector element at index '0'4272// :129:27: note: when computing vector element at index '0'
4278// :129:27: error: use of undefined value here causes illegal behavior4273// :129:27: error: use of undefined value here causes illegal behavior
4274// :129:27: note: when computing vector element at index '0'
4279// :129:27: error: use of undefined value here causes illegal behavior4275// :129:27: error: use of undefined value here causes illegal behavior
4280// :129:27: note: when computing vector element at index '0'4276// :129:27: note: when computing vector element at index '0'
4281// :129:27: error: use of undefined value here causes illegal behavior4277// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4283,7 +4279,7 @@ const std = @import("std");...@@ -4283,7 +4279,7 @@ const std = @import("std");
4283// :129:27: error: use of undefined value here causes illegal behavior4279// :129:27: error: use of undefined value here causes illegal behavior
4284// :129:27: note: when computing vector element at index '0'4280// :129:27: note: when computing vector element at index '0'
4285// :129:27: error: use of undefined value here causes illegal behavior4281// :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'
4287// :129:27: error: use of undefined value here causes illegal behavior4283// :129:27: error: use of undefined value here causes illegal behavior
4288// :129:27: note: when computing vector element at index '0'4284// :129:27: note: when computing vector element at index '0'
4289// :129:27: error: use of undefined value here causes illegal behavior4285// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4291,6 +4287,7 @@ const std = @import("std");...@@ -4291,6 +4287,7 @@ const std = @import("std");
4291// :129:27: error: use of undefined value here causes illegal behavior4287// :129:27: error: use of undefined value here causes illegal behavior
4292// :129:27: note: when computing vector element at index '0'4288// :129:27: note: when computing vector element at index '0'
4293// :129:27: error: use of undefined value here causes illegal behavior4289// :129:27: error: use of undefined value here causes illegal behavior
4290// :129:27: note: when computing vector element at index '0'
4294// :129:27: error: use of undefined value here causes illegal behavior4291// :129:27: error: use of undefined value here causes illegal behavior
4295// :129:27: note: when computing vector element at index '0'4292// :129:27: note: when computing vector element at index '0'
4296// :129:27: error: use of undefined value here causes illegal behavior4293// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4298,7 +4295,7 @@ const std = @import("std");...@@ -4298,7 +4295,7 @@ const std = @import("std");
4298// :129:27: error: use of undefined value here causes illegal behavior4295// :129:27: error: use of undefined value here causes illegal behavior
4299// :129:27: note: when computing vector element at index '0'4296// :129:27: note: when computing vector element at index '0'
4300// :129:27: error: use of undefined value here causes illegal behavior4297// :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'
4302// :129:27: error: use of undefined value here causes illegal behavior4299// :129:27: error: use of undefined value here causes illegal behavior
4303// :129:27: note: when computing vector element at index '0'4300// :129:27: note: when computing vector element at index '0'
4304// :129:27: error: use of undefined value here causes illegal behavior4301// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4306,6 +4303,7 @@ const std = @import("std");...@@ -4306,6 +4303,7 @@ const std = @import("std");
4306// :129:27: error: use of undefined value here causes illegal behavior4303// :129:27: error: use of undefined value here causes illegal behavior
4307// :129:27: note: when computing vector element at index '0'4304// :129:27: note: when computing vector element at index '0'
4308// :129:27: error: use of undefined value here causes illegal behavior4305// :129:27: error: use of undefined value here causes illegal behavior
4306// :129:27: note: when computing vector element at index '0'
4309// :129:27: error: use of undefined value here causes illegal behavior4307// :129:27: error: use of undefined value here causes illegal behavior
4310// :129:27: note: when computing vector element at index '0'4308// :129:27: note: when computing vector element at index '0'
4311// :129:27: error: use of undefined value here causes illegal behavior4309// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4313,7 +4311,7 @@ const std = @import("std");...@@ -4313,7 +4311,7 @@ const std = @import("std");
4313// :129:27: error: use of undefined value here causes illegal behavior4311// :129:27: error: use of undefined value here causes illegal behavior
4314// :129:27: note: when computing vector element at index '0'4312// :129:27: note: when computing vector element at index '0'
4315// :129:27: error: use of undefined value here causes illegal behavior4313// :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'
4317// :129:27: error: use of undefined value here causes illegal behavior4315// :129:27: error: use of undefined value here causes illegal behavior
4318// :129:27: note: when computing vector element at index '0'4316// :129:27: note: when computing vector element at index '0'
4319// :129:27: error: use of undefined value here causes illegal behavior4317// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4321,6 +4319,7 @@ const std = @import("std");...@@ -4321,6 +4319,7 @@ const std = @import("std");
4321// :129:27: error: use of undefined value here causes illegal behavior4319// :129:27: error: use of undefined value here causes illegal behavior
4322// :129:27: note: when computing vector element at index '0'4320// :129:27: note: when computing vector element at index '0'
4323// :129:27: error: use of undefined value here causes illegal behavior4321// :129:27: error: use of undefined value here causes illegal behavior
4322// :129:27: note: when computing vector element at index '0'
4324// :129:27: error: use of undefined value here causes illegal behavior4323// :129:27: error: use of undefined value here causes illegal behavior
4325// :129:27: note: when computing vector element at index '0'4324// :129:27: note: when computing vector element at index '0'
4326// :129:27: error: use of undefined value here causes illegal behavior4325// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4328,7 +4327,7 @@ const std = @import("std");...@@ -4328,7 +4327,7 @@ const std = @import("std");
4328// :129:27: error: use of undefined value here causes illegal behavior4327// :129:27: error: use of undefined value here causes illegal behavior
4329// :129:27: note: when computing vector element at index '0'4328// :129:27: note: when computing vector element at index '0'
4330// :129:27: error: use of undefined value here causes illegal behavior4329// :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'
4332// :129:27: error: use of undefined value here causes illegal behavior4331// :129:27: error: use of undefined value here causes illegal behavior
4333// :129:27: note: when computing vector element at index '0'4332// :129:27: note: when computing vector element at index '0'
4334// :129:27: error: use of undefined value here causes illegal behavior4333// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4336,6 +4335,7 @@ const std = @import("std");...@@ -4336,6 +4335,7 @@ const std = @import("std");
4336// :129:27: error: use of undefined value here causes illegal behavior4335// :129:27: error: use of undefined value here causes illegal behavior
4337// :129:27: note: when computing vector element at index '0'4336// :129:27: note: when computing vector element at index '0'
4338// :129:27: error: use of undefined value here causes illegal behavior4337// :129:27: error: use of undefined value here causes illegal behavior
4338// :129:27: note: when computing vector element at index '0'
4339// :129:27: error: use of undefined value here causes illegal behavior4339// :129:27: error: use of undefined value here causes illegal behavior
4340// :129:27: note: when computing vector element at index '0'4340// :129:27: note: when computing vector element at index '0'
4341// :129:27: error: use of undefined value here causes illegal behavior4341// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4343,7 +4343,7 @@ const std = @import("std");...@@ -4343,7 +4343,7 @@ const std = @import("std");
4343// :129:27: error: use of undefined value here causes illegal behavior4343// :129:27: error: use of undefined value here causes illegal behavior
4344// :129:27: note: when computing vector element at index '0'4344// :129:27: note: when computing vector element at index '0'
4345// :129:27: error: use of undefined value here causes illegal behavior4345// :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'
4347// :129:27: error: use of undefined value here causes illegal behavior4347// :129:27: error: use of undefined value here causes illegal behavior
4348// :129:27: note: when computing vector element at index '0'4348// :129:27: note: when computing vector element at index '0'
4349// :129:27: error: use of undefined value here causes illegal behavior4349// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4351,6 +4351,7 @@ const std = @import("std");...@@ -4351,6 +4351,7 @@ const std = @import("std");
4351// :129:27: error: use of undefined value here causes illegal behavior4351// :129:27: error: use of undefined value here causes illegal behavior
4352// :129:27: note: when computing vector element at index '0'4352// :129:27: note: when computing vector element at index '0'
4353// :129:27: error: use of undefined value here causes illegal behavior4353// :129:27: error: use of undefined value here causes illegal behavior
4354// :129:27: note: when computing vector element at index '0'
4354// :129:27: error: use of undefined value here causes illegal behavior4355// :129:27: error: use of undefined value here causes illegal behavior
4355// :129:27: note: when computing vector element at index '0'4356// :129:27: note: when computing vector element at index '0'
4356// :129:27: error: use of undefined value here causes illegal behavior4357// :129:27: error: use of undefined value here causes illegal behavior
...@@ -4360,126 +4361,120 @@ const std = @import("std");...@@ -4360,126 +4361,120 @@ const std = @import("std");
4360// :129:27: error: use of undefined value here causes illegal behavior4361// :129:27: error: use of undefined value here causes illegal behavior
4361// :129:27: note: when computing vector element at index '1'4362// :129:27: note: when computing vector element at index '1'
4362// :129:27: error: use of undefined value here causes illegal behavior4363// :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: note: when computing vector element at index '1'
4364// :129:27: error: use of undefined value here causes illegal behavior
4365// :129:27: note: when computing vector element at index '0'
4366// :129:27: error: use of undefined value here causes illegal behavior4365// :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'
4368// :129:27: error: use of undefined value here causes illegal behavior4367// :129:27: error: use of undefined value here causes illegal behavior
4368// :129:27: note: when computing vector element at index '1'
4369// :129:27: error: use of undefined value here causes illegal behavior4369// :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'
4371// :129:27: error: use of undefined value here causes illegal behavior4371// :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'
4373// :129:27: error: use of undefined value here causes illegal behavior4373// :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'
4375// :129:27: error: use of undefined value here causes illegal behavior4375// :129:27: error: use of undefined value here causes illegal behavior
4376// :129:27: note: when computing vector element at index '1'4376// :129:27: note: when computing vector element at index '1'
4377// :129:27: error: use of undefined value here causes illegal behavior4377// :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'
4379// :129:27: error: use of undefined value here causes illegal behavior4379// :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'
4381// :129:27: error: use of undefined value here causes illegal behavior4381// :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'
4383// :129:30: error: use of undefined value here causes illegal behavior4383// :129:30: error: use of undefined value here causes illegal behavior
4384// :129:30: error: use of undefined value here causes illegal behavior4384// :129:30: error: use of undefined value here causes illegal behavior
4385// :129:30: note: when computing vector element at index '0'
4386// :129:30: error: use of undefined value here causes illegal behavior4385// :129:30: error: use of undefined value here causes illegal behavior
4387// :129:30: note: when computing vector element at index '0'
4388// :129:30: error: use of undefined value here causes illegal behavior4386// :129:30: error: use of undefined value here causes illegal behavior
4389// :129:30: note: when computing vector element at index '1'
4390// :129:30: error: use of undefined value here causes illegal behavior4387// :129:30: error: use of undefined value here causes illegal behavior
4391// :129:30: note: when computing vector element at index '0'
4392// :129:30: error: use of undefined value here causes illegal behavior4388// :129:30: error: use of undefined value here causes illegal behavior
4393// :129:30: note: when computing vector element at index '0'
4394// :129:30: error: use of undefined value here causes illegal behavior4389// :129:30: error: use of undefined value here causes illegal behavior
4395// :129:30: error: use of undefined value here causes illegal behavior4390// :129:30: error: use of undefined value here causes illegal behavior
4396// :129:30: note: when computing vector element at index '0'
4397// :129:30: error: use of undefined value here causes illegal behavior4391// :129:30: error: use of undefined value here causes illegal behavior
4398// :129:30: note: when computing vector element at index '0'
4399// :129:30: error: use of undefined value here causes illegal behavior4392// :129:30: error: use of undefined value here causes illegal behavior
4400// :129:30: note: when computing vector element at index '1'
4401// :129:30: error: use of undefined value here causes illegal behavior4393// :129:30: error: use of undefined value here causes illegal behavior
4402// :129:30: note: when computing vector element at index '0'
4403// :129:30: error: use of undefined value here causes illegal behavior4394// :129:30: error: use of undefined value here causes illegal behavior
4404// :129:30: note: when computing vector element at index '0'4395// :129:30: note: when computing vector element at index '0'
4405// :129:30: error: use of undefined value here causes illegal behavior4396// :129:30: error: use of undefined value here causes illegal behavior
4406// :129:30: error: use of undefined value here causes illegal behavior
4407// :129:30: note: when computing vector element at index '0'4397// :129:30: note: when computing vector element at index '0'
4408// :129:30: error: use of undefined value here causes illegal behavior4398// :129:30: error: use of undefined value here causes illegal behavior
4409// :129:30: note: when computing vector element at index '0'4399// :129:30: note: when computing vector element at index '0'
4410// :129:30: error: use of undefined value here causes illegal behavior4400// :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
4413// :129:30: note: when computing vector element at index '0'4401// :129:30: note: when computing vector element at index '0'
4414// :129:30: error: use of undefined value here causes illegal behavior4402// :129:30: error: use of undefined value here causes illegal behavior
4415// :129:30: note: when computing vector element at index '0'4403// :129:30: note: when computing vector element at index '0'
4416// :129:30: error: use of undefined value here causes illegal behavior4404// :129:30: error: use of undefined value here causes illegal behavior
4405// :129:30: note: when computing vector element at index '0'
4417// :129:30: error: use of undefined value here causes illegal behavior4406// :129:30: error: use of undefined value here causes illegal behavior
4418// :129:30: note: when computing vector element at index '0'4407// :129:30: note: when computing vector element at index '0'
4419// :129:30: error: use of undefined value here causes illegal behavior4408// :129:30: error: use of undefined value here causes illegal behavior
4420// :129:30: note: when computing vector element at index '0'4409// :129:30: note: when computing vector element at index '0'
4421// :129:30: error: use of undefined value here causes illegal behavior4410// :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'
4423// :129:30: error: use of undefined value here causes illegal behavior4412// :129:30: error: use of undefined value here causes illegal behavior
4424// :129:30: note: when computing vector element at index '0'4413// :129:30: note: when computing vector element at index '0'
4425// :129:30: error: use of undefined value here causes illegal behavior4414// :129:30: error: use of undefined value here causes illegal behavior
4426// :129:30: note: when computing vector element at index '0'4415// :129:30: note: when computing vector element at index '0'
4427// :129:30: error: use of undefined value here causes illegal behavior4416// :129:30: error: use of undefined value here causes illegal behavior
4417// :129:30: note: when computing vector element at index '0'
4428// :129:30: error: use of undefined value here causes illegal behavior4418// :129:30: error: use of undefined value here causes illegal behavior
4429// :129:30: note: when computing vector element at index '0'4419// :129:30: note: when computing vector element at index '0'
4430// :129:30: error: use of undefined value here causes illegal behavior4420// :129:30: error: use of undefined value here causes illegal behavior
4431// :129:30: note: when computing vector element at index '0'4421// :129:30: note: when computing vector element at index '0'
4432// :129:30: error: use of undefined value here causes illegal behavior4422// :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'
4434// :129:30: error: use of undefined value here causes illegal behavior4424// :129:30: error: use of undefined value here causes illegal behavior
4435// :129:30: note: when computing vector element at index '0'4425// :129:30: note: when computing vector element at index '0'
4436// :129:30: error: use of undefined value here causes illegal behavior4426// :129:30: error: use of undefined value here causes illegal behavior
4437// :129:30: note: when computing vector element at index '0'4427// :129:30: note: when computing vector element at index '0'
4438// :129:30: error: use of undefined value here causes illegal behavior4428// :129:30: error: use of undefined value here causes illegal behavior
4429// :129:30: note: when computing vector element at index '0'
4439// :129:30: error: use of undefined value here causes illegal behavior4430// :129:30: error: use of undefined value here causes illegal behavior
4440// :129:30: note: when computing vector element at index '0'4431// :129:30: note: when computing vector element at index '0'
4441// :129:30: error: use of undefined value here causes illegal behavior4432// :129:30: error: use of undefined value here causes illegal behavior
4442// :129:30: note: when computing vector element at index '0'4433// :129:30: note: when computing vector element at index '0'
4443// :129:30: error: use of undefined value here causes illegal behavior4434// :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'
4445// :129:30: error: use of undefined value here causes illegal behavior4436// :129:30: error: use of undefined value here causes illegal behavior
4446// :129:30: note: when computing vector element at index '0'4437// :129:30: note: when computing vector element at index '0'
4447// :129:30: error: use of undefined value here causes illegal behavior4438// :129:30: error: use of undefined value here causes illegal behavior
4448// :129:30: note: when computing vector element at index '0'4439// :129:30: note: when computing vector element at index '0'
4449// :129:30: error: use of undefined value here causes illegal behavior4440// :129:30: error: use of undefined value here causes illegal behavior
4441// :129:30: note: when computing vector element at index '0'
4450// :129:30: error: use of undefined value here causes illegal behavior4442// :129:30: error: use of undefined value here causes illegal behavior
4451// :129:30: note: when computing vector element at index '0'4443// :129:30: note: when computing vector element at index '0'
4452// :129:30: error: use of undefined value here causes illegal behavior4444// :129:30: error: use of undefined value here causes illegal behavior
4453// :129:30: note: when computing vector element at index '0'4445// :129:30: note: when computing vector element at index '0'
4454// :129:30: error: use of undefined value here causes illegal behavior4446// :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'
4456// :129:30: error: use of undefined value here causes illegal behavior4448// :129:30: error: use of undefined value here causes illegal behavior
4457// :129:30: note: when computing vector element at index '0'4449// :129:30: note: when computing vector element at index '0'
4458// :129:30: error: use of undefined value here causes illegal behavior4450// :129:30: error: use of undefined value here causes illegal behavior
4459// :129:30: note: when computing vector element at index '0'4451// :129:30: note: when computing vector element at index '0'
4460// :129:30: error: use of undefined value here causes illegal behavior4452// :129:30: error: use of undefined value here causes illegal behavior
4453// :129:30: note: when computing vector element at index '0'
4461// :129:30: error: use of undefined value here causes illegal behavior4454// :129:30: error: use of undefined value here causes illegal behavior
4462// :129:30: note: when computing vector element at index '0'4455// :129:30: note: when computing vector element at index '0'
4463// :129:30: error: use of undefined value here causes illegal behavior4456// :129:30: error: use of undefined value here causes illegal behavior
4464// :129:30: note: when computing vector element at index '0'4457// :129:30: note: when computing vector element at index '0'
4465// :129:30: error: use of undefined value here causes illegal behavior4458// :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'
4467// :129:30: error: use of undefined value here causes illegal behavior4460// :129:30: error: use of undefined value here causes illegal behavior
4468// :129:30: note: when computing vector element at index '0'4461// :129:30: note: when computing vector element at index '0'
4469// :129:30: error: use of undefined value here causes illegal behavior4462// :129:30: error: use of undefined value here causes illegal behavior
4470// :129:30: note: when computing vector element at index '0'4463// :129:30: note: when computing vector element at index '0'
4471// :129:30: error: use of undefined value here causes illegal behavior4464// :129:30: error: use of undefined value here causes illegal behavior
4465// :129:30: note: when computing vector element at index '0'
4472// :129:30: error: use of undefined value here causes illegal behavior4466// :129:30: error: use of undefined value here causes illegal behavior
4473// :129:30: note: when computing vector element at index '0'4467// :129:30: note: when computing vector element at index '0'
4474// :129:30: error: use of undefined value here causes illegal behavior4468// :129:30: error: use of undefined value here causes illegal behavior
4475// :129:30: note: when computing vector element at index '0'4469// :129:30: note: when computing vector element at index '0'
4476// :129:30: error: use of undefined value here causes illegal behavior4470// :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'
4478// :129:30: error: use of undefined value here causes illegal behavior4472// :129:30: error: use of undefined value here causes illegal behavior
4479// :129:30: note: when computing vector element at index '0'4473// :129:30: note: when computing vector element at index '0'
4480// :129:30: error: use of undefined value here causes illegal behavior4474// :129:30: error: use of undefined value here causes illegal behavior
4481// :129:30: note: when computing vector element at index '0'4475// :129:30: note: when computing vector element at index '0'
4482// :129:30: error: use of undefined value here causes illegal behavior4476// :129:30: error: use of undefined value here causes illegal behavior
4477// :129:30: note: when computing vector element at index '0'
4483// :129:30: error: use of undefined value here causes illegal behavior4478// :129:30: error: use of undefined value here causes illegal behavior
4484// :129:30: note: when computing vector element at index '0'4479// :129:30: note: when computing vector element at index '0'
4485// :129:30: error: use of undefined value here causes illegal behavior4480// :129:30: error: use of undefined value here causes illegal behavior
...@@ -4487,44 +4482,42 @@ const std = @import("std");...@@ -4487,44 +4482,42 @@ const std = @import("std");
4487// :129:30: error: use of undefined value here causes illegal behavior4482// :129:30: error: use of undefined value here causes illegal behavior
4488// :129:30: note: when computing vector element at index '1'4483// :129:30: note: when computing vector element at index '1'
4489// :129:30: error: use of undefined value here causes illegal behavior4484// :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'
4491// :129:30: error: use of undefined value here causes illegal behavior4486// :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'
4493// :129:30: error: use of undefined value here causes illegal behavior4490// :129:30: error: use of undefined value here causes illegal behavior
4491// :129:30: note: when computing vector element at index '1'
4494// :129:30: error: use of undefined value here causes illegal behavior4492// :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'
4496// :129:30: error: use of undefined value here causes illegal behavior4494// :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'
4498// :129:30: error: use of undefined value here causes illegal behavior4496// :129:30: error: use of undefined value here causes illegal behavior
4499// :129:30: note: when computing vector element at index '1'4497// :129:30: note: when computing vector element at index '1'
4500// :129:30: error: use of undefined value here causes illegal behavior4498// :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'
4502// :129:30: error: use of undefined value here causes illegal behavior4500// :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
4504// :133:27: error: use of undefined value here causes illegal behavior4505// :133:27: error: use of undefined value here causes illegal behavior
4505// :133:27: error: use of undefined value here causes illegal behavior4506// :133:27: error: use of undefined value here causes illegal behavior
4506// :133:27: note: when computing vector element at index '0'
4507// :133:27: error: use of undefined value here causes illegal behavior4507// :133:27: error: use of undefined value here causes illegal behavior
4508// :133:27: note: when computing vector element at index '0'
4509// :133:27: error: use of undefined value here causes illegal behavior4508// :133:27: error: use of undefined value here causes illegal behavior
4510// :133:27: note: when computing vector element at index '0'
4511// :133:27: error: use of undefined value here causes illegal behavior4509// :133:27: error: use of undefined value here causes illegal behavior
4512// :133:27: note: when computing vector element at index '1'
4513// :133:27: error: use of undefined value here causes illegal behavior4510// :133:27: error: use of undefined value here causes illegal behavior
4514// :133:27: note: when computing vector element at index '0'
4515// :133:27: error: use of undefined value here causes illegal behavior4511// :133:27: error: use of undefined value here causes illegal behavior
4516// :133:27: note: when computing vector element at index '0'
4517// :133:27: error: use of undefined value here causes illegal behavior4512// :133:27: error: use of undefined value here causes illegal behavior
4518// :133:27: note: when computing vector element at index '0'
4519// :133:27: error: use of undefined value here causes illegal behavior4513// :133:27: error: use of undefined value here causes illegal behavior
4520// :133:27: error: use of undefined value here causes illegal behavior4514// :133:27: error: use of undefined value here causes illegal behavior
4521// :133:27: note: when computing vector element at index '0'
4522// :133:27: error: use of undefined value here causes illegal behavior4515// :133:27: error: use of undefined value here causes illegal behavior
4523// :133:27: note: when computing vector element at index '0'4516// :133:27: note: when computing vector element at index '0'
4524// :133:27: error: use of undefined value here causes illegal behavior4517// :133:27: error: use of undefined value here causes illegal behavior
4525// :133:27: note: when computing vector element at index '0'4518// :133:27: note: when computing vector element at index '0'
4526// :133:27: error: use of undefined value here causes illegal behavior4519// :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'
4528// :133:27: error: use of undefined value here causes illegal behavior4521// :133:27: error: use of undefined value here causes illegal behavior
4529// :133:27: note: when computing vector element at index '0'4522// :133:27: note: when computing vector element at index '0'
4530// :133:27: error: use of undefined value here causes illegal behavior4523// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4532,6 +4525,7 @@ const std = @import("std");...@@ -4532,6 +4525,7 @@ const std = @import("std");
4532// :133:27: error: use of undefined value here causes illegal behavior4525// :133:27: error: use of undefined value here causes illegal behavior
4533// :133:27: note: when computing vector element at index '0'4526// :133:27: note: when computing vector element at index '0'
4534// :133:27: error: use of undefined value here causes illegal behavior4527// :133:27: error: use of undefined value here causes illegal behavior
4528// :133:27: note: when computing vector element at index '0'
4535// :133:27: error: use of undefined value here causes illegal behavior4529// :133:27: error: use of undefined value here causes illegal behavior
4536// :133:27: note: when computing vector element at index '0'4530// :133:27: note: when computing vector element at index '0'
4537// :133:27: error: use of undefined value here causes illegal behavior4531// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4539,7 +4533,7 @@ const std = @import("std");...@@ -4539,7 +4533,7 @@ const std = @import("std");
4539// :133:27: error: use of undefined value here causes illegal behavior4533// :133:27: error: use of undefined value here causes illegal behavior
4540// :133:27: note: when computing vector element at index '0'4534// :133:27: note: when computing vector element at index '0'
4541// :133:27: error: use of undefined value here causes illegal behavior4535// :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'
4543// :133:27: error: use of undefined value here causes illegal behavior4537// :133:27: error: use of undefined value here causes illegal behavior
4544// :133:27: note: when computing vector element at index '0'4538// :133:27: note: when computing vector element at index '0'
4545// :133:27: error: use of undefined value here causes illegal behavior4539// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4547,6 +4541,7 @@ const std = @import("std");...@@ -4547,6 +4541,7 @@ const std = @import("std");
4547// :133:27: error: use of undefined value here causes illegal behavior4541// :133:27: error: use of undefined value here causes illegal behavior
4548// :133:27: note: when computing vector element at index '0'4542// :133:27: note: when computing vector element at index '0'
4549// :133:27: error: use of undefined value here causes illegal behavior4543// :133:27: error: use of undefined value here causes illegal behavior
4544// :133:27: note: when computing vector element at index '0'
4550// :133:27: error: use of undefined value here causes illegal behavior4545// :133:27: error: use of undefined value here causes illegal behavior
4551// :133:27: note: when computing vector element at index '0'4546// :133:27: note: when computing vector element at index '0'
4552// :133:27: error: use of undefined value here causes illegal behavior4547// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4554,7 +4549,7 @@ const std = @import("std");...@@ -4554,7 +4549,7 @@ const std = @import("std");
4554// :133:27: error: use of undefined value here causes illegal behavior4549// :133:27: error: use of undefined value here causes illegal behavior
4555// :133:27: note: when computing vector element at index '0'4550// :133:27: note: when computing vector element at index '0'
4556// :133:27: error: use of undefined value here causes illegal behavior4551// :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'
4558// :133:27: error: use of undefined value here causes illegal behavior4553// :133:27: error: use of undefined value here causes illegal behavior
4559// :133:27: note: when computing vector element at index '0'4554// :133:27: note: when computing vector element at index '0'
4560// :133:27: error: use of undefined value here causes illegal behavior4555// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4562,6 +4557,7 @@ const std = @import("std");...@@ -4562,6 +4557,7 @@ const std = @import("std");
4562// :133:27: error: use of undefined value here causes illegal behavior4557// :133:27: error: use of undefined value here causes illegal behavior
4563// :133:27: note: when computing vector element at index '0'4558// :133:27: note: when computing vector element at index '0'
4564// :133:27: error: use of undefined value here causes illegal behavior4559// :133:27: error: use of undefined value here causes illegal behavior
4560// :133:27: note: when computing vector element at index '0'
4565// :133:27: error: use of undefined value here causes illegal behavior4561// :133:27: error: use of undefined value here causes illegal behavior
4566// :133:27: note: when computing vector element at index '0'4562// :133:27: note: when computing vector element at index '0'
4567// :133:27: error: use of undefined value here causes illegal behavior4563// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4569,7 +4565,7 @@ const std = @import("std");...@@ -4569,7 +4565,7 @@ const std = @import("std");
4569// :133:27: error: use of undefined value here causes illegal behavior4565// :133:27: error: use of undefined value here causes illegal behavior
4570// :133:27: note: when computing vector element at index '0'4566// :133:27: note: when computing vector element at index '0'
4571// :133:27: error: use of undefined value here causes illegal behavior4567// :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'
4573// :133:27: error: use of undefined value here causes illegal behavior4569// :133:27: error: use of undefined value here causes illegal behavior
4574// :133:27: note: when computing vector element at index '0'4570// :133:27: note: when computing vector element at index '0'
4575// :133:27: error: use of undefined value here causes illegal behavior4571// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4577,6 +4573,7 @@ const std = @import("std");...@@ -4577,6 +4573,7 @@ const std = @import("std");
4577// :133:27: error: use of undefined value here causes illegal behavior4573// :133:27: error: use of undefined value here causes illegal behavior
4578// :133:27: note: when computing vector element at index '0'4574// :133:27: note: when computing vector element at index '0'
4579// :133:27: error: use of undefined value here causes illegal behavior4575// :133:27: error: use of undefined value here causes illegal behavior
4576// :133:27: note: when computing vector element at index '0'
4580// :133:27: error: use of undefined value here causes illegal behavior4577// :133:27: error: use of undefined value here causes illegal behavior
4581// :133:27: note: when computing vector element at index '0'4578// :133:27: note: when computing vector element at index '0'
4582// :133:27: error: use of undefined value here causes illegal behavior4579// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4584,7 +4581,7 @@ const std = @import("std");...@@ -4584,7 +4581,7 @@ const std = @import("std");
4584// :133:27: error: use of undefined value here causes illegal behavior4581// :133:27: error: use of undefined value here causes illegal behavior
4585// :133:27: note: when computing vector element at index '0'4582// :133:27: note: when computing vector element at index '0'
4586// :133:27: error: use of undefined value here causes illegal behavior4583// :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'
4588// :133:27: error: use of undefined value here causes illegal behavior4585// :133:27: error: use of undefined value here causes illegal behavior
4589// :133:27: note: when computing vector element at index '0'4586// :133:27: note: when computing vector element at index '0'
4590// :133:27: error: use of undefined value here causes illegal behavior4587// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4592,6 +4589,7 @@ const std = @import("std");...@@ -4592,6 +4589,7 @@ const std = @import("std");
4592// :133:27: error: use of undefined value here causes illegal behavior4589// :133:27: error: use of undefined value here causes illegal behavior
4593// :133:27: note: when computing vector element at index '0'4590// :133:27: note: when computing vector element at index '0'
4594// :133:27: error: use of undefined value here causes illegal behavior4591// :133:27: error: use of undefined value here causes illegal behavior
4592// :133:27: note: when computing vector element at index '0'
4595// :133:27: error: use of undefined value here causes illegal behavior4593// :133:27: error: use of undefined value here causes illegal behavior
4596// :133:27: note: when computing vector element at index '0'4594// :133:27: note: when computing vector element at index '0'
4597// :133:27: error: use of undefined value here causes illegal behavior4595// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4599,7 +4597,7 @@ const std = @import("std");...@@ -4599,7 +4597,7 @@ const std = @import("std");
4599// :133:27: error: use of undefined value here causes illegal behavior4597// :133:27: error: use of undefined value here causes illegal behavior
4600// :133:27: note: when computing vector element at index '0'4598// :133:27: note: when computing vector element at index '0'
4601// :133:27: error: use of undefined value here causes illegal behavior4599// :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'
4603// :133:27: error: use of undefined value here causes illegal behavior4601// :133:27: error: use of undefined value here causes illegal behavior
4604// :133:27: note: when computing vector element at index '0'4602// :133:27: note: when computing vector element at index '0'
4605// :133:27: error: use of undefined value here causes illegal behavior4603// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4607,6 +4605,7 @@ const std = @import("std");...@@ -4607,6 +4605,7 @@ const std = @import("std");
4607// :133:27: error: use of undefined value here causes illegal behavior4605// :133:27: error: use of undefined value here causes illegal behavior
4608// :133:27: note: when computing vector element at index '0'4606// :133:27: note: when computing vector element at index '0'
4609// :133:27: error: use of undefined value here causes illegal behavior4607// :133:27: error: use of undefined value here causes illegal behavior
4608// :133:27: note: when computing vector element at index '0'
4610// :133:27: error: use of undefined value here causes illegal behavior4609// :133:27: error: use of undefined value here causes illegal behavior
4611// :133:27: note: when computing vector element at index '0'4610// :133:27: note: when computing vector element at index '0'
4612// :133:27: error: use of undefined value here causes illegal behavior4611// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4614,7 +4613,7 @@ const std = @import("std");...@@ -4614,7 +4613,7 @@ const std = @import("std");
4614// :133:27: error: use of undefined value here causes illegal behavior4613// :133:27: error: use of undefined value here causes illegal behavior
4615// :133:27: note: when computing vector element at index '0'4614// :133:27: note: when computing vector element at index '0'
4616// :133:27: error: use of undefined value here causes illegal behavior4615// :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'
4618// :133:27: error: use of undefined value here causes illegal behavior4617// :133:27: error: use of undefined value here causes illegal behavior
4619// :133:27: note: when computing vector element at index '0'4618// :133:27: note: when computing vector element at index '0'
4620// :133:27: error: use of undefined value here causes illegal behavior4619// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4622,6 +4621,7 @@ const std = @import("std");...@@ -4622,6 +4621,7 @@ const std = @import("std");
4622// :133:27: error: use of undefined value here causes illegal behavior4621// :133:27: error: use of undefined value here causes illegal behavior
4623// :133:27: note: when computing vector element at index '0'4622// :133:27: note: when computing vector element at index '0'
4624// :133:27: error: use of undefined value here causes illegal behavior4623// :133:27: error: use of undefined value here causes illegal behavior
4624// :133:27: note: when computing vector element at index '0'
4625// :133:27: error: use of undefined value here causes illegal behavior4625// :133:27: error: use of undefined value here causes illegal behavior
4626// :133:27: note: when computing vector element at index '0'4626// :133:27: note: when computing vector element at index '0'
4627// :133:27: error: use of undefined value here causes illegal behavior4627// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4629,7 +4629,7 @@ const std = @import("std");...@@ -4629,7 +4629,7 @@ const std = @import("std");
4629// :133:27: error: use of undefined value here causes illegal behavior4629// :133:27: error: use of undefined value here causes illegal behavior
4630// :133:27: note: when computing vector element at index '0'4630// :133:27: note: when computing vector element at index '0'
4631// :133:27: error: use of undefined value here causes illegal behavior4631// :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'
4633// :133:27: error: use of undefined value here causes illegal behavior4633// :133:27: error: use of undefined value here causes illegal behavior
4634// :133:27: note: when computing vector element at index '0'4634// :133:27: note: when computing vector element at index '0'
4635// :133:27: error: use of undefined value here causes illegal behavior4635// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4637,6 +4637,7 @@ const std = @import("std");...@@ -4637,6 +4637,7 @@ const std = @import("std");
4637// :133:27: error: use of undefined value here causes illegal behavior4637// :133:27: error: use of undefined value here causes illegal behavior
4638// :133:27: note: when computing vector element at index '0'4638// :133:27: note: when computing vector element at index '0'
4639// :133:27: error: use of undefined value here causes illegal behavior4639// :133:27: error: use of undefined value here causes illegal behavior
4640// :133:27: note: when computing vector element at index '0'
4640// :133:27: error: use of undefined value here causes illegal behavior4641// :133:27: error: use of undefined value here causes illegal behavior
4641// :133:27: note: when computing vector element at index '0'4642// :133:27: note: when computing vector element at index '0'
4642// :133:27: error: use of undefined value here causes illegal behavior4643// :133:27: error: use of undefined value here causes illegal behavior
...@@ -4646,126 +4647,120 @@ const std = @import("std");...@@ -4646,126 +4647,120 @@ const std = @import("std");
4646// :133:27: error: use of undefined value here causes illegal behavior4647// :133:27: error: use of undefined value here causes illegal behavior
4647// :133:27: note: when computing vector element at index '1'4648// :133:27: note: when computing vector element at index '1'
4648// :133:27: error: use of undefined value here causes illegal behavior4649// :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: note: when computing vector element at index '1'
4650// :133:27: error: use of undefined value here causes illegal behavior
4651// :133:27: note: when computing vector element at index '0'
4652// :133:27: error: use of undefined value here causes illegal behavior4651// :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'
4654// :133:27: error: use of undefined value here causes illegal behavior4653// :133:27: error: use of undefined value here causes illegal behavior
4654// :133:27: note: when computing vector element at index '1'
4655// :133:27: error: use of undefined value here causes illegal behavior4655// :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'
4657// :133:27: error: use of undefined value here causes illegal behavior4657// :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'
4659// :133:27: error: use of undefined value here causes illegal behavior4659// :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'
4661// :133:27: error: use of undefined value here causes illegal behavior4661// :133:27: error: use of undefined value here causes illegal behavior
4662// :133:27: note: when computing vector element at index '1'4662// :133:27: note: when computing vector element at index '1'
4663// :133:27: error: use of undefined value here causes illegal behavior4663// :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'
4665// :133:27: error: use of undefined value here causes illegal behavior4665// :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'
4667// :133:27: error: use of undefined value here causes illegal behavior4667// :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'
4669// :133:30: error: use of undefined value here causes illegal behavior4669// :133:30: error: use of undefined value here causes illegal behavior
4670// :133:30: error: use of undefined value here causes illegal behavior4670// :133:30: error: use of undefined value here causes illegal behavior
4671// :133:30: note: when computing vector element at index '0'
4672// :133:30: error: use of undefined value here causes illegal behavior4671// :133:30: error: use of undefined value here causes illegal behavior
4673// :133:30: note: when computing vector element at index '0'
4674// :133:30: error: use of undefined value here causes illegal behavior4672// :133:30: error: use of undefined value here causes illegal behavior
4675// :133:30: note: when computing vector element at index '1'
4676// :133:30: error: use of undefined value here causes illegal behavior4673// :133:30: error: use of undefined value here causes illegal behavior
4677// :133:30: note: when computing vector element at index '0'
4678// :133:30: error: use of undefined value here causes illegal behavior4674// :133:30: error: use of undefined value here causes illegal behavior
4679// :133:30: note: when computing vector element at index '0'
4680// :133:30: error: use of undefined value here causes illegal behavior4675// :133:30: error: use of undefined value here causes illegal behavior
4681// :133:30: error: use of undefined value here causes illegal behavior4676// :133:30: error: use of undefined value here causes illegal behavior
4682// :133:30: note: when computing vector element at index '0'
4683// :133:30: error: use of undefined value here causes illegal behavior4677// :133:30: error: use of undefined value here causes illegal behavior
4684// :133:30: note: when computing vector element at index '0'
4685// :133:30: error: use of undefined value here causes illegal behavior4678// :133:30: error: use of undefined value here causes illegal behavior
4686// :133:30: note: when computing vector element at index '1'
4687// :133:30: error: use of undefined value here causes illegal behavior4679// :133:30: error: use of undefined value here causes illegal behavior
4688// :133:30: note: when computing vector element at index '0'
4689// :133:30: error: use of undefined value here causes illegal behavior4680// :133:30: error: use of undefined value here causes illegal behavior
4690// :133:30: note: when computing vector element at index '0'4681// :133:30: note: when computing vector element at index '0'
4691// :133:30: error: use of undefined value here causes illegal behavior4682// :133:30: error: use of undefined value here causes illegal behavior
4692// :133:30: error: use of undefined value here causes illegal behavior
4693// :133:30: note: when computing vector element at index '0'4683// :133:30: note: when computing vector element at index '0'
4694// :133:30: error: use of undefined value here causes illegal behavior4684// :133:30: error: use of undefined value here causes illegal behavior
4695// :133:30: note: when computing vector element at index '0'4685// :133:30: note: when computing vector element at index '0'
4696// :133:30: error: use of undefined value here causes illegal behavior4686// :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
4699// :133:30: note: when computing vector element at index '0'4687// :133:30: note: when computing vector element at index '0'
4700// :133:30: error: use of undefined value here causes illegal behavior4688// :133:30: error: use of undefined value here causes illegal behavior
4701// :133:30: note: when computing vector element at index '0'4689// :133:30: note: when computing vector element at index '0'
4702// :133:30: error: use of undefined value here causes illegal behavior4690// :133:30: error: use of undefined value here causes illegal behavior
4691// :133:30: note: when computing vector element at index '0'
4703// :133:30: error: use of undefined value here causes illegal behavior4692// :133:30: error: use of undefined value here causes illegal behavior
4704// :133:30: note: when computing vector element at index '0'4693// :133:30: note: when computing vector element at index '0'
4705// :133:30: error: use of undefined value here causes illegal behavior4694// :133:30: error: use of undefined value here causes illegal behavior
4706// :133:30: note: when computing vector element at index '0'4695// :133:30: note: when computing vector element at index '0'
4707// :133:30: error: use of undefined value here causes illegal behavior4696// :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'
4709// :133:30: error: use of undefined value here causes illegal behavior4698// :133:30: error: use of undefined value here causes illegal behavior
4710// :133:30: note: when computing vector element at index '0'4699// :133:30: note: when computing vector element at index '0'
4711// :133:30: error: use of undefined value here causes illegal behavior4700// :133:30: error: use of undefined value here causes illegal behavior
4712// :133:30: note: when computing vector element at index '0'4701// :133:30: note: when computing vector element at index '0'
4713// :133:30: error: use of undefined value here causes illegal behavior4702// :133:30: error: use of undefined value here causes illegal behavior
4703// :133:30: note: when computing vector element at index '0'
4714// :133:30: error: use of undefined value here causes illegal behavior4704// :133:30: error: use of undefined value here causes illegal behavior
4715// :133:30: note: when computing vector element at index '0'4705// :133:30: note: when computing vector element at index '0'
4716// :133:30: error: use of undefined value here causes illegal behavior4706// :133:30: error: use of undefined value here causes illegal behavior
4717// :133:30: note: when computing vector element at index '0'4707// :133:30: note: when computing vector element at index '0'
4718// :133:30: error: use of undefined value here causes illegal behavior4708// :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'
4720// :133:30: error: use of undefined value here causes illegal behavior4710// :133:30: error: use of undefined value here causes illegal behavior
4721// :133:30: note: when computing vector element at index '0'4711// :133:30: note: when computing vector element at index '0'
4722// :133:30: error: use of undefined value here causes illegal behavior4712// :133:30: error: use of undefined value here causes illegal behavior
4723// :133:30: note: when computing vector element at index '0'4713// :133:30: note: when computing vector element at index '0'
4724// :133:30: error: use of undefined value here causes illegal behavior4714// :133:30: error: use of undefined value here causes illegal behavior
4715// :133:30: note: when computing vector element at index '0'
4725// :133:30: error: use of undefined value here causes illegal behavior4716// :133:30: error: use of undefined value here causes illegal behavior
4726// :133:30: note: when computing vector element at index '0'4717// :133:30: note: when computing vector element at index '0'
4727// :133:30: error: use of undefined value here causes illegal behavior4718// :133:30: error: use of undefined value here causes illegal behavior
4728// :133:30: note: when computing vector element at index '0'4719// :133:30: note: when computing vector element at index '0'
4729// :133:30: error: use of undefined value here causes illegal behavior4720// :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'
4731// :133:30: error: use of undefined value here causes illegal behavior4722// :133:30: error: use of undefined value here causes illegal behavior
4732// :133:30: note: when computing vector element at index '0'4723// :133:30: note: when computing vector element at index '0'
4733// :133:30: error: use of undefined value here causes illegal behavior4724// :133:30: error: use of undefined value here causes illegal behavior
4734// :133:30: note: when computing vector element at index '0'4725// :133:30: note: when computing vector element at index '0'
4735// :133:30: error: use of undefined value here causes illegal behavior4726// :133:30: error: use of undefined value here causes illegal behavior
4727// :133:30: note: when computing vector element at index '0'
4736// :133:30: error: use of undefined value here causes illegal behavior4728// :133:30: error: use of undefined value here causes illegal behavior
4737// :133:30: note: when computing vector element at index '0'4729// :133:30: note: when computing vector element at index '0'
4738// :133:30: error: use of undefined value here causes illegal behavior4730// :133:30: error: use of undefined value here causes illegal behavior
4739// :133:30: note: when computing vector element at index '0'4731// :133:30: note: when computing vector element at index '0'
4740// :133:30: error: use of undefined value here causes illegal behavior4732// :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'
4742// :133:30: error: use of undefined value here causes illegal behavior4734// :133:30: error: use of undefined value here causes illegal behavior
4743// :133:30: note: when computing vector element at index '0'4735// :133:30: note: when computing vector element at index '0'
4744// :133:30: error: use of undefined value here causes illegal behavior4736// :133:30: error: use of undefined value here causes illegal behavior
4745// :133:30: note: when computing vector element at index '0'4737// :133:30: note: when computing vector element at index '0'
4746// :133:30: error: use of undefined value here causes illegal behavior4738// :133:30: error: use of undefined value here causes illegal behavior
4739// :133:30: note: when computing vector element at index '0'
4747// :133:30: error: use of undefined value here causes illegal behavior4740// :133:30: error: use of undefined value here causes illegal behavior
4748// :133:30: note: when computing vector element at index '0'4741// :133:30: note: when computing vector element at index '0'
4749// :133:30: error: use of undefined value here causes illegal behavior4742// :133:30: error: use of undefined value here causes illegal behavior
4750// :133:30: note: when computing vector element at index '0'4743// :133:30: note: when computing vector element at index '0'
4751// :133:30: error: use of undefined value here causes illegal behavior4744// :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'
4753// :133:30: error: use of undefined value here causes illegal behavior4746// :133:30: error: use of undefined value here causes illegal behavior
4754// :133:30: note: when computing vector element at index '0'4747// :133:30: note: when computing vector element at index '0'
4755// :133:30: error: use of undefined value here causes illegal behavior4748// :133:30: error: use of undefined value here causes illegal behavior
4756// :133:30: note: when computing vector element at index '0'4749// :133:30: note: when computing vector element at index '0'
4757// :133:30: error: use of undefined value here causes illegal behavior4750// :133:30: error: use of undefined value here causes illegal behavior
4751// :133:30: note: when computing vector element at index '0'
4758// :133:30: error: use of undefined value here causes illegal behavior4752// :133:30: error: use of undefined value here causes illegal behavior
4759// :133:30: note: when computing vector element at index '0'4753// :133:30: note: when computing vector element at index '0'
4760// :133:30: error: use of undefined value here causes illegal behavior4754// :133:30: error: use of undefined value here causes illegal behavior
4761// :133:30: note: when computing vector element at index '0'4755// :133:30: note: when computing vector element at index '0'
4762// :133:30: error: use of undefined value here causes illegal behavior4756// :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'
4764// :133:30: error: use of undefined value here causes illegal behavior4758// :133:30: error: use of undefined value here causes illegal behavior
4765// :133:30: note: when computing vector element at index '0'4759// :133:30: note: when computing vector element at index '0'
4766// :133:30: error: use of undefined value here causes illegal behavior4760// :133:30: error: use of undefined value here causes illegal behavior
4767// :133:30: note: when computing vector element at index '0'4761// :133:30: note: when computing vector element at index '0'
4768// :133:30: error: use of undefined value here causes illegal behavior4762// :133:30: error: use of undefined value here causes illegal behavior
4763// :133:30: note: when computing vector element at index '0'
4769// :133:30: error: use of undefined value here causes illegal behavior4764// :133:30: error: use of undefined value here causes illegal behavior
4770// :133:30: note: when computing vector element at index '0'4765// :133:30: note: when computing vector element at index '0'
4771// :133:30: error: use of undefined value here causes illegal behavior4766// :133:30: error: use of undefined value here causes illegal behavior
...@@ -4773,44 +4768,42 @@ const std = @import("std");...@@ -4773,44 +4768,42 @@ const std = @import("std");
4773// :133:30: error: use of undefined value here causes illegal behavior4768// :133:30: error: use of undefined value here causes illegal behavior
4774// :133:30: note: when computing vector element at index '1'4769// :133:30: note: when computing vector element at index '1'
4775// :133:30: error: use of undefined value here causes illegal behavior4770// :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'
4777// :133:30: error: use of undefined value here causes illegal behavior4772// :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'
4779// :133:30: error: use of undefined value here causes illegal behavior4774// :133:30: error: use of undefined value here causes illegal behavior
4775// :133:30: note: when computing vector element at index '1'
4780// :133:30: error: use of undefined value here causes illegal behavior4776// :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'
4782// :133:30: error: use of undefined value here causes illegal behavior4778// :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'
4784// :133:30: error: use of undefined value here causes illegal behavior4780// :133:30: error: use of undefined value here causes illegal behavior
4785// :133:30: note: when computing vector element at index '1'4781// :133:30: note: when computing vector element at index '1'
4786// :133:30: error: use of undefined value here causes illegal behavior4782// :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'
4788// :133:30: error: use of undefined value here causes illegal behavior4784// :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
4790// :137:17: error: use of undefined value here causes illegal behavior4791// :137:17: error: use of undefined value here causes illegal behavior
4791// :137:17: error: use of undefined value here causes illegal behavior4792// :137:17: error: use of undefined value here causes illegal behavior
4792// :137:17: note: when computing vector element at index '0'
4793// :137:17: error: use of undefined value here causes illegal behavior4793// :137:17: error: use of undefined value here causes illegal behavior
4794// :137:17: note: when computing vector element at index '0'
4795// :137:17: error: use of undefined value here causes illegal behavior4794// :137:17: error: use of undefined value here causes illegal behavior
4796// :137:17: note: when computing vector element at index '0'
4797// :137:17: error: use of undefined value here causes illegal behavior4795// :137:17: error: use of undefined value here causes illegal behavior
4798// :137:17: note: when computing vector element at index '1'
4799// :137:17: error: use of undefined value here causes illegal behavior4796// :137:17: error: use of undefined value here causes illegal behavior
4800// :137:17: note: when computing vector element at index '0'
4801// :137:17: error: use of undefined value here causes illegal behavior4797// :137:17: error: use of undefined value here causes illegal behavior
4802// :137:17: note: when computing vector element at index '0'
4803// :137:17: error: use of undefined value here causes illegal behavior4798// :137:17: error: use of undefined value here causes illegal behavior
4804// :137:17: note: when computing vector element at index '0'
4805// :137:17: error: use of undefined value here causes illegal behavior4799// :137:17: error: use of undefined value here causes illegal behavior
4806// :137:17: error: use of undefined value here causes illegal behavior4800// :137:17: error: use of undefined value here causes illegal behavior
4807// :137:17: note: when computing vector element at index '0'
4808// :137:17: error: use of undefined value here causes illegal behavior4801// :137:17: error: use of undefined value here causes illegal behavior
4809// :137:17: note: when computing vector element at index '0'4802// :137:17: note: when computing vector element at index '0'
4810// :137:17: error: use of undefined value here causes illegal behavior4803// :137:17: error: use of undefined value here causes illegal behavior
4811// :137:17: note: when computing vector element at index '0'4804// :137:17: note: when computing vector element at index '0'
4812// :137:17: error: use of undefined value here causes illegal behavior4805// :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'
4814// :137:17: error: use of undefined value here causes illegal behavior4807// :137:17: error: use of undefined value here causes illegal behavior
4815// :137:17: note: when computing vector element at index '0'4808// :137:17: note: when computing vector element at index '0'
4816// :137:17: error: use of undefined value here causes illegal behavior4809// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4818,6 +4811,7 @@ const std = @import("std");...@@ -4818,6 +4811,7 @@ const std = @import("std");
4818// :137:17: error: use of undefined value here causes illegal behavior4811// :137:17: error: use of undefined value here causes illegal behavior
4819// :137:17: note: when computing vector element at index '0'4812// :137:17: note: when computing vector element at index '0'
4820// :137:17: error: use of undefined value here causes illegal behavior4813// :137:17: error: use of undefined value here causes illegal behavior
4814// :137:17: note: when computing vector element at index '0'
4821// :137:17: error: use of undefined value here causes illegal behavior4815// :137:17: error: use of undefined value here causes illegal behavior
4822// :137:17: note: when computing vector element at index '0'4816// :137:17: note: when computing vector element at index '0'
4823// :137:17: error: use of undefined value here causes illegal behavior4817// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4825,7 +4819,7 @@ const std = @import("std");...@@ -4825,7 +4819,7 @@ const std = @import("std");
4825// :137:17: error: use of undefined value here causes illegal behavior4819// :137:17: error: use of undefined value here causes illegal behavior
4826// :137:17: note: when computing vector element at index '0'4820// :137:17: note: when computing vector element at index '0'
4827// :137:17: error: use of undefined value here causes illegal behavior4821// :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'
4829// :137:17: error: use of undefined value here causes illegal behavior4823// :137:17: error: use of undefined value here causes illegal behavior
4830// :137:17: note: when computing vector element at index '0'4824// :137:17: note: when computing vector element at index '0'
4831// :137:17: error: use of undefined value here causes illegal behavior4825// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4833,6 +4827,7 @@ const std = @import("std");...@@ -4833,6 +4827,7 @@ const std = @import("std");
4833// :137:17: error: use of undefined value here causes illegal behavior4827// :137:17: error: use of undefined value here causes illegal behavior
4834// :137:17: note: when computing vector element at index '0'4828// :137:17: note: when computing vector element at index '0'
4835// :137:17: error: use of undefined value here causes illegal behavior4829// :137:17: error: use of undefined value here causes illegal behavior
4830// :137:17: note: when computing vector element at index '0'
4836// :137:17: error: use of undefined value here causes illegal behavior4831// :137:17: error: use of undefined value here causes illegal behavior
4837// :137:17: note: when computing vector element at index '0'4832// :137:17: note: when computing vector element at index '0'
4838// :137:17: error: use of undefined value here causes illegal behavior4833// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4840,7 +4835,7 @@ const std = @import("std");...@@ -4840,7 +4835,7 @@ const std = @import("std");
4840// :137:17: error: use of undefined value here causes illegal behavior4835// :137:17: error: use of undefined value here causes illegal behavior
4841// :137:17: note: when computing vector element at index '0'4836// :137:17: note: when computing vector element at index '0'
4842// :137:17: error: use of undefined value here causes illegal behavior4837// :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'
4844// :137:17: error: use of undefined value here causes illegal behavior4839// :137:17: error: use of undefined value here causes illegal behavior
4845// :137:17: note: when computing vector element at index '0'4840// :137:17: note: when computing vector element at index '0'
4846// :137:17: error: use of undefined value here causes illegal behavior4841// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4848,6 +4843,7 @@ const std = @import("std");...@@ -4848,6 +4843,7 @@ const std = @import("std");
4848// :137:17: error: use of undefined value here causes illegal behavior4843// :137:17: error: use of undefined value here causes illegal behavior
4849// :137:17: note: when computing vector element at index '0'4844// :137:17: note: when computing vector element at index '0'
4850// :137:17: error: use of undefined value here causes illegal behavior4845// :137:17: error: use of undefined value here causes illegal behavior
4846// :137:17: note: when computing vector element at index '0'
4851// :137:17: error: use of undefined value here causes illegal behavior4847// :137:17: error: use of undefined value here causes illegal behavior
4852// :137:17: note: when computing vector element at index '0'4848// :137:17: note: when computing vector element at index '0'
4853// :137:17: error: use of undefined value here causes illegal behavior4849// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4855,7 +4851,7 @@ const std = @import("std");...@@ -4855,7 +4851,7 @@ const std = @import("std");
4855// :137:17: error: use of undefined value here causes illegal behavior4851// :137:17: error: use of undefined value here causes illegal behavior
4856// :137:17: note: when computing vector element at index '0'4852// :137:17: note: when computing vector element at index '0'
4857// :137:17: error: use of undefined value here causes illegal behavior4853// :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'
4859// :137:17: error: use of undefined value here causes illegal behavior4855// :137:17: error: use of undefined value here causes illegal behavior
4860// :137:17: note: when computing vector element at index '0'4856// :137:17: note: when computing vector element at index '0'
4861// :137:17: error: use of undefined value here causes illegal behavior4857// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4863,6 +4859,7 @@ const std = @import("std");...@@ -4863,6 +4859,7 @@ const std = @import("std");
4863// :137:17: error: use of undefined value here causes illegal behavior4859// :137:17: error: use of undefined value here causes illegal behavior
4864// :137:17: note: when computing vector element at index '0'4860// :137:17: note: when computing vector element at index '0'
4865// :137:17: error: use of undefined value here causes illegal behavior4861// :137:17: error: use of undefined value here causes illegal behavior
4862// :137:17: note: when computing vector element at index '0'
4866// :137:17: error: use of undefined value here causes illegal behavior4863// :137:17: error: use of undefined value here causes illegal behavior
4867// :137:17: note: when computing vector element at index '0'4864// :137:17: note: when computing vector element at index '0'
4868// :137:17: error: use of undefined value here causes illegal behavior4865// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4870,7 +4867,7 @@ const std = @import("std");...@@ -4870,7 +4867,7 @@ const std = @import("std");
4870// :137:17: error: use of undefined value here causes illegal behavior4867// :137:17: error: use of undefined value here causes illegal behavior
4871// :137:17: note: when computing vector element at index '0'4868// :137:17: note: when computing vector element at index '0'
4872// :137:17: error: use of undefined value here causes illegal behavior4869// :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'
4874// :137:17: error: use of undefined value here causes illegal behavior4871// :137:17: error: use of undefined value here causes illegal behavior
4875// :137:17: note: when computing vector element at index '0'4872// :137:17: note: when computing vector element at index '0'
4876// :137:17: error: use of undefined value here causes illegal behavior4873// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4878,6 +4875,7 @@ const std = @import("std");...@@ -4878,6 +4875,7 @@ const std = @import("std");
4878// :137:17: error: use of undefined value here causes illegal behavior4875// :137:17: error: use of undefined value here causes illegal behavior
4879// :137:17: note: when computing vector element at index '0'4876// :137:17: note: when computing vector element at index '0'
4880// :137:17: error: use of undefined value here causes illegal behavior4877// :137:17: error: use of undefined value here causes illegal behavior
4878// :137:17: note: when computing vector element at index '0'
4881// :137:17: error: use of undefined value here causes illegal behavior4879// :137:17: error: use of undefined value here causes illegal behavior
4882// :137:17: note: when computing vector element at index '0'4880// :137:17: note: when computing vector element at index '0'
4883// :137:17: error: use of undefined value here causes illegal behavior4881// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4885,7 +4883,7 @@ const std = @import("std");...@@ -4885,7 +4883,7 @@ const std = @import("std");
4885// :137:17: error: use of undefined value here causes illegal behavior4883// :137:17: error: use of undefined value here causes illegal behavior
4886// :137:17: note: when computing vector element at index '0'4884// :137:17: note: when computing vector element at index '0'
4887// :137:17: error: use of undefined value here causes illegal behavior4885// :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'
4889// :137:17: error: use of undefined value here causes illegal behavior4887// :137:17: error: use of undefined value here causes illegal behavior
4890// :137:17: note: when computing vector element at index '0'4888// :137:17: note: when computing vector element at index '0'
4891// :137:17: error: use of undefined value here causes illegal behavior4889// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4893,6 +4891,7 @@ const std = @import("std");...@@ -4893,6 +4891,7 @@ const std = @import("std");
4893// :137:17: error: use of undefined value here causes illegal behavior4891// :137:17: error: use of undefined value here causes illegal behavior
4894// :137:17: note: when computing vector element at index '0'4892// :137:17: note: when computing vector element at index '0'
4895// :137:17: error: use of undefined value here causes illegal behavior4893// :137:17: error: use of undefined value here causes illegal behavior
4894// :137:17: note: when computing vector element at index '0'
4896// :137:17: error: use of undefined value here causes illegal behavior4895// :137:17: error: use of undefined value here causes illegal behavior
4897// :137:17: note: when computing vector element at index '0'4896// :137:17: note: when computing vector element at index '0'
4898// :137:17: error: use of undefined value here causes illegal behavior4897// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4900,7 +4899,7 @@ const std = @import("std");...@@ -4900,7 +4899,7 @@ const std = @import("std");
4900// :137:17: error: use of undefined value here causes illegal behavior4899// :137:17: error: use of undefined value here causes illegal behavior
4901// :137:17: note: when computing vector element at index '0'4900// :137:17: note: when computing vector element at index '0'
4902// :137:17: error: use of undefined value here causes illegal behavior4901// :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'
4904// :137:17: error: use of undefined value here causes illegal behavior4903// :137:17: error: use of undefined value here causes illegal behavior
4905// :137:17: note: when computing vector element at index '0'4904// :137:17: note: when computing vector element at index '0'
4906// :137:17: error: use of undefined value here causes illegal behavior4905// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4908,6 +4907,7 @@ const std = @import("std");...@@ -4908,6 +4907,7 @@ const std = @import("std");
4908// :137:17: error: use of undefined value here causes illegal behavior4907// :137:17: error: use of undefined value here causes illegal behavior
4909// :137:17: note: when computing vector element at index '0'4908// :137:17: note: when computing vector element at index '0'
4910// :137:17: error: use of undefined value here causes illegal behavior4909// :137:17: error: use of undefined value here causes illegal behavior
4910// :137:17: note: when computing vector element at index '0'
4911// :137:17: error: use of undefined value here causes illegal behavior4911// :137:17: error: use of undefined value here causes illegal behavior
4912// :137:17: note: when computing vector element at index '0'4912// :137:17: note: when computing vector element at index '0'
4913// :137:17: error: use of undefined value here causes illegal behavior4913// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4915,7 +4915,7 @@ const std = @import("std");...@@ -4915,7 +4915,7 @@ const std = @import("std");
4915// :137:17: error: use of undefined value here causes illegal behavior4915// :137:17: error: use of undefined value here causes illegal behavior
4916// :137:17: note: when computing vector element at index '0'4916// :137:17: note: when computing vector element at index '0'
4917// :137:17: error: use of undefined value here causes illegal behavior4917// :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'
4919// :137:17: error: use of undefined value here causes illegal behavior4919// :137:17: error: use of undefined value here causes illegal behavior
4920// :137:17: note: when computing vector element at index '0'4920// :137:17: note: when computing vector element at index '0'
4921// :137:17: error: use of undefined value here causes illegal behavior4921// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4923,6 +4923,7 @@ const std = @import("std");...@@ -4923,6 +4923,7 @@ const std = @import("std");
4923// :137:17: error: use of undefined value here causes illegal behavior4923// :137:17: error: use of undefined value here causes illegal behavior
4924// :137:17: note: when computing vector element at index '0'4924// :137:17: note: when computing vector element at index '0'
4925// :137:17: error: use of undefined value here causes illegal behavior4925// :137:17: error: use of undefined value here causes illegal behavior
4926// :137:17: note: when computing vector element at index '0'
4926// :137:17: error: use of undefined value here causes illegal behavior4927// :137:17: error: use of undefined value here causes illegal behavior
4927// :137:17: note: when computing vector element at index '0'4928// :137:17: note: when computing vector element at index '0'
4928// :137:17: error: use of undefined value here causes illegal behavior4929// :137:17: error: use of undefined value here causes illegal behavior
...@@ -4932,126 +4933,120 @@ const std = @import("std");...@@ -4932,126 +4933,120 @@ const std = @import("std");
4932// :137:17: error: use of undefined value here causes illegal behavior4933// :137:17: error: use of undefined value here causes illegal behavior
4933// :137:17: note: when computing vector element at index '1'4934// :137:17: note: when computing vector element at index '1'
4934// :137:17: error: use of undefined value here causes illegal behavior4935// :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: note: when computing vector element at index '1'
4936// :137:17: error: use of undefined value here causes illegal behavior
4937// :137:17: note: when computing vector element at index '0'
4938// :137:17: error: use of undefined value here causes illegal behavior4937// :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'
4940// :137:17: error: use of undefined value here causes illegal behavior4939// :137:17: error: use of undefined value here causes illegal behavior
4940// :137:17: note: when computing vector element at index '1'
4941// :137:17: error: use of undefined value here causes illegal behavior4941// :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'
4943// :137:17: error: use of undefined value here causes illegal behavior4943// :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'
4945// :137:17: error: use of undefined value here causes illegal behavior4945// :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'
4947// :137:17: error: use of undefined value here causes illegal behavior4947// :137:17: error: use of undefined value here causes illegal behavior
4948// :137:17: note: when computing vector element at index '1'4948// :137:17: note: when computing vector element at index '1'
4949// :137:17: error: use of undefined value here causes illegal behavior4949// :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'
4951// :137:17: error: use of undefined value here causes illegal behavior4951// :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'
4953// :137:17: error: use of undefined value here causes illegal behavior4953// :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'
4955// :137:21: error: use of undefined value here causes illegal behavior4955// :137:21: error: use of undefined value here causes illegal behavior
4956// :137:21: error: use of undefined value here causes illegal behavior4956// :137:21: error: use of undefined value here causes illegal behavior
4957// :137:21: note: when computing vector element at index '0'
4958// :137:21: error: use of undefined value here causes illegal behavior4957// :137:21: error: use of undefined value here causes illegal behavior
4959// :137:21: note: when computing vector element at index '0'
4960// :137:21: error: use of undefined value here causes illegal behavior4958// :137:21: error: use of undefined value here causes illegal behavior
4961// :137:21: note: when computing vector element at index '1'
4962// :137:21: error: use of undefined value here causes illegal behavior4959// :137:21: error: use of undefined value here causes illegal behavior
4963// :137:21: note: when computing vector element at index '0'
4964// :137:21: error: use of undefined value here causes illegal behavior4960// :137:21: error: use of undefined value here causes illegal behavior
4965// :137:21: note: when computing vector element at index '0'
4966// :137:21: error: use of undefined value here causes illegal behavior4961// :137:21: error: use of undefined value here causes illegal behavior
4967// :137:21: error: use of undefined value here causes illegal behavior4962// :137:21: error: use of undefined value here causes illegal behavior
4968// :137:21: note: when computing vector element at index '0'
4969// :137:21: error: use of undefined value here causes illegal behavior4963// :137:21: error: use of undefined value here causes illegal behavior
4970// :137:21: note: when computing vector element at index '0'
4971// :137:21: error: use of undefined value here causes illegal behavior4964// :137:21: error: use of undefined value here causes illegal behavior
4972// :137:21: note: when computing vector element at index '1'
4973// :137:21: error: use of undefined value here causes illegal behavior4965// :137:21: error: use of undefined value here causes illegal behavior
4974// :137:21: note: when computing vector element at index '0'
4975// :137:21: error: use of undefined value here causes illegal behavior4966// :137:21: error: use of undefined value here causes illegal behavior
4976// :137:21: note: when computing vector element at index '0'4967// :137:21: note: when computing vector element at index '0'
4977// :137:21: error: use of undefined value here causes illegal behavior4968// :137:21: error: use of undefined value here causes illegal behavior
4978// :137:21: error: use of undefined value here causes illegal behavior
4979// :137:21: note: when computing vector element at index '0'4969// :137:21: note: when computing vector element at index '0'
4980// :137:21: error: use of undefined value here causes illegal behavior4970// :137:21: error: use of undefined value here causes illegal behavior
4981// :137:21: note: when computing vector element at index '0'4971// :137:21: note: when computing vector element at index '0'
4982// :137:21: error: use of undefined value here causes illegal behavior4972// :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
4985// :137:21: note: when computing vector element at index '0'4973// :137:21: note: when computing vector element at index '0'
4986// :137:21: error: use of undefined value here causes illegal behavior4974// :137:21: error: use of undefined value here causes illegal behavior
4987// :137:21: note: when computing vector element at index '0'4975// :137:21: note: when computing vector element at index '0'
4988// :137:21: error: use of undefined value here causes illegal behavior4976// :137:21: error: use of undefined value here causes illegal behavior
4977// :137:21: note: when computing vector element at index '0'
4989// :137:21: error: use of undefined value here causes illegal behavior4978// :137:21: error: use of undefined value here causes illegal behavior
4990// :137:21: note: when computing vector element at index '0'4979// :137:21: note: when computing vector element at index '0'
4991// :137:21: error: use of undefined value here causes illegal behavior4980// :137:21: error: use of undefined value here causes illegal behavior
4992// :137:21: note: when computing vector element at index '0'4981// :137:21: note: when computing vector element at index '0'
4993// :137:21: error: use of undefined value here causes illegal behavior4982// :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'
4995// :137:21: error: use of undefined value here causes illegal behavior4984// :137:21: error: use of undefined value here causes illegal behavior
4996// :137:21: note: when computing vector element at index '0'4985// :137:21: note: when computing vector element at index '0'
4997// :137:21: error: use of undefined value here causes illegal behavior4986// :137:21: error: use of undefined value here causes illegal behavior
4998// :137:21: note: when computing vector element at index '0'4987// :137:21: note: when computing vector element at index '0'
4999// :137:21: error: use of undefined value here causes illegal behavior4988// :137:21: error: use of undefined value here causes illegal behavior
4989// :137:21: note: when computing vector element at index '0'
5000// :137:21: error: use of undefined value here causes illegal behavior4990// :137:21: error: use of undefined value here causes illegal behavior
5001// :137:21: note: when computing vector element at index '0'4991// :137:21: note: when computing vector element at index '0'
5002// :137:21: error: use of undefined value here causes illegal behavior4992// :137:21: error: use of undefined value here causes illegal behavior
5003// :137:21: note: when computing vector element at index '0'4993// :137:21: note: when computing vector element at index '0'
5004// :137:21: error: use of undefined value here causes illegal behavior4994// :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'
5006// :137:21: error: use of undefined value here causes illegal behavior4996// :137:21: error: use of undefined value here causes illegal behavior
5007// :137:21: note: when computing vector element at index '0'4997// :137:21: note: when computing vector element at index '0'
5008// :137:21: error: use of undefined value here causes illegal behavior4998// :137:21: error: use of undefined value here causes illegal behavior
5009// :137:21: note: when computing vector element at index '0'4999// :137:21: note: when computing vector element at index '0'
5010// :137:21: error: use of undefined value here causes illegal behavior5000// :137:21: error: use of undefined value here causes illegal behavior
5001// :137:21: note: when computing vector element at index '0'
5011// :137:21: error: use of undefined value here causes illegal behavior5002// :137:21: error: use of undefined value here causes illegal behavior
5012// :137:21: note: when computing vector element at index '0'5003// :137:21: note: when computing vector element at index '0'
5013// :137:21: error: use of undefined value here causes illegal behavior5004// :137:21: error: use of undefined value here causes illegal behavior
5014// :137:21: note: when computing vector element at index '0'5005// :137:21: note: when computing vector element at index '0'
5015// :137:21: error: use of undefined value here causes illegal behavior5006// :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'
5017// :137:21: error: use of undefined value here causes illegal behavior5008// :137:21: error: use of undefined value here causes illegal behavior
5018// :137:21: note: when computing vector element at index '0'5009// :137:21: note: when computing vector element at index '0'
5019// :137:21: error: use of undefined value here causes illegal behavior5010// :137:21: error: use of undefined value here causes illegal behavior
5020// :137:21: note: when computing vector element at index '0'5011// :137:21: note: when computing vector element at index '0'
5021// :137:21: error: use of undefined value here causes illegal behavior5012// :137:21: error: use of undefined value here causes illegal behavior
5013// :137:21: note: when computing vector element at index '0'
5022// :137:21: error: use of undefined value here causes illegal behavior5014// :137:21: error: use of undefined value here causes illegal behavior
5023// :137:21: note: when computing vector element at index '0'5015// :137:21: note: when computing vector element at index '0'
5024// :137:21: error: use of undefined value here causes illegal behavior5016// :137:21: error: use of undefined value here causes illegal behavior
5025// :137:21: note: when computing vector element at index '0'5017// :137:21: note: when computing vector element at index '0'
5026// :137:21: error: use of undefined value here causes illegal behavior5018// :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'
5028// :137:21: error: use of undefined value here causes illegal behavior5020// :137:21: error: use of undefined value here causes illegal behavior
5029// :137:21: note: when computing vector element at index '0'5021// :137:21: note: when computing vector element at index '0'
5030// :137:21: error: use of undefined value here causes illegal behavior5022// :137:21: error: use of undefined value here causes illegal behavior
5031// :137:21: note: when computing vector element at index '0'5023// :137:21: note: when computing vector element at index '0'
5032// :137:21: error: use of undefined value here causes illegal behavior5024// :137:21: error: use of undefined value here causes illegal behavior
5025// :137:21: note: when computing vector element at index '0'
5033// :137:21: error: use of undefined value here causes illegal behavior5026// :137:21: error: use of undefined value here causes illegal behavior
5034// :137:21: note: when computing vector element at index '0'5027// :137:21: note: when computing vector element at index '0'
5035// :137:21: error: use of undefined value here causes illegal behavior5028// :137:21: error: use of undefined value here causes illegal behavior
5036// :137:21: note: when computing vector element at index '0'5029// :137:21: note: when computing vector element at index '0'
5037// :137:21: error: use of undefined value here causes illegal behavior5030// :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'
5039// :137:21: error: use of undefined value here causes illegal behavior5032// :137:21: error: use of undefined value here causes illegal behavior
5040// :137:21: note: when computing vector element at index '0'5033// :137:21: note: when computing vector element at index '0'
5041// :137:21: error: use of undefined value here causes illegal behavior5034// :137:21: error: use of undefined value here causes illegal behavior
5042// :137:21: note: when computing vector element at index '0'5035// :137:21: note: when computing vector element at index '0'
5043// :137:21: error: use of undefined value here causes illegal behavior5036// :137:21: error: use of undefined value here causes illegal behavior
5037// :137:21: note: when computing vector element at index '0'
5044// :137:21: error: use of undefined value here causes illegal behavior5038// :137:21: error: use of undefined value here causes illegal behavior
5045// :137:21: note: when computing vector element at index '0'5039// :137:21: note: when computing vector element at index '0'
5046// :137:21: error: use of undefined value here causes illegal behavior5040// :137:21: error: use of undefined value here causes illegal behavior
5047// :137:21: note: when computing vector element at index '0'5041// :137:21: note: when computing vector element at index '0'
5048// :137:21: error: use of undefined value here causes illegal behavior5042// :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'
5050// :137:21: error: use of undefined value here causes illegal behavior5044// :137:21: error: use of undefined value here causes illegal behavior
5051// :137:21: note: when computing vector element at index '0'5045// :137:21: note: when computing vector element at index '0'
5052// :137:21: error: use of undefined value here causes illegal behavior5046// :137:21: error: use of undefined value here causes illegal behavior
5053// :137:21: note: when computing vector element at index '0'5047// :137:21: note: when computing vector element at index '0'
5054// :137:21: error: use of undefined value here causes illegal behavior5048// :137:21: error: use of undefined value here causes illegal behavior
5049// :137:21: note: when computing vector element at index '0'
5055// :137:21: error: use of undefined value here causes illegal behavior5050// :137:21: error: use of undefined value here causes illegal behavior
5056// :137:21: note: when computing vector element at index '0'5051// :137:21: note: when computing vector element at index '0'
5057// :137:21: error: use of undefined value here causes illegal behavior5052// :137:21: error: use of undefined value here causes illegal behavior
...@@ -5059,44 +5054,42 @@ const std = @import("std");...@@ -5059,44 +5054,42 @@ const std = @import("std");
5059// :137:21: error: use of undefined value here causes illegal behavior5054// :137:21: error: use of undefined value here causes illegal behavior
5060// :137:21: note: when computing vector element at index '1'5055// :137:21: note: when computing vector element at index '1'
5061// :137:21: error: use of undefined value here causes illegal behavior5056// :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'
5063// :137:21: error: use of undefined value here causes illegal behavior5058// :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'
5065// :137:21: error: use of undefined value here causes illegal behavior5060// :137:21: error: use of undefined value here causes illegal behavior
5061// :137:21: note: when computing vector element at index '1'
5066// :137:21: error: use of undefined value here causes illegal behavior5062// :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'
5068// :137:21: error: use of undefined value here causes illegal behavior5064// :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'
5070// :137:21: error: use of undefined value here causes illegal behavior5066// :137:21: error: use of undefined value here causes illegal behavior
5071// :137:21: note: when computing vector element at index '1'5067// :137:21: note: when computing vector element at index '1'
5072// :137:21: error: use of undefined value here causes illegal behavior5068// :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'
5074// :137:21: error: use of undefined value here causes illegal behavior5070// :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
5076// :141:22: error: use of undefined value here causes illegal behavior5077// :141:22: error: use of undefined value here causes illegal behavior
5077// :141:22: error: use of undefined value here causes illegal behavior5078// :141:22: error: use of undefined value here causes illegal behavior
5078// :141:22: note: when computing vector element at index '0'
5079// :141:22: error: use of undefined value here causes illegal behavior5079// :141:22: error: use of undefined value here causes illegal behavior
5080// :141:22: note: when computing vector element at index '0'
5081// :141:22: error: use of undefined value here causes illegal behavior5080// :141:22: error: use of undefined value here causes illegal behavior
5082// :141:22: note: when computing vector element at index '0'
5083// :141:22: error: use of undefined value here causes illegal behavior5081// :141:22: error: use of undefined value here causes illegal behavior
5084// :141:22: note: when computing vector element at index '1'
5085// :141:22: error: use of undefined value here causes illegal behavior5082// :141:22: error: use of undefined value here causes illegal behavior
5086// :141:22: note: when computing vector element at index '0'
5087// :141:22: error: use of undefined value here causes illegal behavior5083// :141:22: error: use of undefined value here causes illegal behavior
5088// :141:22: note: when computing vector element at index '0'
5089// :141:22: error: use of undefined value here causes illegal behavior5084// :141:22: error: use of undefined value here causes illegal behavior
5090// :141:22: note: when computing vector element at index '0'
5091// :141:22: error: use of undefined value here causes illegal behavior5085// :141:22: error: use of undefined value here causes illegal behavior
5092// :141:22: error: use of undefined value here causes illegal behavior5086// :141:22: error: use of undefined value here causes illegal behavior
5093// :141:22: note: when computing vector element at index '0'
5094// :141:22: error: use of undefined value here causes illegal behavior5087// :141:22: error: use of undefined value here causes illegal behavior
5095// :141:22: note: when computing vector element at index '0'5088// :141:22: note: when computing vector element at index '0'
5096// :141:22: error: use of undefined value here causes illegal behavior5089// :141:22: error: use of undefined value here causes illegal behavior
5097// :141:22: note: when computing vector element at index '0'5090// :141:22: note: when computing vector element at index '0'
5098// :141:22: error: use of undefined value here causes illegal behavior5091// :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'
5100// :141:22: error: use of undefined value here causes illegal behavior5093// :141:22: error: use of undefined value here causes illegal behavior
5101// :141:22: note: when computing vector element at index '0'5094// :141:22: note: when computing vector element at index '0'
5102// :141:22: error: use of undefined value here causes illegal behavior5095// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5104,6 +5097,7 @@ const std = @import("std");...@@ -5104,6 +5097,7 @@ const std = @import("std");
5104// :141:22: error: use of undefined value here causes illegal behavior5097// :141:22: error: use of undefined value here causes illegal behavior
5105// :141:22: note: when computing vector element at index '0'5098// :141:22: note: when computing vector element at index '0'
5106// :141:22: error: use of undefined value here causes illegal behavior5099// :141:22: error: use of undefined value here causes illegal behavior
5100// :141:22: note: when computing vector element at index '0'
5107// :141:22: error: use of undefined value here causes illegal behavior5101// :141:22: error: use of undefined value here causes illegal behavior
5108// :141:22: note: when computing vector element at index '0'5102// :141:22: note: when computing vector element at index '0'
5109// :141:22: error: use of undefined value here causes illegal behavior5103// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5111,7 +5105,7 @@ const std = @import("std");...@@ -5111,7 +5105,7 @@ const std = @import("std");
5111// :141:22: error: use of undefined value here causes illegal behavior5105// :141:22: error: use of undefined value here causes illegal behavior
5112// :141:22: note: when computing vector element at index '0'5106// :141:22: note: when computing vector element at index '0'
5113// :141:22: error: use of undefined value here causes illegal behavior5107// :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'
5115// :141:22: error: use of undefined value here causes illegal behavior5109// :141:22: error: use of undefined value here causes illegal behavior
5116// :141:22: note: when computing vector element at index '0'5110// :141:22: note: when computing vector element at index '0'
5117// :141:22: error: use of undefined value here causes illegal behavior5111// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5119,6 +5113,7 @@ const std = @import("std");...@@ -5119,6 +5113,7 @@ const std = @import("std");
5119// :141:22: error: use of undefined value here causes illegal behavior5113// :141:22: error: use of undefined value here causes illegal behavior
5120// :141:22: note: when computing vector element at index '0'5114// :141:22: note: when computing vector element at index '0'
5121// :141:22: error: use of undefined value here causes illegal behavior5115// :141:22: error: use of undefined value here causes illegal behavior
5116// :141:22: note: when computing vector element at index '0'
5122// :141:22: error: use of undefined value here causes illegal behavior5117// :141:22: error: use of undefined value here causes illegal behavior
5123// :141:22: note: when computing vector element at index '0'5118// :141:22: note: when computing vector element at index '0'
5124// :141:22: error: use of undefined value here causes illegal behavior5119// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5126,7 +5121,7 @@ const std = @import("std");...@@ -5126,7 +5121,7 @@ const std = @import("std");
5126// :141:22: error: use of undefined value here causes illegal behavior5121// :141:22: error: use of undefined value here causes illegal behavior
5127// :141:22: note: when computing vector element at index '0'5122// :141:22: note: when computing vector element at index '0'
5128// :141:22: error: use of undefined value here causes illegal behavior5123// :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'
5130// :141:22: error: use of undefined value here causes illegal behavior5125// :141:22: error: use of undefined value here causes illegal behavior
5131// :141:22: note: when computing vector element at index '0'5126// :141:22: note: when computing vector element at index '0'
5132// :141:22: error: use of undefined value here causes illegal behavior5127// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5134,6 +5129,7 @@ const std = @import("std");...@@ -5134,6 +5129,7 @@ const std = @import("std");
5134// :141:22: error: use of undefined value here causes illegal behavior5129// :141:22: error: use of undefined value here causes illegal behavior
5135// :141:22: note: when computing vector element at index '0'5130// :141:22: note: when computing vector element at index '0'
5136// :141:22: error: use of undefined value here causes illegal behavior5131// :141:22: error: use of undefined value here causes illegal behavior
5132// :141:22: note: when computing vector element at index '0'
5137// :141:22: error: use of undefined value here causes illegal behavior5133// :141:22: error: use of undefined value here causes illegal behavior
5138// :141:22: note: when computing vector element at index '0'5134// :141:22: note: when computing vector element at index '0'
5139// :141:22: error: use of undefined value here causes illegal behavior5135// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5141,7 +5137,7 @@ const std = @import("std");...@@ -5141,7 +5137,7 @@ const std = @import("std");
5141// :141:22: error: use of undefined value here causes illegal behavior5137// :141:22: error: use of undefined value here causes illegal behavior
5142// :141:22: note: when computing vector element at index '0'5138// :141:22: note: when computing vector element at index '0'
5143// :141:22: error: use of undefined value here causes illegal behavior5139// :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'
5145// :141:22: error: use of undefined value here causes illegal behavior5141// :141:22: error: use of undefined value here causes illegal behavior
5146// :141:22: note: when computing vector element at index '0'5142// :141:22: note: when computing vector element at index '0'
5147// :141:22: error: use of undefined value here causes illegal behavior5143// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5149,6 +5145,7 @@ const std = @import("std");...@@ -5149,6 +5145,7 @@ const std = @import("std");
5149// :141:22: error: use of undefined value here causes illegal behavior5145// :141:22: error: use of undefined value here causes illegal behavior
5150// :141:22: note: when computing vector element at index '0'5146// :141:22: note: when computing vector element at index '0'
5151// :141:22: error: use of undefined value here causes illegal behavior5147// :141:22: error: use of undefined value here causes illegal behavior
5148// :141:22: note: when computing vector element at index '0'
5152// :141:22: error: use of undefined value here causes illegal behavior5149// :141:22: error: use of undefined value here causes illegal behavior
5153// :141:22: note: when computing vector element at index '0'5150// :141:22: note: when computing vector element at index '0'
5154// :141:22: error: use of undefined value here causes illegal behavior5151// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5156,7 +5153,7 @@ const std = @import("std");...@@ -5156,7 +5153,7 @@ const std = @import("std");
5156// :141:22: error: use of undefined value here causes illegal behavior5153// :141:22: error: use of undefined value here causes illegal behavior
5157// :141:22: note: when computing vector element at index '0'5154// :141:22: note: when computing vector element at index '0'
5158// :141:22: error: use of undefined value here causes illegal behavior5155// :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'
5160// :141:22: error: use of undefined value here causes illegal behavior5157// :141:22: error: use of undefined value here causes illegal behavior
5161// :141:22: note: when computing vector element at index '0'5158// :141:22: note: when computing vector element at index '0'
5162// :141:22: error: use of undefined value here causes illegal behavior5159// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5164,6 +5161,7 @@ const std = @import("std");...@@ -5164,6 +5161,7 @@ const std = @import("std");
5164// :141:22: error: use of undefined value here causes illegal behavior5161// :141:22: error: use of undefined value here causes illegal behavior
5165// :141:22: note: when computing vector element at index '0'5162// :141:22: note: when computing vector element at index '0'
5166// :141:22: error: use of undefined value here causes illegal behavior5163// :141:22: error: use of undefined value here causes illegal behavior
5164// :141:22: note: when computing vector element at index '0'
5167// :141:22: error: use of undefined value here causes illegal behavior5165// :141:22: error: use of undefined value here causes illegal behavior
5168// :141:22: note: when computing vector element at index '0'5166// :141:22: note: when computing vector element at index '0'
5169// :141:22: error: use of undefined value here causes illegal behavior5167// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5171,7 +5169,7 @@ const std = @import("std");...@@ -5171,7 +5169,7 @@ const std = @import("std");
5171// :141:22: error: use of undefined value here causes illegal behavior5169// :141:22: error: use of undefined value here causes illegal behavior
5172// :141:22: note: when computing vector element at index '0'5170// :141:22: note: when computing vector element at index '0'
5173// :141:22: error: use of undefined value here causes illegal behavior5171// :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'
5175// :141:22: error: use of undefined value here causes illegal behavior5173// :141:22: error: use of undefined value here causes illegal behavior
5176// :141:22: note: when computing vector element at index '0'5174// :141:22: note: when computing vector element at index '0'
5177// :141:22: error: use of undefined value here causes illegal behavior5175// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5179,6 +5177,7 @@ const std = @import("std");...@@ -5179,6 +5177,7 @@ const std = @import("std");
5179// :141:22: error: use of undefined value here causes illegal behavior5177// :141:22: error: use of undefined value here causes illegal behavior
5180// :141:22: note: when computing vector element at index '0'5178// :141:22: note: when computing vector element at index '0'
5181// :141:22: error: use of undefined value here causes illegal behavior5179// :141:22: error: use of undefined value here causes illegal behavior
5180// :141:22: note: when computing vector element at index '0'
5182// :141:22: error: use of undefined value here causes illegal behavior5181// :141:22: error: use of undefined value here causes illegal behavior
5183// :141:22: note: when computing vector element at index '0'5182// :141:22: note: when computing vector element at index '0'
5184// :141:22: error: use of undefined value here causes illegal behavior5183// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5186,7 +5185,7 @@ const std = @import("std");...@@ -5186,7 +5185,7 @@ const std = @import("std");
5186// :141:22: error: use of undefined value here causes illegal behavior5185// :141:22: error: use of undefined value here causes illegal behavior
5187// :141:22: note: when computing vector element at index '0'5186// :141:22: note: when computing vector element at index '0'
5188// :141:22: error: use of undefined value here causes illegal behavior5187// :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'
5190// :141:22: error: use of undefined value here causes illegal behavior5189// :141:22: error: use of undefined value here causes illegal behavior
5191// :141:22: note: when computing vector element at index '0'5190// :141:22: note: when computing vector element at index '0'
5192// :141:22: error: use of undefined value here causes illegal behavior5191// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5194,6 +5193,7 @@ const std = @import("std");...@@ -5194,6 +5193,7 @@ const std = @import("std");
5194// :141:22: error: use of undefined value here causes illegal behavior5193// :141:22: error: use of undefined value here causes illegal behavior
5195// :141:22: note: when computing vector element at index '0'5194// :141:22: note: when computing vector element at index '0'
5196// :141:22: error: use of undefined value here causes illegal behavior5195// :141:22: error: use of undefined value here causes illegal behavior
5196// :141:22: note: when computing vector element at index '0'
5197// :141:22: error: use of undefined value here causes illegal behavior5197// :141:22: error: use of undefined value here causes illegal behavior
5198// :141:22: note: when computing vector element at index '0'5198// :141:22: note: when computing vector element at index '0'
5199// :141:22: error: use of undefined value here causes illegal behavior5199// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5201,7 +5201,7 @@ const std = @import("std");...@@ -5201,7 +5201,7 @@ const std = @import("std");
5201// :141:22: error: use of undefined value here causes illegal behavior5201// :141:22: error: use of undefined value here causes illegal behavior
5202// :141:22: note: when computing vector element at index '0'5202// :141:22: note: when computing vector element at index '0'
5203// :141:22: error: use of undefined value here causes illegal behavior5203// :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'
5205// :141:22: error: use of undefined value here causes illegal behavior5205// :141:22: error: use of undefined value here causes illegal behavior
5206// :141:22: note: when computing vector element at index '0'5206// :141:22: note: when computing vector element at index '0'
5207// :141:22: error: use of undefined value here causes illegal behavior5207// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5209,6 +5209,7 @@ const std = @import("std");...@@ -5209,6 +5209,7 @@ const std = @import("std");
5209// :141:22: error: use of undefined value here causes illegal behavior5209// :141:22: error: use of undefined value here causes illegal behavior
5210// :141:22: note: when computing vector element at index '0'5210// :141:22: note: when computing vector element at index '0'
5211// :141:22: error: use of undefined value here causes illegal behavior5211// :141:22: error: use of undefined value here causes illegal behavior
5212// :141:22: note: when computing vector element at index '0'
5212// :141:22: error: use of undefined value here causes illegal behavior5213// :141:22: error: use of undefined value here causes illegal behavior
5213// :141:22: note: when computing vector element at index '0'5214// :141:22: note: when computing vector element at index '0'
5214// :141:22: error: use of undefined value here causes illegal behavior5215// :141:22: error: use of undefined value here causes illegal behavior
...@@ -5218,126 +5219,120 @@ const std = @import("std");...@@ -5218,126 +5219,120 @@ const std = @import("std");
5218// :141:22: error: use of undefined value here causes illegal behavior5219// :141:22: error: use of undefined value here causes illegal behavior
5219// :141:22: note: when computing vector element at index '1'5220// :141:22: note: when computing vector element at index '1'
5220// :141:22: error: use of undefined value here causes illegal behavior5221// :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: note: when computing vector element at index '1'
5222// :141:22: error: use of undefined value here causes illegal behavior
5223// :141:22: note: when computing vector element at index '0'
5224// :141:22: error: use of undefined value here causes illegal behavior5223// :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'
5226// :141:22: error: use of undefined value here causes illegal behavior5225// :141:22: error: use of undefined value here causes illegal behavior
5226// :141:22: note: when computing vector element at index '1'
5227// :141:22: error: use of undefined value here causes illegal behavior5227// :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'
5229// :141:22: error: use of undefined value here causes illegal behavior5229// :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'
5231// :141:22: error: use of undefined value here causes illegal behavior5231// :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'
5233// :141:22: error: use of undefined value here causes illegal behavior5233// :141:22: error: use of undefined value here causes illegal behavior
5234// :141:22: note: when computing vector element at index '1'5234// :141:22: note: when computing vector element at index '1'
5235// :141:22: error: use of undefined value here causes illegal behavior5235// :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'
5237// :141:22: error: use of undefined value here causes illegal behavior5237// :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'
5239// :141:22: error: use of undefined value here causes illegal behavior5239// :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'
5241// :141:25: error: use of undefined value here causes illegal behavior5241// :141:25: error: use of undefined value here causes illegal behavior
5242// :141:25: error: use of undefined value here causes illegal behavior5242// :141:25: error: use of undefined value here causes illegal behavior
5243// :141:25: note: when computing vector element at index '0'
5244// :141:25: error: use of undefined value here causes illegal behavior5243// :141:25: error: use of undefined value here causes illegal behavior
5245// :141:25: note: when computing vector element at index '0'
5246// :141:25: error: use of undefined value here causes illegal behavior5244// :141:25: error: use of undefined value here causes illegal behavior
5247// :141:25: note: when computing vector element at index '1'
5248// :141:25: error: use of undefined value here causes illegal behavior5245// :141:25: error: use of undefined value here causes illegal behavior
5249// :141:25: note: when computing vector element at index '0'
5250// :141:25: error: use of undefined value here causes illegal behavior5246// :141:25: error: use of undefined value here causes illegal behavior
5251// :141:25: note: when computing vector element at index '0'
5252// :141:25: error: use of undefined value here causes illegal behavior5247// :141:25: error: use of undefined value here causes illegal behavior
5253// :141:25: error: use of undefined value here causes illegal behavior5248// :141:25: error: use of undefined value here causes illegal behavior
5254// :141:25: note: when computing vector element at index '0'
5255// :141:25: error: use of undefined value here causes illegal behavior5249// :141:25: error: use of undefined value here causes illegal behavior
5256// :141:25: note: when computing vector element at index '0'
5257// :141:25: error: use of undefined value here causes illegal behavior5250// :141:25: error: use of undefined value here causes illegal behavior
5258// :141:25: note: when computing vector element at index '1'
5259// :141:25: error: use of undefined value here causes illegal behavior5251// :141:25: error: use of undefined value here causes illegal behavior
5260// :141:25: note: when computing vector element at index '0'
5261// :141:25: error: use of undefined value here causes illegal behavior5252// :141:25: error: use of undefined value here causes illegal behavior
5262// :141:25: note: when computing vector element at index '0'5253// :141:25: note: when computing vector element at index '0'
5263// :141:25: error: use of undefined value here causes illegal behavior5254// :141:25: error: use of undefined value here causes illegal behavior
5264// :141:25: error: use of undefined value here causes illegal behavior
5265// :141:25: note: when computing vector element at index '0'5255// :141:25: note: when computing vector element at index '0'
5266// :141:25: error: use of undefined value here causes illegal behavior5256// :141:25: error: use of undefined value here causes illegal behavior
5267// :141:25: note: when computing vector element at index '0'5257// :141:25: note: when computing vector element at index '0'
5268// :141:25: error: use of undefined value here causes illegal behavior5258// :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
5271// :141:25: note: when computing vector element at index '0'5259// :141:25: note: when computing vector element at index '0'
5272// :141:25: error: use of undefined value here causes illegal behavior5260// :141:25: error: use of undefined value here causes illegal behavior
5273// :141:25: note: when computing vector element at index '0'5261// :141:25: note: when computing vector element at index '0'
5274// :141:25: error: use of undefined value here causes illegal behavior5262// :141:25: error: use of undefined value here causes illegal behavior
5263// :141:25: note: when computing vector element at index '0'
5275// :141:25: error: use of undefined value here causes illegal behavior5264// :141:25: error: use of undefined value here causes illegal behavior
5276// :141:25: note: when computing vector element at index '0'5265// :141:25: note: when computing vector element at index '0'
5277// :141:25: error: use of undefined value here causes illegal behavior5266// :141:25: error: use of undefined value here causes illegal behavior
5278// :141:25: note: when computing vector element at index '0'5267// :141:25: note: when computing vector element at index '0'
5279// :141:25: error: use of undefined value here causes illegal behavior5268// :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'
5281// :141:25: error: use of undefined value here causes illegal behavior5270// :141:25: error: use of undefined value here causes illegal behavior
5282// :141:25: note: when computing vector element at index '0'5271// :141:25: note: when computing vector element at index '0'
5283// :141:25: error: use of undefined value here causes illegal behavior5272// :141:25: error: use of undefined value here causes illegal behavior
5284// :141:25: note: when computing vector element at index '0'5273// :141:25: note: when computing vector element at index '0'
5285// :141:25: error: use of undefined value here causes illegal behavior5274// :141:25: error: use of undefined value here causes illegal behavior
5275// :141:25: note: when computing vector element at index '0'
5286// :141:25: error: use of undefined value here causes illegal behavior5276// :141:25: error: use of undefined value here causes illegal behavior
5287// :141:25: note: when computing vector element at index '0'5277// :141:25: note: when computing vector element at index '0'
5288// :141:25: error: use of undefined value here causes illegal behavior5278// :141:25: error: use of undefined value here causes illegal behavior
5289// :141:25: note: when computing vector element at index '0'5279// :141:25: note: when computing vector element at index '0'
5290// :141:25: error: use of undefined value here causes illegal behavior5280// :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'
5292// :141:25: error: use of undefined value here causes illegal behavior5282// :141:25: error: use of undefined value here causes illegal behavior
5293// :141:25: note: when computing vector element at index '0'5283// :141:25: note: when computing vector element at index '0'
5294// :141:25: error: use of undefined value here causes illegal behavior5284// :141:25: error: use of undefined value here causes illegal behavior
5295// :141:25: note: when computing vector element at index '0'5285// :141:25: note: when computing vector element at index '0'
5296// :141:25: error: use of undefined value here causes illegal behavior5286// :141:25: error: use of undefined value here causes illegal behavior
5287// :141:25: note: when computing vector element at index '0'
5297// :141:25: error: use of undefined value here causes illegal behavior5288// :141:25: error: use of undefined value here causes illegal behavior
5298// :141:25: note: when computing vector element at index '0'5289// :141:25: note: when computing vector element at index '0'
5299// :141:25: error: use of undefined value here causes illegal behavior5290// :141:25: error: use of undefined value here causes illegal behavior
5300// :141:25: note: when computing vector element at index '0'5291// :141:25: note: when computing vector element at index '0'
5301// :141:25: error: use of undefined value here causes illegal behavior5292// :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'
5303// :141:25: error: use of undefined value here causes illegal behavior5294// :141:25: error: use of undefined value here causes illegal behavior
5304// :141:25: note: when computing vector element at index '0'5295// :141:25: note: when computing vector element at index '0'
5305// :141:25: error: use of undefined value here causes illegal behavior5296// :141:25: error: use of undefined value here causes illegal behavior
5306// :141:25: note: when computing vector element at index '0'5297// :141:25: note: when computing vector element at index '0'
5307// :141:25: error: use of undefined value here causes illegal behavior5298// :141:25: error: use of undefined value here causes illegal behavior
5299// :141:25: note: when computing vector element at index '0'
5308// :141:25: error: use of undefined value here causes illegal behavior5300// :141:25: error: use of undefined value here causes illegal behavior
5309// :141:25: note: when computing vector element at index '0'5301// :141:25: note: when computing vector element at index '0'
5310// :141:25: error: use of undefined value here causes illegal behavior5302// :141:25: error: use of undefined value here causes illegal behavior
5311// :141:25: note: when computing vector element at index '0'5303// :141:25: note: when computing vector element at index '0'
5312// :141:25: error: use of undefined value here causes illegal behavior5304// :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'
5314// :141:25: error: use of undefined value here causes illegal behavior5306// :141:25: error: use of undefined value here causes illegal behavior
5315// :141:25: note: when computing vector element at index '0'5307// :141:25: note: when computing vector element at index '0'
5316// :141:25: error: use of undefined value here causes illegal behavior5308// :141:25: error: use of undefined value here causes illegal behavior
5317// :141:25: note: when computing vector element at index '0'5309// :141:25: note: when computing vector element at index '0'
5318// :141:25: error: use of undefined value here causes illegal behavior5310// :141:25: error: use of undefined value here causes illegal behavior
5311// :141:25: note: when computing vector element at index '0'
5319// :141:25: error: use of undefined value here causes illegal behavior5312// :141:25: error: use of undefined value here causes illegal behavior
5320// :141:25: note: when computing vector element at index '0'5313// :141:25: note: when computing vector element at index '0'
5321// :141:25: error: use of undefined value here causes illegal behavior5314// :141:25: error: use of undefined value here causes illegal behavior
5322// :141:25: note: when computing vector element at index '0'5315// :141:25: note: when computing vector element at index '0'
5323// :141:25: error: use of undefined value here causes illegal behavior5316// :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'
5325// :141:25: error: use of undefined value here causes illegal behavior5318// :141:25: error: use of undefined value here causes illegal behavior
5326// :141:25: note: when computing vector element at index '0'5319// :141:25: note: when computing vector element at index '0'
5327// :141:25: error: use of undefined value here causes illegal behavior5320// :141:25: error: use of undefined value here causes illegal behavior
5328// :141:25: note: when computing vector element at index '0'5321// :141:25: note: when computing vector element at index '0'
5329// :141:25: error: use of undefined value here causes illegal behavior5322// :141:25: error: use of undefined value here causes illegal behavior
5323// :141:25: note: when computing vector element at index '0'
5330// :141:25: error: use of undefined value here causes illegal behavior5324// :141:25: error: use of undefined value here causes illegal behavior
5331// :141:25: note: when computing vector element at index '0'5325// :141:25: note: when computing vector element at index '0'
5332// :141:25: error: use of undefined value here causes illegal behavior5326// :141:25: error: use of undefined value here causes illegal behavior
5333// :141:25: note: when computing vector element at index '0'5327// :141:25: note: when computing vector element at index '0'
5334// :141:25: error: use of undefined value here causes illegal behavior5328// :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'
5336// :141:25: error: use of undefined value here causes illegal behavior5330// :141:25: error: use of undefined value here causes illegal behavior
5337// :141:25: note: when computing vector element at index '0'5331// :141:25: note: when computing vector element at index '0'
5338// :141:25: error: use of undefined value here causes illegal behavior5332// :141:25: error: use of undefined value here causes illegal behavior
5339// :141:25: note: when computing vector element at index '0'5333// :141:25: note: when computing vector element at index '0'
5340// :141:25: error: use of undefined value here causes illegal behavior5334// :141:25: error: use of undefined value here causes illegal behavior
5335// :141:25: note: when computing vector element at index '0'
5341// :141:25: error: use of undefined value here causes illegal behavior5336// :141:25: error: use of undefined value here causes illegal behavior
5342// :141:25: note: when computing vector element at index '0'5337// :141:25: note: when computing vector element at index '0'
5343// :141:25: error: use of undefined value here causes illegal behavior5338// :141:25: error: use of undefined value here causes illegal behavior
...@@ -5345,44 +5340,42 @@ const std = @import("std");...@@ -5345,44 +5340,42 @@ const std = @import("std");
5345// :141:25: error: use of undefined value here causes illegal behavior5340// :141:25: error: use of undefined value here causes illegal behavior
5346// :141:25: note: when computing vector element at index '1'5341// :141:25: note: when computing vector element at index '1'
5347// :141:25: error: use of undefined value here causes illegal behavior5342// :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'
5349// :141:25: error: use of undefined value here causes illegal behavior5344// :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'
5351// :141:25: error: use of undefined value here causes illegal behavior5346// :141:25: error: use of undefined value here causes illegal behavior
5347// :141:25: note: when computing vector element at index '1'
5352// :141:25: error: use of undefined value here causes illegal behavior5348// :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'
5354// :141:25: error: use of undefined value here causes illegal behavior5350// :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'
5356// :141:25: error: use of undefined value here causes illegal behavior5352// :141:25: error: use of undefined value here causes illegal behavior
5357// :141:25: note: when computing vector element at index '1'5353// :141:25: note: when computing vector element at index '1'
5358// :141:25: error: use of undefined value here causes illegal behavior5354// :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'
5360// :141:25: error: use of undefined value here causes illegal behavior5356// :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
5362// :145:22: error: use of undefined value here causes illegal behavior5363// :145:22: error: use of undefined value here causes illegal behavior
5363// :145:22: error: use of undefined value here causes illegal behavior5364// :145:22: error: use of undefined value here causes illegal behavior
5364// :145:22: note: when computing vector element at index '0'
5365// :145:22: error: use of undefined value here causes illegal behavior5365// :145:22: error: use of undefined value here causes illegal behavior
5366// :145:22: note: when computing vector element at index '0'
5367// :145:22: error: use of undefined value here causes illegal behavior5366// :145:22: error: use of undefined value here causes illegal behavior
5368// :145:22: note: when computing vector element at index '0'
5369// :145:22: error: use of undefined value here causes illegal behavior5367// :145:22: error: use of undefined value here causes illegal behavior
5370// :145:22: note: when computing vector element at index '1'
5371// :145:22: error: use of undefined value here causes illegal behavior5368// :145:22: error: use of undefined value here causes illegal behavior
5372// :145:22: note: when computing vector element at index '0'
5373// :145:22: error: use of undefined value here causes illegal behavior5369// :145:22: error: use of undefined value here causes illegal behavior
5374// :145:22: note: when computing vector element at index '0'
5375// :145:22: error: use of undefined value here causes illegal behavior5370// :145:22: error: use of undefined value here causes illegal behavior
5376// :145:22: note: when computing vector element at index '0'
5377// :145:22: error: use of undefined value here causes illegal behavior5371// :145:22: error: use of undefined value here causes illegal behavior
5378// :145:22: error: use of undefined value here causes illegal behavior5372// :145:22: error: use of undefined value here causes illegal behavior
5379// :145:22: note: when computing vector element at index '0'
5380// :145:22: error: use of undefined value here causes illegal behavior5373// :145:22: error: use of undefined value here causes illegal behavior
5381// :145:22: note: when computing vector element at index '0'5374// :145:22: note: when computing vector element at index '0'
5382// :145:22: error: use of undefined value here causes illegal behavior5375// :145:22: error: use of undefined value here causes illegal behavior
5383// :145:22: note: when computing vector element at index '0'5376// :145:22: note: when computing vector element at index '0'
5384// :145:22: error: use of undefined value here causes illegal behavior5377// :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'
5386// :145:22: error: use of undefined value here causes illegal behavior5379// :145:22: error: use of undefined value here causes illegal behavior
5387// :145:22: note: when computing vector element at index '0'5380// :145:22: note: when computing vector element at index '0'
5388// :145:22: error: use of undefined value here causes illegal behavior5381// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5390,6 +5383,7 @@ const std = @import("std");...@@ -5390,6 +5383,7 @@ const std = @import("std");
5390// :145:22: error: use of undefined value here causes illegal behavior5383// :145:22: error: use of undefined value here causes illegal behavior
5391// :145:22: note: when computing vector element at index '0'5384// :145:22: note: when computing vector element at index '0'
5392// :145:22: error: use of undefined value here causes illegal behavior5385// :145:22: error: use of undefined value here causes illegal behavior
5386// :145:22: note: when computing vector element at index '0'
5393// :145:22: error: use of undefined value here causes illegal behavior5387// :145:22: error: use of undefined value here causes illegal behavior
5394// :145:22: note: when computing vector element at index '0'5388// :145:22: note: when computing vector element at index '0'
5395// :145:22: error: use of undefined value here causes illegal behavior5389// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5397,7 +5391,7 @@ const std = @import("std");...@@ -5397,7 +5391,7 @@ const std = @import("std");
5397// :145:22: error: use of undefined value here causes illegal behavior5391// :145:22: error: use of undefined value here causes illegal behavior
5398// :145:22: note: when computing vector element at index '0'5392// :145:22: note: when computing vector element at index '0'
5399// :145:22: error: use of undefined value here causes illegal behavior5393// :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'
5401// :145:22: error: use of undefined value here causes illegal behavior5395// :145:22: error: use of undefined value here causes illegal behavior
5402// :145:22: note: when computing vector element at index '0'5396// :145:22: note: when computing vector element at index '0'
5403// :145:22: error: use of undefined value here causes illegal behavior5397// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5405,6 +5399,7 @@ const std = @import("std");...@@ -5405,6 +5399,7 @@ const std = @import("std");
5405// :145:22: error: use of undefined value here causes illegal behavior5399// :145:22: error: use of undefined value here causes illegal behavior
5406// :145:22: note: when computing vector element at index '0'5400// :145:22: note: when computing vector element at index '0'
5407// :145:22: error: use of undefined value here causes illegal behavior5401// :145:22: error: use of undefined value here causes illegal behavior
5402// :145:22: note: when computing vector element at index '0'
5408// :145:22: error: use of undefined value here causes illegal behavior5403// :145:22: error: use of undefined value here causes illegal behavior
5409// :145:22: note: when computing vector element at index '0'5404// :145:22: note: when computing vector element at index '0'
5410// :145:22: error: use of undefined value here causes illegal behavior5405// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5412,7 +5407,7 @@ const std = @import("std");...@@ -5412,7 +5407,7 @@ const std = @import("std");
5412// :145:22: error: use of undefined value here causes illegal behavior5407// :145:22: error: use of undefined value here causes illegal behavior
5413// :145:22: note: when computing vector element at index '0'5408// :145:22: note: when computing vector element at index '0'
5414// :145:22: error: use of undefined value here causes illegal behavior5409// :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'
5416// :145:22: error: use of undefined value here causes illegal behavior5411// :145:22: error: use of undefined value here causes illegal behavior
5417// :145:22: note: when computing vector element at index '0'5412// :145:22: note: when computing vector element at index '0'
5418// :145:22: error: use of undefined value here causes illegal behavior5413// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5420,6 +5415,7 @@ const std = @import("std");...@@ -5420,6 +5415,7 @@ const std = @import("std");
5420// :145:22: error: use of undefined value here causes illegal behavior5415// :145:22: error: use of undefined value here causes illegal behavior
5421// :145:22: note: when computing vector element at index '0'5416// :145:22: note: when computing vector element at index '0'
5422// :145:22: error: use of undefined value here causes illegal behavior5417// :145:22: error: use of undefined value here causes illegal behavior
5418// :145:22: note: when computing vector element at index '0'
5423// :145:22: error: use of undefined value here causes illegal behavior5419// :145:22: error: use of undefined value here causes illegal behavior
5424// :145:22: note: when computing vector element at index '0'5420// :145:22: note: when computing vector element at index '0'
5425// :145:22: error: use of undefined value here causes illegal behavior5421// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5427,7 +5423,7 @@ const std = @import("std");...@@ -5427,7 +5423,7 @@ const std = @import("std");
5427// :145:22: error: use of undefined value here causes illegal behavior5423// :145:22: error: use of undefined value here causes illegal behavior
5428// :145:22: note: when computing vector element at index '0'5424// :145:22: note: when computing vector element at index '0'
5429// :145:22: error: use of undefined value here causes illegal behavior5425// :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'
5431// :145:22: error: use of undefined value here causes illegal behavior5427// :145:22: error: use of undefined value here causes illegal behavior
5432// :145:22: note: when computing vector element at index '0'5428// :145:22: note: when computing vector element at index '0'
5433// :145:22: error: use of undefined value here causes illegal behavior5429// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5435,6 +5431,7 @@ const std = @import("std");...@@ -5435,6 +5431,7 @@ const std = @import("std");
5435// :145:22: error: use of undefined value here causes illegal behavior5431// :145:22: error: use of undefined value here causes illegal behavior
5436// :145:22: note: when computing vector element at index '0'5432// :145:22: note: when computing vector element at index '0'
5437// :145:22: error: use of undefined value here causes illegal behavior5433// :145:22: error: use of undefined value here causes illegal behavior
5434// :145:22: note: when computing vector element at index '0'
5438// :145:22: error: use of undefined value here causes illegal behavior5435// :145:22: error: use of undefined value here causes illegal behavior
5439// :145:22: note: when computing vector element at index '0'5436// :145:22: note: when computing vector element at index '0'
5440// :145:22: error: use of undefined value here causes illegal behavior5437// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5442,7 +5439,7 @@ const std = @import("std");...@@ -5442,7 +5439,7 @@ const std = @import("std");
5442// :145:22: error: use of undefined value here causes illegal behavior5439// :145:22: error: use of undefined value here causes illegal behavior
5443// :145:22: note: when computing vector element at index '0'5440// :145:22: note: when computing vector element at index '0'
5444// :145:22: error: use of undefined value here causes illegal behavior5441// :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'
5446// :145:22: error: use of undefined value here causes illegal behavior5443// :145:22: error: use of undefined value here causes illegal behavior
5447// :145:22: note: when computing vector element at index '0'5444// :145:22: note: when computing vector element at index '0'
5448// :145:22: error: use of undefined value here causes illegal behavior5445// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5450,6 +5447,7 @@ const std = @import("std");...@@ -5450,6 +5447,7 @@ const std = @import("std");
5450// :145:22: error: use of undefined value here causes illegal behavior5447// :145:22: error: use of undefined value here causes illegal behavior
5451// :145:22: note: when computing vector element at index '0'5448// :145:22: note: when computing vector element at index '0'
5452// :145:22: error: use of undefined value here causes illegal behavior5449// :145:22: error: use of undefined value here causes illegal behavior
5450// :145:22: note: when computing vector element at index '0'
5453// :145:22: error: use of undefined value here causes illegal behavior5451// :145:22: error: use of undefined value here causes illegal behavior
5454// :145:22: note: when computing vector element at index '0'5452// :145:22: note: when computing vector element at index '0'
5455// :145:22: error: use of undefined value here causes illegal behavior5453// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5457,7 +5455,7 @@ const std = @import("std");...@@ -5457,7 +5455,7 @@ const std = @import("std");
5457// :145:22: error: use of undefined value here causes illegal behavior5455// :145:22: error: use of undefined value here causes illegal behavior
5458// :145:22: note: when computing vector element at index '0'5456// :145:22: note: when computing vector element at index '0'
5459// :145:22: error: use of undefined value here causes illegal behavior5457// :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'
5461// :145:22: error: use of undefined value here causes illegal behavior5459// :145:22: error: use of undefined value here causes illegal behavior
5462// :145:22: note: when computing vector element at index '0'5460// :145:22: note: when computing vector element at index '0'
5463// :145:22: error: use of undefined value here causes illegal behavior5461// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5465,6 +5463,7 @@ const std = @import("std");...@@ -5465,6 +5463,7 @@ const std = @import("std");
5465// :145:22: error: use of undefined value here causes illegal behavior5463// :145:22: error: use of undefined value here causes illegal behavior
5466// :145:22: note: when computing vector element at index '0'5464// :145:22: note: when computing vector element at index '0'
5467// :145:22: error: use of undefined value here causes illegal behavior5465// :145:22: error: use of undefined value here causes illegal behavior
5466// :145:22: note: when computing vector element at index '0'
5468// :145:22: error: use of undefined value here causes illegal behavior5467// :145:22: error: use of undefined value here causes illegal behavior
5469// :145:22: note: when computing vector element at index '0'5468// :145:22: note: when computing vector element at index '0'
5470// :145:22: error: use of undefined value here causes illegal behavior5469// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5472,7 +5471,7 @@ const std = @import("std");...@@ -5472,7 +5471,7 @@ const std = @import("std");
5472// :145:22: error: use of undefined value here causes illegal behavior5471// :145:22: error: use of undefined value here causes illegal behavior
5473// :145:22: note: when computing vector element at index '0'5472// :145:22: note: when computing vector element at index '0'
5474// :145:22: error: use of undefined value here causes illegal behavior5473// :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'
5476// :145:22: error: use of undefined value here causes illegal behavior5475// :145:22: error: use of undefined value here causes illegal behavior
5477// :145:22: note: when computing vector element at index '0'5476// :145:22: note: when computing vector element at index '0'
5478// :145:22: error: use of undefined value here causes illegal behavior5477// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5480,6 +5479,7 @@ const std = @import("std");...@@ -5480,6 +5479,7 @@ const std = @import("std");
5480// :145:22: error: use of undefined value here causes illegal behavior5479// :145:22: error: use of undefined value here causes illegal behavior
5481// :145:22: note: when computing vector element at index '0'5480// :145:22: note: when computing vector element at index '0'
5482// :145:22: error: use of undefined value here causes illegal behavior5481// :145:22: error: use of undefined value here causes illegal behavior
5482// :145:22: note: when computing vector element at index '0'
5483// :145:22: error: use of undefined value here causes illegal behavior5483// :145:22: error: use of undefined value here causes illegal behavior
5484// :145:22: note: when computing vector element at index '0'5484// :145:22: note: when computing vector element at index '0'
5485// :145:22: error: use of undefined value here causes illegal behavior5485// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5487,7 +5487,7 @@ const std = @import("std");...@@ -5487,7 +5487,7 @@ const std = @import("std");
5487// :145:22: error: use of undefined value here causes illegal behavior5487// :145:22: error: use of undefined value here causes illegal behavior
5488// :145:22: note: when computing vector element at index '0'5488// :145:22: note: when computing vector element at index '0'
5489// :145:22: error: use of undefined value here causes illegal behavior5489// :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'
5491// :145:22: error: use of undefined value here causes illegal behavior5491// :145:22: error: use of undefined value here causes illegal behavior
5492// :145:22: note: when computing vector element at index '0'5492// :145:22: note: when computing vector element at index '0'
5493// :145:22: error: use of undefined value here causes illegal behavior5493// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5495,6 +5495,7 @@ const std = @import("std");...@@ -5495,6 +5495,7 @@ const std = @import("std");
5495// :145:22: error: use of undefined value here causes illegal behavior5495// :145:22: error: use of undefined value here causes illegal behavior
5496// :145:22: note: when computing vector element at index '0'5496// :145:22: note: when computing vector element at index '0'
5497// :145:22: error: use of undefined value here causes illegal behavior5497// :145:22: error: use of undefined value here causes illegal behavior
5498// :145:22: note: when computing vector element at index '0'
5498// :145:22: error: use of undefined value here causes illegal behavior5499// :145:22: error: use of undefined value here causes illegal behavior
5499// :145:22: note: when computing vector element at index '0'5500// :145:22: note: when computing vector element at index '0'
5500// :145:22: error: use of undefined value here causes illegal behavior5501// :145:22: error: use of undefined value here causes illegal behavior
...@@ -5504,126 +5505,120 @@ const std = @import("std");...@@ -5504,126 +5505,120 @@ const std = @import("std");
5504// :145:22: error: use of undefined value here causes illegal behavior5505// :145:22: error: use of undefined value here causes illegal behavior
5505// :145:22: note: when computing vector element at index '1'5506// :145:22: note: when computing vector element at index '1'
5506// :145:22: error: use of undefined value here causes illegal behavior5507// :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: note: when computing vector element at index '1'
5508// :145:22: error: use of undefined value here causes illegal behavior
5509// :145:22: note: when computing vector element at index '0'
5510// :145:22: error: use of undefined value here causes illegal behavior5509// :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'
5512// :145:22: error: use of undefined value here causes illegal behavior5511// :145:22: error: use of undefined value here causes illegal behavior
5512// :145:22: note: when computing vector element at index '1'
5513// :145:22: error: use of undefined value here causes illegal behavior5513// :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'
5515// :145:22: error: use of undefined value here causes illegal behavior5515// :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'
5517// :145:22: error: use of undefined value here causes illegal behavior5517// :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'
5519// :145:22: error: use of undefined value here causes illegal behavior5519// :145:22: error: use of undefined value here causes illegal behavior
5520// :145:22: note: when computing vector element at index '1'5520// :145:22: note: when computing vector element at index '1'
5521// :145:22: error: use of undefined value here causes illegal behavior5521// :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'
5523// :145:22: error: use of undefined value here causes illegal behavior5523// :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'
5525// :145:22: error: use of undefined value here causes illegal behavior5525// :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'
5527// :145:25: error: use of undefined value here causes illegal behavior5527// :145:25: error: use of undefined value here causes illegal behavior
5528// :145:25: error: use of undefined value here causes illegal behavior5528// :145:25: error: use of undefined value here causes illegal behavior
5529// :145:25: note: when computing vector element at index '0'
5530// :145:25: error: use of undefined value here causes illegal behavior5529// :145:25: error: use of undefined value here causes illegal behavior
5531// :145:25: note: when computing vector element at index '0'
5532// :145:25: error: use of undefined value here causes illegal behavior5530// :145:25: error: use of undefined value here causes illegal behavior
5533// :145:25: note: when computing vector element at index '1'
5534// :145:25: error: use of undefined value here causes illegal behavior5531// :145:25: error: use of undefined value here causes illegal behavior
5535// :145:25: note: when computing vector element at index '0'
5536// :145:25: error: use of undefined value here causes illegal behavior5532// :145:25: error: use of undefined value here causes illegal behavior
5537// :145:25: note: when computing vector element at index '0'
5538// :145:25: error: use of undefined value here causes illegal behavior5533// :145:25: error: use of undefined value here causes illegal behavior
5539// :145:25: error: use of undefined value here causes illegal behavior5534// :145:25: error: use of undefined value here causes illegal behavior
5540// :145:25: note: when computing vector element at index '0'
5541// :145:25: error: use of undefined value here causes illegal behavior5535// :145:25: error: use of undefined value here causes illegal behavior
5542// :145:25: note: when computing vector element at index '0'
5543// :145:25: error: use of undefined value here causes illegal behavior5536// :145:25: error: use of undefined value here causes illegal behavior
5544// :145:25: note: when computing vector element at index '1'
5545// :145:25: error: use of undefined value here causes illegal behavior5537// :145:25: error: use of undefined value here causes illegal behavior
5546// :145:25: note: when computing vector element at index '0'
5547// :145:25: error: use of undefined value here causes illegal behavior5538// :145:25: error: use of undefined value here causes illegal behavior
5548// :145:25: note: when computing vector element at index '0'5539// :145:25: note: when computing vector element at index '0'
5549// :145:25: error: use of undefined value here causes illegal behavior5540// :145:25: error: use of undefined value here causes illegal behavior
5550// :145:25: error: use of undefined value here causes illegal behavior
5551// :145:25: note: when computing vector element at index '0'5541// :145:25: note: when computing vector element at index '0'
5552// :145:25: error: use of undefined value here causes illegal behavior5542// :145:25: error: use of undefined value here causes illegal behavior
5553// :145:25: note: when computing vector element at index '0'5543// :145:25: note: when computing vector element at index '0'
5554// :145:25: error: use of undefined value here causes illegal behavior5544// :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
5557// :145:25: note: when computing vector element at index '0'5545// :145:25: note: when computing vector element at index '0'
5558// :145:25: error: use of undefined value here causes illegal behavior5546// :145:25: error: use of undefined value here causes illegal behavior
5559// :145:25: note: when computing vector element at index '0'5547// :145:25: note: when computing vector element at index '0'
5560// :145:25: error: use of undefined value here causes illegal behavior5548// :145:25: error: use of undefined value here causes illegal behavior
5549// :145:25: note: when computing vector element at index '0'
5561// :145:25: error: use of undefined value here causes illegal behavior5550// :145:25: error: use of undefined value here causes illegal behavior
5562// :145:25: note: when computing vector element at index '0'5551// :145:25: note: when computing vector element at index '0'
5563// :145:25: error: use of undefined value here causes illegal behavior5552// :145:25: error: use of undefined value here causes illegal behavior
5564// :145:25: note: when computing vector element at index '0'5553// :145:25: note: when computing vector element at index '0'
5565// :145:25: error: use of undefined value here causes illegal behavior5554// :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'
5567// :145:25: error: use of undefined value here causes illegal behavior5556// :145:25: error: use of undefined value here causes illegal behavior
5568// :145:25: note: when computing vector element at index '0'5557// :145:25: note: when computing vector element at index '0'
5569// :145:25: error: use of undefined value here causes illegal behavior5558// :145:25: error: use of undefined value here causes illegal behavior
5570// :145:25: note: when computing vector element at index '0'5559// :145:25: note: when computing vector element at index '0'
5571// :145:25: error: use of undefined value here causes illegal behavior5560// :145:25: error: use of undefined value here causes illegal behavior
5561// :145:25: note: when computing vector element at index '0'
5572// :145:25: error: use of undefined value here causes illegal behavior5562// :145:25: error: use of undefined value here causes illegal behavior
5573// :145:25: note: when computing vector element at index '0'5563// :145:25: note: when computing vector element at index '0'
5574// :145:25: error: use of undefined value here causes illegal behavior5564// :145:25: error: use of undefined value here causes illegal behavior
5575// :145:25: note: when computing vector element at index '0'5565// :145:25: note: when computing vector element at index '0'
5576// :145:25: error: use of undefined value here causes illegal behavior5566// :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'
5578// :145:25: error: use of undefined value here causes illegal behavior5568// :145:25: error: use of undefined value here causes illegal behavior
5579// :145:25: note: when computing vector element at index '0'5569// :145:25: note: when computing vector element at index '0'
5580// :145:25: error: use of undefined value here causes illegal behavior5570// :145:25: error: use of undefined value here causes illegal behavior
5581// :145:25: note: when computing vector element at index '0'5571// :145:25: note: when computing vector element at index '0'
5582// :145:25: error: use of undefined value here causes illegal behavior5572// :145:25: error: use of undefined value here causes illegal behavior
5573// :145:25: note: when computing vector element at index '0'
5583// :145:25: error: use of undefined value here causes illegal behavior5574// :145:25: error: use of undefined value here causes illegal behavior
5584// :145:25: note: when computing vector element at index '0'5575// :145:25: note: when computing vector element at index '0'
5585// :145:25: error: use of undefined value here causes illegal behavior5576// :145:25: error: use of undefined value here causes illegal behavior
5586// :145:25: note: when computing vector element at index '0'5577// :145:25: note: when computing vector element at index '0'
5587// :145:25: error: use of undefined value here causes illegal behavior5578// :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'
5589// :145:25: error: use of undefined value here causes illegal behavior5580// :145:25: error: use of undefined value here causes illegal behavior
5590// :145:25: note: when computing vector element at index '0'5581// :145:25: note: when computing vector element at index '0'
5591// :145:25: error: use of undefined value here causes illegal behavior5582// :145:25: error: use of undefined value here causes illegal behavior
5592// :145:25: note: when computing vector element at index '0'5583// :145:25: note: when computing vector element at index '0'
5593// :145:25: error: use of undefined value here causes illegal behavior5584// :145:25: error: use of undefined value here causes illegal behavior
5585// :145:25: note: when computing vector element at index '0'
5594// :145:25: error: use of undefined value here causes illegal behavior5586// :145:25: error: use of undefined value here causes illegal behavior
5595// :145:25: note: when computing vector element at index '0'5587// :145:25: note: when computing vector element at index '0'
5596// :145:25: error: use of undefined value here causes illegal behavior5588// :145:25: error: use of undefined value here causes illegal behavior
5597// :145:25: note: when computing vector element at index '0'5589// :145:25: note: when computing vector element at index '0'
5598// :145:25: error: use of undefined value here causes illegal behavior5590// :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'
5600// :145:25: error: use of undefined value here causes illegal behavior5592// :145:25: error: use of undefined value here causes illegal behavior
5601// :145:25: note: when computing vector element at index '0'5593// :145:25: note: when computing vector element at index '0'
5602// :145:25: error: use of undefined value here causes illegal behavior5594// :145:25: error: use of undefined value here causes illegal behavior
5603// :145:25: note: when computing vector element at index '0'5595// :145:25: note: when computing vector element at index '0'
5604// :145:25: error: use of undefined value here causes illegal behavior5596// :145:25: error: use of undefined value here causes illegal behavior
5597// :145:25: note: when computing vector element at index '0'
5605// :145:25: error: use of undefined value here causes illegal behavior5598// :145:25: error: use of undefined value here causes illegal behavior
5606// :145:25: note: when computing vector element at index '0'5599// :145:25: note: when computing vector element at index '0'
5607// :145:25: error: use of undefined value here causes illegal behavior5600// :145:25: error: use of undefined value here causes illegal behavior
5608// :145:25: note: when computing vector element at index '0'5601// :145:25: note: when computing vector element at index '0'
5609// :145:25: error: use of undefined value here causes illegal behavior5602// :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'
5611// :145:25: error: use of undefined value here causes illegal behavior5604// :145:25: error: use of undefined value here causes illegal behavior
5612// :145:25: note: when computing vector element at index '0'5605// :145:25: note: when computing vector element at index '0'
5613// :145:25: error: use of undefined value here causes illegal behavior5606// :145:25: error: use of undefined value here causes illegal behavior
5614// :145:25: note: when computing vector element at index '0'5607// :145:25: note: when computing vector element at index '0'
5615// :145:25: error: use of undefined value here causes illegal behavior5608// :145:25: error: use of undefined value here causes illegal behavior
5609// :145:25: note: when computing vector element at index '0'
5616// :145:25: error: use of undefined value here causes illegal behavior5610// :145:25: error: use of undefined value here causes illegal behavior
5617// :145:25: note: when computing vector element at index '0'5611// :145:25: note: when computing vector element at index '0'
5618// :145:25: error: use of undefined value here causes illegal behavior5612// :145:25: error: use of undefined value here causes illegal behavior
5619// :145:25: note: when computing vector element at index '0'5613// :145:25: note: when computing vector element at index '0'
5620// :145:25: error: use of undefined value here causes illegal behavior5614// :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'
5622// :145:25: error: use of undefined value here causes illegal behavior5616// :145:25: error: use of undefined value here causes illegal behavior
5623// :145:25: note: when computing vector element at index '0'5617// :145:25: note: when computing vector element at index '0'
5624// :145:25: error: use of undefined value here causes illegal behavior5618// :145:25: error: use of undefined value here causes illegal behavior
5625// :145:25: note: when computing vector element at index '0'5619// :145:25: note: when computing vector element at index '0'
5626// :145:25: error: use of undefined value here causes illegal behavior5620// :145:25: error: use of undefined value here causes illegal behavior
5621// :145:25: note: when computing vector element at index '0'
5627// :145:25: error: use of undefined value here causes illegal behavior5622// :145:25: error: use of undefined value here causes illegal behavior
5628// :145:25: note: when computing vector element at index '0'5623// :145:25: note: when computing vector element at index '0'
5629// :145:25: error: use of undefined value here causes illegal behavior5624// :145:25: error: use of undefined value here causes illegal behavior
...@@ -5631,20 +5626,25 @@ const std = @import("std");...@@ -5631,20 +5626,25 @@ const std = @import("std");
5631// :145:25: error: use of undefined value here causes illegal behavior5626// :145:25: error: use of undefined value here causes illegal behavior
5632// :145:25: note: when computing vector element at index '1'5627// :145:25: note: when computing vector element at index '1'
5633// :145:25: error: use of undefined value here causes illegal behavior5628// :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'
5635// :145:25: error: use of undefined value here causes illegal behavior5630// :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'
5637// :145:25: error: use of undefined value here causes illegal behavior5634// :145:25: error: use of undefined value here causes illegal behavior
5635// :145:25: note: when computing vector element at index '1'
5638// :145:25: error: use of undefined value here causes illegal behavior5636// :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'
5640// :145:25: error: use of undefined value here causes illegal behavior5638// :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'
5642// :145:25: error: use of undefined value here causes illegal behavior5640// :145:25: error: use of undefined value here causes illegal behavior
5643// :145:25: note: when computing vector element at index '1'5641// :145:25: note: when computing vector element at index '1'
5644// :145:25: error: use of undefined value here causes illegal behavior5642// :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'
5646// :145:25: error: use of undefined value here causes illegal behavior5644// :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'
5648// :151:21: error: use of undefined value here causes illegal behavior5648// :151:21: error: use of undefined value here causes illegal behavior
5649// :151:21: error: use of undefined value here causes illegal behavior5649// :151:21: error: use of undefined value here causes illegal behavior
5650// :151:21: error: use of undefined value here causes illegal behavior5650// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5652,21 +5652,13 @@ const std = @import("std");...@@ -5652,21 +5652,13 @@ const std = @import("std");
5652// :151:21: error: use of undefined value here causes illegal behavior5652// :151:21: error: use of undefined value here causes illegal behavior
5653// :151:21: error: use of undefined value here causes illegal behavior5653// :151:21: error: use of undefined value here causes illegal behavior
5654// :151:21: error: use of undefined value here causes illegal behavior5654// :151:21: error: use of undefined value here causes illegal behavior
5655// :151:21: note: when computing vector element at index '1'
5656// :151:21: error: use of undefined value here causes illegal behavior5655// :151:21: error: use of undefined value here causes illegal behavior
5657// :151:21: note: when computing vector element at index '1'
5658// :151:21: error: use of undefined value here causes illegal behavior5656// :151:21: error: use of undefined value here causes illegal behavior
5659// :151:21: note: when computing vector element at index '1'
5660// :151:21: error: use of undefined value here causes illegal behavior5657// :151:21: error: use of undefined value here causes illegal behavior
5661// :151:21: note: when computing vector element at index '1'
5662// :151:21: error: use of undefined value here causes illegal behavior5658// :151:21: error: use of undefined value here causes illegal behavior
5663// :151:21: note: when computing vector element at index '0'
5664// :151:21: error: use of undefined value here causes illegal behavior5659// :151:21: error: use of undefined value here causes illegal behavior
5665// :151:21: note: when computing vector element at index '0'
5666// :151:21: error: use of undefined value here causes illegal behavior5660// :151:21: error: use of undefined value here causes illegal behavior
5667// :151:21: note: when computing vector element at index '0'
5668// :151:21: error: use of undefined value here causes illegal behavior5661// :151:21: error: use of undefined value here causes illegal behavior
5669// :151:21: note: when computing vector element at index '0'
5670// :151:21: error: use of undefined value here causes illegal behavior5662// :151:21: error: use of undefined value here causes illegal behavior
5671// :151:21: error: use of undefined value here causes illegal behavior5663// :151:21: error: use of undefined value here causes illegal behavior
5672// :151:21: error: use of undefined value here causes illegal behavior5664// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5674,21 +5666,13 @@ const std = @import("std");...@@ -5674,21 +5666,13 @@ const std = @import("std");
5674// :151:21: error: use of undefined value here causes illegal behavior5666// :151:21: error: use of undefined value here causes illegal behavior
5675// :151:21: error: use of undefined value here causes illegal behavior5667// :151:21: error: use of undefined value here causes illegal behavior
5676// :151:21: error: use of undefined value here causes illegal behavior5668// :151:21: error: use of undefined value here causes illegal behavior
5677// :151:21: note: when computing vector element at index '1'
5678// :151:21: error: use of undefined value here causes illegal behavior5669// :151:21: error: use of undefined value here causes illegal behavior
5679// :151:21: note: when computing vector element at index '1'
5680// :151:21: error: use of undefined value here causes illegal behavior5670// :151:21: error: use of undefined value here causes illegal behavior
5681// :151:21: note: when computing vector element at index '1'
5682// :151:21: error: use of undefined value here causes illegal behavior5671// :151:21: error: use of undefined value here causes illegal behavior
5683// :151:21: note: when computing vector element at index '1'
5684// :151:21: error: use of undefined value here causes illegal behavior5672// :151:21: error: use of undefined value here causes illegal behavior
5685// :151:21: note: when computing vector element at index '0'
5686// :151:21: error: use of undefined value here causes illegal behavior5673// :151:21: error: use of undefined value here causes illegal behavior
5687// :151:21: note: when computing vector element at index '0'
5688// :151:21: error: use of undefined value here causes illegal behavior5674// :151:21: error: use of undefined value here causes illegal behavior
5689// :151:21: note: when computing vector element at index '0'
5690// :151:21: error: use of undefined value here causes illegal behavior5675// :151:21: error: use of undefined value here causes illegal behavior
5691// :151:21: note: when computing vector element at index '0'
5692// :151:21: error: use of undefined value here causes illegal behavior5676// :151:21: error: use of undefined value here causes illegal behavior
5693// :151:21: error: use of undefined value here causes illegal behavior5677// :151:21: error: use of undefined value here causes illegal behavior
5694// :151:21: error: use of undefined value here causes illegal behavior5678// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5696,21 +5680,13 @@ const std = @import("std");...@@ -5696,21 +5680,13 @@ const std = @import("std");
5696// :151:21: error: use of undefined value here causes illegal behavior5680// :151:21: error: use of undefined value here causes illegal behavior
5697// :151:21: error: use of undefined value here causes illegal behavior5681// :151:21: error: use of undefined value here causes illegal behavior
5698// :151:21: error: use of undefined value here causes illegal behavior5682// :151:21: error: use of undefined value here causes illegal behavior
5699// :151:21: note: when computing vector element at index '1'
5700// :151:21: error: use of undefined value here causes illegal behavior5683// :151:21: error: use of undefined value here causes illegal behavior
5701// :151:21: note: when computing vector element at index '1'
5702// :151:21: error: use of undefined value here causes illegal behavior5684// :151:21: error: use of undefined value here causes illegal behavior
5703// :151:21: note: when computing vector element at index '1'
5704// :151:21: error: use of undefined value here causes illegal behavior5685// :151:21: error: use of undefined value here causes illegal behavior
5705// :151:21: note: when computing vector element at index '1'
5706// :151:21: error: use of undefined value here causes illegal behavior5686// :151:21: error: use of undefined value here causes illegal behavior
5707// :151:21: note: when computing vector element at index '0'
5708// :151:21: error: use of undefined value here causes illegal behavior5687// :151:21: error: use of undefined value here causes illegal behavior
5709// :151:21: note: when computing vector element at index '0'
5710// :151:21: error: use of undefined value here causes illegal behavior5688// :151:21: error: use of undefined value here causes illegal behavior
5711// :151:21: note: when computing vector element at index '0'
5712// :151:21: error: use of undefined value here causes illegal behavior5689// :151:21: error: use of undefined value here causes illegal behavior
5713// :151:21: note: when computing vector element at index '0'
5714// :151:21: error: use of undefined value here causes illegal behavior5690// :151:21: error: use of undefined value here causes illegal behavior
5715// :151:21: error: use of undefined value here causes illegal behavior5691// :151:21: error: use of undefined value here causes illegal behavior
5716// :151:21: error: use of undefined value here causes illegal behavior5692// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5718,21 +5694,13 @@ const std = @import("std");...@@ -5718,21 +5694,13 @@ const std = @import("std");
5718// :151:21: error: use of undefined value here causes illegal behavior5694// :151:21: error: use of undefined value here causes illegal behavior
5719// :151:21: error: use of undefined value here causes illegal behavior5695// :151:21: error: use of undefined value here causes illegal behavior
5720// :151:21: error: use of undefined value here causes illegal behavior5696// :151:21: error: use of undefined value here causes illegal behavior
5721// :151:21: note: when computing vector element at index '1'
5722// :151:21: error: use of undefined value here causes illegal behavior5697// :151:21: error: use of undefined value here causes illegal behavior
5723// :151:21: note: when computing vector element at index '1'
5724// :151:21: error: use of undefined value here causes illegal behavior5698// :151:21: error: use of undefined value here causes illegal behavior
5725// :151:21: note: when computing vector element at index '1'
5726// :151:21: error: use of undefined value here causes illegal behavior5699// :151:21: error: use of undefined value here causes illegal behavior
5727// :151:21: note: when computing vector element at index '1'
5728// :151:21: error: use of undefined value here causes illegal behavior5700// :151:21: error: use of undefined value here causes illegal behavior
5729// :151:21: note: when computing vector element at index '0'
5730// :151:21: error: use of undefined value here causes illegal behavior5701// :151:21: error: use of undefined value here causes illegal behavior
5731// :151:21: note: when computing vector element at index '0'
5732// :151:21: error: use of undefined value here causes illegal behavior5702// :151:21: error: use of undefined value here causes illegal behavior
5733// :151:21: note: when computing vector element at index '0'
5734// :151:21: error: use of undefined value here causes illegal behavior5703// :151:21: error: use of undefined value here causes illegal behavior
5735// :151:21: note: when computing vector element at index '0'
5736// :151:21: error: use of undefined value here causes illegal behavior5704// :151:21: error: use of undefined value here causes illegal behavior
5737// :151:21: error: use of undefined value here causes illegal behavior5705// :151:21: error: use of undefined value here causes illegal behavior
5738// :151:21: error: use of undefined value here causes illegal behavior5706// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5740,13 +5708,9 @@ const std = @import("std");...@@ -5740,13 +5708,9 @@ const std = @import("std");
5740// :151:21: error: use of undefined value here causes illegal behavior5708// :151:21: error: use of undefined value here causes illegal behavior
5741// :151:21: error: use of undefined value here causes illegal behavior5709// :151:21: error: use of undefined value here causes illegal behavior
5742// :151:21: error: use of undefined value here causes illegal behavior5710// :151:21: error: use of undefined value here causes illegal behavior
5743// :151:21: note: when computing vector element at index '1'
5744// :151:21: error: use of undefined value here causes illegal behavior5711// :151:21: error: use of undefined value here causes illegal behavior
5745// :151:21: note: when computing vector element at index '1'
5746// :151:21: error: use of undefined value here causes illegal behavior5712// :151:21: error: use of undefined value here causes illegal behavior
5747// :151:21: note: when computing vector element at index '1'
5748// :151:21: error: use of undefined value here causes illegal behavior5713// :151:21: error: use of undefined value here causes illegal behavior
5749// :151:21: note: when computing vector element at index '1'
5750// :151:21: error: use of undefined value here causes illegal behavior5714// :151:21: error: use of undefined value here causes illegal behavior
5751// :151:21: note: when computing vector element at index '0'5715// :151:21: note: when computing vector element at index '0'
5752// :151:21: error: use of undefined value here causes illegal behavior5716// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5756,19 +5720,21 @@ const std = @import("std");...@@ -5756,19 +5720,21 @@ const std = @import("std");
5756// :151:21: error: use of undefined value here causes illegal behavior5720// :151:21: error: use of undefined value here causes illegal behavior
5757// :151:21: note: when computing vector element at index '0'5721// :151:21: note: when computing vector element at index '0'
5758// :151:21: error: use of undefined value here causes illegal behavior5722// :151:21: error: use of undefined value here causes illegal behavior
5723// :151:21: note: when computing vector element at index '0'
5759// :151:21: error: use of undefined value here causes illegal behavior5724// :151:21: error: use of undefined value here causes illegal behavior
5725// :151:21: note: when computing vector element at index '0'
5760// :151:21: error: use of undefined value here causes illegal behavior5726// :151:21: error: use of undefined value here causes illegal behavior
5727// :151:21: note: when computing vector element at index '0'
5761// :151:21: error: use of undefined value here causes illegal behavior5728// :151:21: error: use of undefined value here causes illegal behavior
5729// :151:21: note: when computing vector element at index '0'
5762// :151:21: error: use of undefined value here causes illegal behavior5730// :151:21: error: use of undefined value here causes illegal behavior
5731// :151:21: note: when computing vector element at index '0'
5763// :151:21: error: use of undefined value here causes illegal behavior5732// :151:21: error: use of undefined value here causes illegal behavior
5733// :151:21: note: when computing vector element at index '0'
5764// :151:21: error: use of undefined value here causes illegal behavior5734// :151:21: error: use of undefined value here causes illegal behavior
5765// :151:21: note: when computing vector element at index '1'5735// :151:21: note: when computing vector element at index '0'
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'
5770// :151:21: error: use of undefined value here causes illegal behavior5736// :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'
5772// :151:21: error: use of undefined value here causes illegal behavior5738// :151:21: error: use of undefined value here causes illegal behavior
5773// :151:21: note: when computing vector element at index '0'5739// :151:21: note: when computing vector element at index '0'
5774// :151:21: error: use of undefined value here causes illegal behavior5740// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5778,19 +5744,25 @@ const std = @import("std");...@@ -5778,19 +5744,25 @@ const std = @import("std");
5778// :151:21: error: use of undefined value here causes illegal behavior5744// :151:21: error: use of undefined value here causes illegal behavior
5779// :151:21: note: when computing vector element at index '0'5745// :151:21: note: when computing vector element at index '0'
5780// :151:21: error: use of undefined value here causes illegal behavior5746// :151:21: error: use of undefined value here causes illegal behavior
5747// :151:21: note: when computing vector element at index '0'
5781// :151:21: error: use of undefined value here causes illegal behavior5748// :151:21: error: use of undefined value here causes illegal behavior
5749// :151:21: note: when computing vector element at index '0'
5782// :151:21: error: use of undefined value here causes illegal behavior5750// :151:21: error: use of undefined value here causes illegal behavior
5751// :151:21: note: when computing vector element at index '0'
5783// :151:21: error: use of undefined value here causes illegal behavior5752// :151:21: error: use of undefined value here causes illegal behavior
5753// :151:21: note: when computing vector element at index '0'
5784// :151:21: error: use of undefined value here causes illegal behavior5754// :151:21: error: use of undefined value here causes illegal behavior
5755// :151:21: note: when computing vector element at index '0'
5785// :151:21: error: use of undefined value here causes illegal behavior5756// :151:21: error: use of undefined value here causes illegal behavior
5757// :151:21: note: when computing vector element at index '0'
5786// :151:21: error: use of undefined value here causes illegal behavior5758// :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'
5788// :151:21: error: use of undefined value here causes illegal behavior5760// :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'
5790// :151:21: error: use of undefined value here causes illegal behavior5762// :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'
5792// :151:21: error: use of undefined value here causes illegal behavior5764// :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'
5794// :151:21: error: use of undefined value here causes illegal behavior5766// :151:21: error: use of undefined value here causes illegal behavior
5795// :151:21: note: when computing vector element at index '0'5767// :151:21: note: when computing vector element at index '0'
5796// :151:21: error: use of undefined value here causes illegal behavior5768// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5800,19 +5772,25 @@ const std = @import("std");...@@ -5800,19 +5772,25 @@ const std = @import("std");
5800// :151:21: error: use of undefined value here causes illegal behavior5772// :151:21: error: use of undefined value here causes illegal behavior
5801// :151:21: note: when computing vector element at index '0'5773// :151:21: note: when computing vector element at index '0'
5802// :151:21: error: use of undefined value here causes illegal behavior5774// :151:21: error: use of undefined value here causes illegal behavior
5775// :151:21: note: when computing vector element at index '0'
5803// :151:21: error: use of undefined value here causes illegal behavior5776// :151:21: error: use of undefined value here causes illegal behavior
5777// :151:21: note: when computing vector element at index '0'
5804// :151:21: error: use of undefined value here causes illegal behavior5778// :151:21: error: use of undefined value here causes illegal behavior
5779// :151:21: note: when computing vector element at index '0'
5805// :151:21: error: use of undefined value here causes illegal behavior5780// :151:21: error: use of undefined value here causes illegal behavior
5781// :151:21: note: when computing vector element at index '0'
5806// :151:21: error: use of undefined value here causes illegal behavior5782// :151:21: error: use of undefined value here causes illegal behavior
5783// :151:21: note: when computing vector element at index '0'
5807// :151:21: error: use of undefined value here causes illegal behavior5784// :151:21: error: use of undefined value here causes illegal behavior
5785// :151:21: note: when computing vector element at index '0'
5808// :151:21: error: use of undefined value here causes illegal behavior5786// :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'
5810// :151:21: error: use of undefined value here causes illegal behavior5788// :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'
5812// :151:21: error: use of undefined value here causes illegal behavior5790// :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'
5814// :151:21: error: use of undefined value here causes illegal behavior5792// :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'
5816// :151:21: error: use of undefined value here causes illegal behavior5794// :151:21: error: use of undefined value here causes illegal behavior
5817// :151:21: note: when computing vector element at index '0'5795// :151:21: note: when computing vector element at index '0'
5818// :151:21: error: use of undefined value here causes illegal behavior5796// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5822,11 +5800,17 @@ const std = @import("std");...@@ -5822,11 +5800,17 @@ const std = @import("std");
5822// :151:21: error: use of undefined value here causes illegal behavior5800// :151:21: error: use of undefined value here causes illegal behavior
5823// :151:21: note: when computing vector element at index '0'5801// :151:21: note: when computing vector element at index '0'
5824// :151:21: error: use of undefined value here causes illegal behavior5802// :151:21: error: use of undefined value here causes illegal behavior
5803// :151:21: note: when computing vector element at index '1'
5825// :151:21: error: use of undefined value here causes illegal behavior5804// :151:21: error: use of undefined value here causes illegal behavior
5805// :151:21: note: when computing vector element at index '1'
5826// :151:21: error: use of undefined value here causes illegal behavior5806// :151:21: error: use of undefined value here causes illegal behavior
5807// :151:21: note: when computing vector element at index '1'
5827// :151:21: error: use of undefined value here causes illegal behavior5808// :151:21: error: use of undefined value here causes illegal behavior
5809// :151:21: note: when computing vector element at index '1'
5828// :151:21: error: use of undefined value here causes illegal behavior5810// :151:21: error: use of undefined value here causes illegal behavior
5811// :151:21: note: when computing vector element at index '1'
5829// :151:21: error: use of undefined value here causes illegal behavior5812// :151:21: error: use of undefined value here causes illegal behavior
5813// :151:21: note: when computing vector element at index '1'
5830// :151:21: error: use of undefined value here causes illegal behavior5814// :151:21: error: use of undefined value here causes illegal behavior
5831// :151:21: note: when computing vector element at index '1'5815// :151:21: note: when computing vector element at index '1'
5832// :151:21: error: use of undefined value here causes illegal behavior5816// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5836,19 +5820,25 @@ const std = @import("std");...@@ -5836,19 +5820,25 @@ const std = @import("std");
5836// :151:21: error: use of undefined value here causes illegal behavior5820// :151:21: error: use of undefined value here causes illegal behavior
5837// :151:21: note: when computing vector element at index '1'5821// :151:21: note: when computing vector element at index '1'
5838// :151:21: error: use of undefined value here causes illegal behavior5822// :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'
5840// :151:21: error: use of undefined value here causes illegal behavior5824// :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'
5842// :151:21: error: use of undefined value here causes illegal behavior5826// :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'
5844// :151:21: error: use of undefined value here causes illegal behavior5828// :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'
5846// :151:21: error: use of undefined value here causes illegal behavior5830// :151:21: error: use of undefined value here causes illegal behavior
5831// :151:21: note: when computing vector element at index '1'
5847// :151:21: error: use of undefined value here causes illegal behavior5832// :151:21: error: use of undefined value here causes illegal behavior
5833// :151:21: note: when computing vector element at index '1'
5848// :151:21: error: use of undefined value here causes illegal behavior5834// :151:21: error: use of undefined value here causes illegal behavior
5835// :151:21: note: when computing vector element at index '1'
5849// :151:21: error: use of undefined value here causes illegal behavior5836// :151:21: error: use of undefined value here causes illegal behavior
5837// :151:21: note: when computing vector element at index '1'
5850// :151:21: error: use of undefined value here causes illegal behavior5838// :151:21: error: use of undefined value here causes illegal behavior
5839// :151:21: note: when computing vector element at index '1'
5851// :151:21: error: use of undefined value here causes illegal behavior5840// :151:21: error: use of undefined value here causes illegal behavior
5841// :151:21: note: when computing vector element at index '1'
5852// :151:21: error: use of undefined value here causes illegal behavior5842// :151:21: error: use of undefined value here causes illegal behavior
5853// :151:21: note: when computing vector element at index '1'5843// :151:21: note: when computing vector element at index '1'
5854// :151:21: error: use of undefined value here causes illegal behavior5844// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5858,19 +5848,25 @@ const std = @import("std");...@@ -5858,19 +5848,25 @@ const std = @import("std");
5858// :151:21: error: use of undefined value here causes illegal behavior5848// :151:21: error: use of undefined value here causes illegal behavior
5859// :151:21: note: when computing vector element at index '1'5849// :151:21: note: when computing vector element at index '1'
5860// :151:21: error: use of undefined value here causes illegal behavior5850// :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'
5862// :151:21: error: use of undefined value here causes illegal behavior5852// :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'
5864// :151:21: error: use of undefined value here causes illegal behavior5854// :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'
5866// :151:21: error: use of undefined value here causes illegal behavior5856// :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'
5868// :151:21: error: use of undefined value here causes illegal behavior5858// :151:21: error: use of undefined value here causes illegal behavior
5859// :151:21: note: when computing vector element at index '1'
5869// :151:21: error: use of undefined value here causes illegal behavior5860// :151:21: error: use of undefined value here causes illegal behavior
5861// :151:21: note: when computing vector element at index '1'
5870// :151:21: error: use of undefined value here causes illegal behavior5862// :151:21: error: use of undefined value here causes illegal behavior
5863// :151:21: note: when computing vector element at index '1'
5871// :151:21: error: use of undefined value here causes illegal behavior5864// :151:21: error: use of undefined value here causes illegal behavior
5865// :151:21: note: when computing vector element at index '1'
5872// :151:21: error: use of undefined value here causes illegal behavior5866// :151:21: error: use of undefined value here causes illegal behavior
5867// :151:21: note: when computing vector element at index '1'
5873// :151:21: error: use of undefined value here causes illegal behavior5868// :151:21: error: use of undefined value here causes illegal behavior
5869// :151:21: note: when computing vector element at index '1'
5874// :151:21: error: use of undefined value here causes illegal behavior5870// :151:21: error: use of undefined value here causes illegal behavior
5875// :151:21: note: when computing vector element at index '1'5871// :151:21: note: when computing vector element at index '1'
5876// :151:21: error: use of undefined value here causes illegal behavior5872// :151:21: error: use of undefined value here causes illegal behavior
...@@ -5880,13 +5876,17 @@ const std = @import("std");...@@ -5880,13 +5876,17 @@ const std = @import("std");
5880// :151:21: error: use of undefined value here causes illegal behavior5876// :151:21: error: use of undefined value here causes illegal behavior
5881// :151:21: note: when computing vector element at index '1'5877// :151:21: note: when computing vector element at index '1'
5882// :151:21: error: use of undefined value here causes illegal behavior5878// :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'
5884// :151:21: error: use of undefined value here causes illegal behavior5880// :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'
5886// :151:21: error: use of undefined value here causes illegal behavior5882// :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'
5888// :151:21: error: use of undefined value here causes illegal behavior5884// :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'
5890// :155:30: error: use of undefined value here causes illegal behavior5890// :155:30: error: use of undefined value here causes illegal behavior
5891// :155:30: error: use of undefined value here causes illegal behavior5891// :155:30: error: use of undefined value here causes illegal behavior
5892// :155:30: error: use of undefined value here causes illegal behavior5892// :155:30: error: use of undefined value here causes illegal behavior
...@@ -5894,21 +5894,13 @@ const std = @import("std");...@@ -5894,21 +5894,13 @@ const std = @import("std");
5894// :155:30: error: use of undefined value here causes illegal behavior5894// :155:30: error: use of undefined value here causes illegal behavior
5895// :155:30: error: use of undefined value here causes illegal behavior5895// :155:30: error: use of undefined value here causes illegal behavior
5896// :155:30: error: use of undefined value here causes illegal behavior5896// :155:30: error: use of undefined value here causes illegal behavior
5897// :155:30: note: when computing vector element at index '1'
5898// :155:30: error: use of undefined value here causes illegal behavior5897// :155:30: error: use of undefined value here causes illegal behavior
5899// :155:30: note: when computing vector element at index '1'
5900// :155:30: error: use of undefined value here causes illegal behavior5898// :155:30: error: use of undefined value here causes illegal behavior
5901// :155:30: note: when computing vector element at index '1'
5902// :155:30: error: use of undefined value here causes illegal behavior5899// :155:30: error: use of undefined value here causes illegal behavior
5903// :155:30: note: when computing vector element at index '1'
5904// :155:30: error: use of undefined value here causes illegal behavior5900// :155:30: error: use of undefined value here causes illegal behavior
5905// :155:30: note: when computing vector element at index '0'
5906// :155:30: error: use of undefined value here causes illegal behavior5901// :155:30: error: use of undefined value here causes illegal behavior
5907// :155:30: note: when computing vector element at index '0'
5908// :155:30: error: use of undefined value here causes illegal behavior5902// :155:30: error: use of undefined value here causes illegal behavior
5909// :155:30: note: when computing vector element at index '0'
5910// :155:30: error: use of undefined value here causes illegal behavior5903// :155:30: error: use of undefined value here causes illegal behavior
5911// :155:30: note: when computing vector element at index '0'
5912// :155:30: error: use of undefined value here causes illegal behavior5904// :155:30: error: use of undefined value here causes illegal behavior
5913// :155:30: error: use of undefined value here causes illegal behavior5905// :155:30: error: use of undefined value here causes illegal behavior
5914// :155:30: error: use of undefined value here causes illegal behavior5906// :155:30: error: use of undefined value here causes illegal behavior
...@@ -5916,21 +5908,13 @@ const std = @import("std");...@@ -5916,21 +5908,13 @@ const std = @import("std");
5916// :155:30: error: use of undefined value here causes illegal behavior5908// :155:30: error: use of undefined value here causes illegal behavior
5917// :155:30: error: use of undefined value here causes illegal behavior5909// :155:30: error: use of undefined value here causes illegal behavior
5918// :155:30: error: use of undefined value here causes illegal behavior5910// :155:30: error: use of undefined value here causes illegal behavior
5919// :155:30: note: when computing vector element at index '1'
5920// :155:30: error: use of undefined value here causes illegal behavior5911// :155:30: error: use of undefined value here causes illegal behavior
5921// :155:30: note: when computing vector element at index '1'
5922// :155:30: error: use of undefined value here causes illegal behavior5912// :155:30: error: use of undefined value here causes illegal behavior
5923// :155:30: note: when computing vector element at index '1'
5924// :155:30: error: use of undefined value here causes illegal behavior5913// :155:30: error: use of undefined value here causes illegal behavior
5925// :155:30: note: when computing vector element at index '1'
5926// :155:30: error: use of undefined value here causes illegal behavior5914// :155:30: error: use of undefined value here causes illegal behavior
5927// :155:30: note: when computing vector element at index '0'
5928// :155:30: error: use of undefined value here causes illegal behavior5915// :155:30: error: use of undefined value here causes illegal behavior
5929// :155:30: note: when computing vector element at index '0'
5930// :155:30: error: use of undefined value here causes illegal behavior5916// :155:30: error: use of undefined value here causes illegal behavior
5931// :155:30: note: when computing vector element at index '0'
5932// :155:30: error: use of undefined value here causes illegal behavior5917// :155:30: error: use of undefined value here causes illegal behavior
5933// :155:30: note: when computing vector element at index '0'
5934// :155:30: error: use of undefined value here causes illegal behavior5918// :155:30: error: use of undefined value here causes illegal behavior
5935// :155:30: error: use of undefined value here causes illegal behavior5919// :155:30: error: use of undefined value here causes illegal behavior
5936// :155:30: error: use of undefined value here causes illegal behavior5920// :155:30: error: use of undefined value here causes illegal behavior
...@@ -5938,21 +5922,13 @@ const std = @import("std");...@@ -5938,21 +5922,13 @@ const std = @import("std");
5938// :155:30: error: use of undefined value here causes illegal behavior5922// :155:30: error: use of undefined value here causes illegal behavior
5939// :155:30: error: use of undefined value here causes illegal behavior5923// :155:30: error: use of undefined value here causes illegal behavior
5940// :155:30: error: use of undefined value here causes illegal behavior5924// :155:30: error: use of undefined value here causes illegal behavior
5941// :155:30: note: when computing vector element at index '1'
5942// :155:30: error: use of undefined value here causes illegal behavior5925// :155:30: error: use of undefined value here causes illegal behavior
5943// :155:30: note: when computing vector element at index '1'
5944// :155:30: error: use of undefined value here causes illegal behavior5926// :155:30: error: use of undefined value here causes illegal behavior
5945// :155:30: note: when computing vector element at index '1'
5946// :155:30: error: use of undefined value here causes illegal behavior5927// :155:30: error: use of undefined value here causes illegal behavior
5947// :155:30: note: when computing vector element at index '1'
5948// :155:30: error: use of undefined value here causes illegal behavior5928// :155:30: error: use of undefined value here causes illegal behavior
5949// :155:30: note: when computing vector element at index '0'
5950// :155:30: error: use of undefined value here causes illegal behavior5929// :155:30: error: use of undefined value here causes illegal behavior
5951// :155:30: note: when computing vector element at index '0'
5952// :155:30: error: use of undefined value here causes illegal behavior5930// :155:30: error: use of undefined value here causes illegal behavior
5953// :155:30: note: when computing vector element at index '0'
5954// :155:30: error: use of undefined value here causes illegal behavior5931// :155:30: error: use of undefined value here causes illegal behavior
5955// :155:30: note: when computing vector element at index '0'
5956// :155:30: error: use of undefined value here causes illegal behavior5932// :155:30: error: use of undefined value here causes illegal behavior
5957// :155:30: error: use of undefined value here causes illegal behavior5933// :155:30: error: use of undefined value here causes illegal behavior
5958// :155:30: error: use of undefined value here causes illegal behavior5934// :155:30: error: use of undefined value here causes illegal behavior
...@@ -5960,21 +5936,13 @@ const std = @import("std");...@@ -5960,21 +5936,13 @@ const std = @import("std");
5960// :155:30: error: use of undefined value here causes illegal behavior5936// :155:30: error: use of undefined value here causes illegal behavior
5961// :155:30: error: use of undefined value here causes illegal behavior5937// :155:30: error: use of undefined value here causes illegal behavior
5962// :155:30: error: use of undefined value here causes illegal behavior5938// :155:30: error: use of undefined value here causes illegal behavior
5963// :155:30: note: when computing vector element at index '1'
5964// :155:30: error: use of undefined value here causes illegal behavior5939// :155:30: error: use of undefined value here causes illegal behavior
5965// :155:30: note: when computing vector element at index '1'
5966// :155:30: error: use of undefined value here causes illegal behavior5940// :155:30: error: use of undefined value here causes illegal behavior
5967// :155:30: note: when computing vector element at index '1'
5968// :155:30: error: use of undefined value here causes illegal behavior5941// :155:30: error: use of undefined value here causes illegal behavior
5969// :155:30: note: when computing vector element at index '1'
5970// :155:30: error: use of undefined value here causes illegal behavior5942// :155:30: error: use of undefined value here causes illegal behavior
5971// :155:30: note: when computing vector element at index '0'
5972// :155:30: error: use of undefined value here causes illegal behavior5943// :155:30: error: use of undefined value here causes illegal behavior
5973// :155:30: note: when computing vector element at index '0'
5974// :155:30: error: use of undefined value here causes illegal behavior5944// :155:30: error: use of undefined value here causes illegal behavior
5975// :155:30: note: when computing vector element at index '0'
5976// :155:30: error: use of undefined value here causes illegal behavior5945// :155:30: error: use of undefined value here causes illegal behavior
5977// :155:30: note: when computing vector element at index '0'
5978// :155:30: error: use of undefined value here causes illegal behavior5946// :155:30: error: use of undefined value here causes illegal behavior
5979// :155:30: error: use of undefined value here causes illegal behavior5947// :155:30: error: use of undefined value here causes illegal behavior
5980// :155:30: error: use of undefined value here causes illegal behavior5948// :155:30: error: use of undefined value here causes illegal behavior
...@@ -5982,13 +5950,9 @@ const std = @import("std");...@@ -5982,13 +5950,9 @@ const std = @import("std");
5982// :155:30: error: use of undefined value here causes illegal behavior5950// :155:30: error: use of undefined value here causes illegal behavior
5983// :155:30: error: use of undefined value here causes illegal behavior5951// :155:30: error: use of undefined value here causes illegal behavior
5984// :155:30: error: use of undefined value here causes illegal behavior5952// :155:30: error: use of undefined value here causes illegal behavior
5985// :155:30: note: when computing vector element at index '1'
5986// :155:30: error: use of undefined value here causes illegal behavior5953// :155:30: error: use of undefined value here causes illegal behavior
5987// :155:30: note: when computing vector element at index '1'
5988// :155:30: error: use of undefined value here causes illegal behavior5954// :155:30: error: use of undefined value here causes illegal behavior
5989// :155:30: note: when computing vector element at index '1'
5990// :155:30: error: use of undefined value here causes illegal behavior5955// :155:30: error: use of undefined value here causes illegal behavior
5991// :155:30: note: when computing vector element at index '1'
5992// :155:30: error: use of undefined value here causes illegal behavior5956// :155:30: error: use of undefined value here causes illegal behavior
5993// :155:30: note: when computing vector element at index '0'5957// :155:30: note: when computing vector element at index '0'
5994// :155:30: error: use of undefined value here causes illegal behavior5958// :155:30: error: use of undefined value here causes illegal behavior
...@@ -5998,19 +5962,21 @@ const std = @import("std");...@@ -5998,19 +5962,21 @@ const std = @import("std");
5998// :155:30: error: use of undefined value here causes illegal behavior5962// :155:30: error: use of undefined value here causes illegal behavior
5999// :155:30: note: when computing vector element at index '0'5963// :155:30: note: when computing vector element at index '0'
6000// :155:30: error: use of undefined value here causes illegal behavior5964// :155:30: error: use of undefined value here causes illegal behavior
5965// :155:30: note: when computing vector element at index '0'
6001// :155:30: error: use of undefined value here causes illegal behavior5966// :155:30: error: use of undefined value here causes illegal behavior
5967// :155:30: note: when computing vector element at index '0'
6002// :155:30: error: use of undefined value here causes illegal behavior5968// :155:30: error: use of undefined value here causes illegal behavior
5969// :155:30: note: when computing vector element at index '0'
6003// :155:30: error: use of undefined value here causes illegal behavior5970// :155:30: error: use of undefined value here causes illegal behavior
5971// :155:30: note: when computing vector element at index '0'
6004// :155:30: error: use of undefined value here causes illegal behavior5972// :155:30: error: use of undefined value here causes illegal behavior
5973// :155:30: note: when computing vector element at index '0'
6005// :155:30: error: use of undefined value here causes illegal behavior5974// :155:30: error: use of undefined value here causes illegal behavior
5975// :155:30: note: when computing vector element at index '0'
6006// :155:30: error: use of undefined value here causes illegal behavior5976// :155:30: error: use of undefined value here causes illegal behavior
6007// :155:30: note: when computing vector element at index '1'5977// :155:30: note: when computing vector element at index '0'
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'
6012// :155:30: error: use of undefined value here causes illegal behavior5978// :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'
6014// :155:30: error: use of undefined value here causes illegal behavior5980// :155:30: error: use of undefined value here causes illegal behavior
6015// :155:30: note: when computing vector element at index '0'5981// :155:30: note: when computing vector element at index '0'
6016// :155:30: error: use of undefined value here causes illegal behavior5982// :155:30: error: use of undefined value here causes illegal behavior
...@@ -6020,19 +5986,25 @@ const std = @import("std");...@@ -6020,19 +5986,25 @@ const std = @import("std");
6020// :155:30: error: use of undefined value here causes illegal behavior5986// :155:30: error: use of undefined value here causes illegal behavior
6021// :155:30: note: when computing vector element at index '0'5987// :155:30: note: when computing vector element at index '0'
6022// :155:30: error: use of undefined value here causes illegal behavior5988// :155:30: error: use of undefined value here causes illegal behavior
5989// :155:30: note: when computing vector element at index '0'
6023// :155:30: error: use of undefined value here causes illegal behavior5990// :155:30: error: use of undefined value here causes illegal behavior
5991// :155:30: note: when computing vector element at index '0'
6024// :155:30: error: use of undefined value here causes illegal behavior5992// :155:30: error: use of undefined value here causes illegal behavior
5993// :155:30: note: when computing vector element at index '0'
6025// :155:30: error: use of undefined value here causes illegal behavior5994// :155:30: error: use of undefined value here causes illegal behavior
5995// :155:30: note: when computing vector element at index '0'
6026// :155:30: error: use of undefined value here causes illegal behavior5996// :155:30: error: use of undefined value here causes illegal behavior
5997// :155:30: note: when computing vector element at index '0'
6027// :155:30: error: use of undefined value here causes illegal behavior5998// :155:30: error: use of undefined value here causes illegal behavior
5999// :155:30: note: when computing vector element at index '0'
6028// :155:30: error: use of undefined value here causes illegal behavior6000// :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'
6030// :155:30: error: use of undefined value here causes illegal behavior6002// :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'
6032// :155:30: error: use of undefined value here causes illegal behavior6004// :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'
6034// :155:30: error: use of undefined value here causes illegal behavior6006// :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'
6036// :155:30: error: use of undefined value here causes illegal behavior6008// :155:30: error: use of undefined value here causes illegal behavior
6037// :155:30: note: when computing vector element at index '0'6009// :155:30: note: when computing vector element at index '0'
6038// :155:30: error: use of undefined value here causes illegal behavior6010// :155:30: error: use of undefined value here causes illegal behavior
...@@ -6042,19 +6014,25 @@ const std = @import("std");...@@ -6042,19 +6014,25 @@ const std = @import("std");
6042// :155:30: error: use of undefined value here causes illegal behavior6014// :155:30: error: use of undefined value here causes illegal behavior
6043// :155:30: note: when computing vector element at index '0'6015// :155:30: note: when computing vector element at index '0'
6044// :155:30: error: use of undefined value here causes illegal behavior6016// :155:30: error: use of undefined value here causes illegal behavior
6017// :155:30: note: when computing vector element at index '0'
6045// :155:30: error: use of undefined value here causes illegal behavior6018// :155:30: error: use of undefined value here causes illegal behavior
6019// :155:30: note: when computing vector element at index '0'
6046// :155:30: error: use of undefined value here causes illegal behavior6020// :155:30: error: use of undefined value here causes illegal behavior
6021// :155:30: note: when computing vector element at index '0'
6047// :155:30: error: use of undefined value here causes illegal behavior6022// :155:30: error: use of undefined value here causes illegal behavior
6023// :155:30: note: when computing vector element at index '0'
6048// :155:30: error: use of undefined value here causes illegal behavior6024// :155:30: error: use of undefined value here causes illegal behavior
6025// :155:30: note: when computing vector element at index '0'
6049// :155:30: error: use of undefined value here causes illegal behavior6026// :155:30: error: use of undefined value here causes illegal behavior
6027// :155:30: note: when computing vector element at index '0'
6050// :155:30: error: use of undefined value here causes illegal behavior6028// :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'
6052// :155:30: error: use of undefined value here causes illegal behavior6030// :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'
6054// :155:30: error: use of undefined value here causes illegal behavior6032// :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'
6056// :155:30: error: use of undefined value here causes illegal behavior6034// :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'
6058// :155:30: error: use of undefined value here causes illegal behavior6036// :155:30: error: use of undefined value here causes illegal behavior
6059// :155:30: note: when computing vector element at index '0'6037// :155:30: note: when computing vector element at index '0'
6060// :155:30: error: use of undefined value here causes illegal behavior6038// :155:30: error: use of undefined value here causes illegal behavior
...@@ -6064,11 +6042,17 @@ const std = @import("std");...@@ -6064,11 +6042,17 @@ const std = @import("std");
6064// :155:30: error: use of undefined value here causes illegal behavior6042// :155:30: error: use of undefined value here causes illegal behavior
6065// :155:30: note: when computing vector element at index '0'6043// :155:30: note: when computing vector element at index '0'
6066// :155:30: error: use of undefined value here causes illegal behavior6044// :155:30: error: use of undefined value here causes illegal behavior
6045// :155:30: note: when computing vector element at index '1'
6067// :155:30: error: use of undefined value here causes illegal behavior6046// :155:30: error: use of undefined value here causes illegal behavior
6047// :155:30: note: when computing vector element at index '1'
6068// :155:30: error: use of undefined value here causes illegal behavior6048// :155:30: error: use of undefined value here causes illegal behavior
6049// :155:30: note: when computing vector element at index '1'
6069// :155:30: error: use of undefined value here causes illegal behavior6050// :155:30: error: use of undefined value here causes illegal behavior
6051// :155:30: note: when computing vector element at index '1'
6070// :155:30: error: use of undefined value here causes illegal behavior6052// :155:30: error: use of undefined value here causes illegal behavior
6053// :155:30: note: when computing vector element at index '1'
6071// :155:30: error: use of undefined value here causes illegal behavior6054// :155:30: error: use of undefined value here causes illegal behavior
6055// :155:30: note: when computing vector element at index '1'
6072// :155:30: error: use of undefined value here causes illegal behavior6056// :155:30: error: use of undefined value here causes illegal behavior
6073// :155:30: note: when computing vector element at index '1'6057// :155:30: note: when computing vector element at index '1'
6074// :155:30: error: use of undefined value here causes illegal behavior6058// :155:30: error: use of undefined value here causes illegal behavior
...@@ -6078,19 +6062,25 @@ const std = @import("std");...@@ -6078,19 +6062,25 @@ const std = @import("std");
6078// :155:30: error: use of undefined value here causes illegal behavior6062// :155:30: error: use of undefined value here causes illegal behavior
6079// :155:30: note: when computing vector element at index '1'6063// :155:30: note: when computing vector element at index '1'
6080// :155:30: error: use of undefined value here causes illegal behavior6064// :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'
6082// :155:30: error: use of undefined value here causes illegal behavior6066// :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'
6084// :155:30: error: use of undefined value here causes illegal behavior6068// :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'
6086// :155:30: error: use of undefined value here causes illegal behavior6070// :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'
6088// :155:30: error: use of undefined value here causes illegal behavior6072// :155:30: error: use of undefined value here causes illegal behavior
6073// :155:30: note: when computing vector element at index '1'
6089// :155:30: error: use of undefined value here causes illegal behavior6074// :155:30: error: use of undefined value here causes illegal behavior
6075// :155:30: note: when computing vector element at index '1'
6090// :155:30: error: use of undefined value here causes illegal behavior6076// :155:30: error: use of undefined value here causes illegal behavior
6077// :155:30: note: when computing vector element at index '1'
6091// :155:30: error: use of undefined value here causes illegal behavior6078// :155:30: error: use of undefined value here causes illegal behavior
6079// :155:30: note: when computing vector element at index '1'
6092// :155:30: error: use of undefined value here causes illegal behavior6080// :155:30: error: use of undefined value here causes illegal behavior
6081// :155:30: note: when computing vector element at index '1'
6093// :155:30: error: use of undefined value here causes illegal behavior6082// :155:30: error: use of undefined value here causes illegal behavior
6083// :155:30: note: when computing vector element at index '1'
6094// :155:30: error: use of undefined value here causes illegal behavior6084// :155:30: error: use of undefined value here causes illegal behavior
6095// :155:30: note: when computing vector element at index '1'6085// :155:30: note: when computing vector element at index '1'
6096// :155:30: error: use of undefined value here causes illegal behavior6086// :155:30: error: use of undefined value here causes illegal behavior
...@@ -6100,19 +6090,25 @@ const std = @import("std");...@@ -6100,19 +6090,25 @@ const std = @import("std");
6100// :155:30: error: use of undefined value here causes illegal behavior6090// :155:30: error: use of undefined value here causes illegal behavior
6101// :155:30: note: when computing vector element at index '1'6091// :155:30: note: when computing vector element at index '1'
6102// :155:30: error: use of undefined value here causes illegal behavior6092// :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'
6104// :155:30: error: use of undefined value here causes illegal behavior6094// :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'
6106// :155:30: error: use of undefined value here causes illegal behavior6096// :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'
6108// :155:30: error: use of undefined value here causes illegal behavior6098// :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'
6110// :155:30: error: use of undefined value here causes illegal behavior6100// :155:30: error: use of undefined value here causes illegal behavior
6101// :155:30: note: when computing vector element at index '1'
6111// :155:30: error: use of undefined value here causes illegal behavior6102// :155:30: error: use of undefined value here causes illegal behavior
6103// :155:30: note: when computing vector element at index '1'
6112// :155:30: error: use of undefined value here causes illegal behavior6104// :155:30: error: use of undefined value here causes illegal behavior
6105// :155:30: note: when computing vector element at index '1'
6113// :155:30: error: use of undefined value here causes illegal behavior6106// :155:30: error: use of undefined value here causes illegal behavior
6107// :155:30: note: when computing vector element at index '1'
6114// :155:30: error: use of undefined value here causes illegal behavior6108// :155:30: error: use of undefined value here causes illegal behavior
6109// :155:30: note: when computing vector element at index '1'
6115// :155:30: error: use of undefined value here causes illegal behavior6110// :155:30: error: use of undefined value here causes illegal behavior
6111// :155:30: note: when computing vector element at index '1'
6116// :155:30: error: use of undefined value here causes illegal behavior6112// :155:30: error: use of undefined value here causes illegal behavior
6117// :155:30: note: when computing vector element at index '1'6113// :155:30: note: when computing vector element at index '1'
6118// :155:30: error: use of undefined value here causes illegal behavior6114// :155:30: error: use of undefined value here causes illegal behavior
...@@ -6122,13 +6118,17 @@ const std = @import("std");...@@ -6122,13 +6118,17 @@ const std = @import("std");
6122// :155:30: error: use of undefined value here causes illegal behavior6118// :155:30: error: use of undefined value here causes illegal behavior
6123// :155:30: note: when computing vector element at index '1'6119// :155:30: note: when computing vector element at index '1'
6124// :155:30: error: use of undefined value here causes illegal behavior6120// :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'
6126// :155:30: error: use of undefined value here causes illegal behavior6122// :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'
6128// :155:30: error: use of undefined value here causes illegal behavior6124// :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'
6130// :155:30: error: use of undefined value here causes illegal behavior6126// :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'
6132// :159:30: error: use of undefined value here causes illegal behavior6132// :159:30: error: use of undefined value here causes illegal behavior
6133// :159:30: error: use of undefined value here causes illegal behavior6133// :159:30: error: use of undefined value here causes illegal behavior
6134// :159:30: error: use of undefined value here causes illegal behavior6134// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6136,21 +6136,13 @@ const std = @import("std");...@@ -6136,21 +6136,13 @@ const std = @import("std");
6136// :159:30: error: use of undefined value here causes illegal behavior6136// :159:30: error: use of undefined value here causes illegal behavior
6137// :159:30: error: use of undefined value here causes illegal behavior6137// :159:30: error: use of undefined value here causes illegal behavior
6138// :159:30: error: use of undefined value here causes illegal behavior6138// :159:30: error: use of undefined value here causes illegal behavior
6139// :159:30: note: when computing vector element at index '1'
6140// :159:30: error: use of undefined value here causes illegal behavior6139// :159:30: error: use of undefined value here causes illegal behavior
6141// :159:30: note: when computing vector element at index '1'
6142// :159:30: error: use of undefined value here causes illegal behavior6140// :159:30: error: use of undefined value here causes illegal behavior
6143// :159:30: note: when computing vector element at index '1'
6144// :159:30: error: use of undefined value here causes illegal behavior6141// :159:30: error: use of undefined value here causes illegal behavior
6145// :159:30: note: when computing vector element at index '1'
6146// :159:30: error: use of undefined value here causes illegal behavior6142// :159:30: error: use of undefined value here causes illegal behavior
6147// :159:30: note: when computing vector element at index '0'
6148// :159:30: error: use of undefined value here causes illegal behavior6143// :159:30: error: use of undefined value here causes illegal behavior
6149// :159:30: note: when computing vector element at index '0'
6150// :159:30: error: use of undefined value here causes illegal behavior6144// :159:30: error: use of undefined value here causes illegal behavior
6151// :159:30: note: when computing vector element at index '0'
6152// :159:30: error: use of undefined value here causes illegal behavior6145// :159:30: error: use of undefined value here causes illegal behavior
6153// :159:30: note: when computing vector element at index '0'
6154// :159:30: error: use of undefined value here causes illegal behavior6146// :159:30: error: use of undefined value here causes illegal behavior
6155// :159:30: error: use of undefined value here causes illegal behavior6147// :159:30: error: use of undefined value here causes illegal behavior
6156// :159:30: error: use of undefined value here causes illegal behavior6148// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6158,21 +6150,13 @@ const std = @import("std");...@@ -6158,21 +6150,13 @@ const std = @import("std");
6158// :159:30: error: use of undefined value here causes illegal behavior6150// :159:30: error: use of undefined value here causes illegal behavior
6159// :159:30: error: use of undefined value here causes illegal behavior6151// :159:30: error: use of undefined value here causes illegal behavior
6160// :159:30: error: use of undefined value here causes illegal behavior6152// :159:30: error: use of undefined value here causes illegal behavior
6161// :159:30: note: when computing vector element at index '1'
6162// :159:30: error: use of undefined value here causes illegal behavior6153// :159:30: error: use of undefined value here causes illegal behavior
6163// :159:30: note: when computing vector element at index '1'
6164// :159:30: error: use of undefined value here causes illegal behavior6154// :159:30: error: use of undefined value here causes illegal behavior
6165// :159:30: note: when computing vector element at index '1'
6166// :159:30: error: use of undefined value here causes illegal behavior6155// :159:30: error: use of undefined value here causes illegal behavior
6167// :159:30: note: when computing vector element at index '1'
6168// :159:30: error: use of undefined value here causes illegal behavior6156// :159:30: error: use of undefined value here causes illegal behavior
6169// :159:30: note: when computing vector element at index '0'
6170// :159:30: error: use of undefined value here causes illegal behavior6157// :159:30: error: use of undefined value here causes illegal behavior
6171// :159:30: note: when computing vector element at index '0'
6172// :159:30: error: use of undefined value here causes illegal behavior6158// :159:30: error: use of undefined value here causes illegal behavior
6173// :159:30: note: when computing vector element at index '0'
6174// :159:30: error: use of undefined value here causes illegal behavior6159// :159:30: error: use of undefined value here causes illegal behavior
6175// :159:30: note: when computing vector element at index '0'
6176// :159:30: error: use of undefined value here causes illegal behavior6160// :159:30: error: use of undefined value here causes illegal behavior
6177// :159:30: error: use of undefined value here causes illegal behavior6161// :159:30: error: use of undefined value here causes illegal behavior
6178// :159:30: error: use of undefined value here causes illegal behavior6162// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6180,21 +6164,13 @@ const std = @import("std");...@@ -6180,21 +6164,13 @@ const std = @import("std");
6180// :159:30: error: use of undefined value here causes illegal behavior6164// :159:30: error: use of undefined value here causes illegal behavior
6181// :159:30: error: use of undefined value here causes illegal behavior6165// :159:30: error: use of undefined value here causes illegal behavior
6182// :159:30: error: use of undefined value here causes illegal behavior6166// :159:30: error: use of undefined value here causes illegal behavior
6183// :159:30: note: when computing vector element at index '1'
6184// :159:30: error: use of undefined value here causes illegal behavior6167// :159:30: error: use of undefined value here causes illegal behavior
6185// :159:30: note: when computing vector element at index '1'
6186// :159:30: error: use of undefined value here causes illegal behavior6168// :159:30: error: use of undefined value here causes illegal behavior
6187// :159:30: note: when computing vector element at index '1'
6188// :159:30: error: use of undefined value here causes illegal behavior6169// :159:30: error: use of undefined value here causes illegal behavior
6189// :159:30: note: when computing vector element at index '1'
6190// :159:30: error: use of undefined value here causes illegal behavior6170// :159:30: error: use of undefined value here causes illegal behavior
6191// :159:30: note: when computing vector element at index '0'
6192// :159:30: error: use of undefined value here causes illegal behavior6171// :159:30: error: use of undefined value here causes illegal behavior
6193// :159:30: note: when computing vector element at index '0'
6194// :159:30: error: use of undefined value here causes illegal behavior6172// :159:30: error: use of undefined value here causes illegal behavior
6195// :159:30: note: when computing vector element at index '0'
6196// :159:30: error: use of undefined value here causes illegal behavior6173// :159:30: error: use of undefined value here causes illegal behavior
6197// :159:30: note: when computing vector element at index '0'
6198// :159:30: error: use of undefined value here causes illegal behavior6174// :159:30: error: use of undefined value here causes illegal behavior
6199// :159:30: error: use of undefined value here causes illegal behavior6175// :159:30: error: use of undefined value here causes illegal behavior
6200// :159:30: error: use of undefined value here causes illegal behavior6176// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6202,21 +6178,13 @@ const std = @import("std");...@@ -6202,21 +6178,13 @@ const std = @import("std");
6202// :159:30: error: use of undefined value here causes illegal behavior6178// :159:30: error: use of undefined value here causes illegal behavior
6203// :159:30: error: use of undefined value here causes illegal behavior6179// :159:30: error: use of undefined value here causes illegal behavior
6204// :159:30: error: use of undefined value here causes illegal behavior6180// :159:30: error: use of undefined value here causes illegal behavior
6205// :159:30: note: when computing vector element at index '1'
6206// :159:30: error: use of undefined value here causes illegal behavior6181// :159:30: error: use of undefined value here causes illegal behavior
6207// :159:30: note: when computing vector element at index '1'
6208// :159:30: error: use of undefined value here causes illegal behavior6182// :159:30: error: use of undefined value here causes illegal behavior
6209// :159:30: note: when computing vector element at index '1'
6210// :159:30: error: use of undefined value here causes illegal behavior6183// :159:30: error: use of undefined value here causes illegal behavior
6211// :159:30: note: when computing vector element at index '1'
6212// :159:30: error: use of undefined value here causes illegal behavior6184// :159:30: error: use of undefined value here causes illegal behavior
6213// :159:30: note: when computing vector element at index '0'
6214// :159:30: error: use of undefined value here causes illegal behavior6185// :159:30: error: use of undefined value here causes illegal behavior
6215// :159:30: note: when computing vector element at index '0'
6216// :159:30: error: use of undefined value here causes illegal behavior6186// :159:30: error: use of undefined value here causes illegal behavior
6217// :159:30: note: when computing vector element at index '0'
6218// :159:30: error: use of undefined value here causes illegal behavior6187// :159:30: error: use of undefined value here causes illegal behavior
6219// :159:30: note: when computing vector element at index '0'
6220// :159:30: error: use of undefined value here causes illegal behavior6188// :159:30: error: use of undefined value here causes illegal behavior
6221// :159:30: error: use of undefined value here causes illegal behavior6189// :159:30: error: use of undefined value here causes illegal behavior
6222// :159:30: error: use of undefined value here causes illegal behavior6190// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6224,13 +6192,9 @@ const std = @import("std");...@@ -6224,13 +6192,9 @@ const std = @import("std");
6224// :159:30: error: use of undefined value here causes illegal behavior6192// :159:30: error: use of undefined value here causes illegal behavior
6225// :159:30: error: use of undefined value here causes illegal behavior6193// :159:30: error: use of undefined value here causes illegal behavior
6226// :159:30: error: use of undefined value here causes illegal behavior6194// :159:30: error: use of undefined value here causes illegal behavior
6227// :159:30: note: when computing vector element at index '1'
6228// :159:30: error: use of undefined value here causes illegal behavior6195// :159:30: error: use of undefined value here causes illegal behavior
6229// :159:30: note: when computing vector element at index '1'
6230// :159:30: error: use of undefined value here causes illegal behavior6196// :159:30: error: use of undefined value here causes illegal behavior
6231// :159:30: note: when computing vector element at index '1'
6232// :159:30: error: use of undefined value here causes illegal behavior6197// :159:30: error: use of undefined value here causes illegal behavior
6233// :159:30: note: when computing vector element at index '1'
6234// :159:30: error: use of undefined value here causes illegal behavior6198// :159:30: error: use of undefined value here causes illegal behavior
6235// :159:30: note: when computing vector element at index '0'6199// :159:30: note: when computing vector element at index '0'
6236// :159:30: error: use of undefined value here causes illegal behavior6200// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6240,19 +6204,21 @@ const std = @import("std");...@@ -6240,19 +6204,21 @@ const std = @import("std");
6240// :159:30: error: use of undefined value here causes illegal behavior6204// :159:30: error: use of undefined value here causes illegal behavior
6241// :159:30: note: when computing vector element at index '0'6205// :159:30: note: when computing vector element at index '0'
6242// :159:30: error: use of undefined value here causes illegal behavior6206// :159:30: error: use of undefined value here causes illegal behavior
6207// :159:30: note: when computing vector element at index '0'
6243// :159:30: error: use of undefined value here causes illegal behavior6208// :159:30: error: use of undefined value here causes illegal behavior
6209// :159:30: note: when computing vector element at index '0'
6244// :159:30: error: use of undefined value here causes illegal behavior6210// :159:30: error: use of undefined value here causes illegal behavior
6211// :159:30: note: when computing vector element at index '0'
6245// :159:30: error: use of undefined value here causes illegal behavior6212// :159:30: error: use of undefined value here causes illegal behavior
6213// :159:30: note: when computing vector element at index '0'
6246// :159:30: error: use of undefined value here causes illegal behavior6214// :159:30: error: use of undefined value here causes illegal behavior
6215// :159:30: note: when computing vector element at index '0'
6247// :159:30: error: use of undefined value here causes illegal behavior6216// :159:30: error: use of undefined value here causes illegal behavior
6217// :159:30: note: when computing vector element at index '0'
6248// :159:30: error: use of undefined value here causes illegal behavior6218// :159:30: error: use of undefined value here causes illegal behavior
6249// :159:30: note: when computing vector element at index '1'6219// :159:30: note: when computing vector element at index '0'
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'
6254// :159:30: error: use of undefined value here causes illegal behavior6220// :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'
6256// :159:30: error: use of undefined value here causes illegal behavior6222// :159:30: error: use of undefined value here causes illegal behavior
6257// :159:30: note: when computing vector element at index '0'6223// :159:30: note: when computing vector element at index '0'
6258// :159:30: error: use of undefined value here causes illegal behavior6224// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6262,19 +6228,25 @@ const std = @import("std");...@@ -6262,19 +6228,25 @@ const std = @import("std");
6262// :159:30: error: use of undefined value here causes illegal behavior6228// :159:30: error: use of undefined value here causes illegal behavior
6263// :159:30: note: when computing vector element at index '0'6229// :159:30: note: when computing vector element at index '0'
6264// :159:30: error: use of undefined value here causes illegal behavior6230// :159:30: error: use of undefined value here causes illegal behavior
6231// :159:30: note: when computing vector element at index '0'
6265// :159:30: error: use of undefined value here causes illegal behavior6232// :159:30: error: use of undefined value here causes illegal behavior
6233// :159:30: note: when computing vector element at index '0'
6266// :159:30: error: use of undefined value here causes illegal behavior6234// :159:30: error: use of undefined value here causes illegal behavior
6235// :159:30: note: when computing vector element at index '0'
6267// :159:30: error: use of undefined value here causes illegal behavior6236// :159:30: error: use of undefined value here causes illegal behavior
6237// :159:30: note: when computing vector element at index '0'
6268// :159:30: error: use of undefined value here causes illegal behavior6238// :159:30: error: use of undefined value here causes illegal behavior
6239// :159:30: note: when computing vector element at index '0'
6269// :159:30: error: use of undefined value here causes illegal behavior6240// :159:30: error: use of undefined value here causes illegal behavior
6241// :159:30: note: when computing vector element at index '0'
6270// :159:30: error: use of undefined value here causes illegal behavior6242// :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'
6272// :159:30: error: use of undefined value here causes illegal behavior6244// :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'
6274// :159:30: error: use of undefined value here causes illegal behavior6246// :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'
6276// :159:30: error: use of undefined value here causes illegal behavior6248// :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'
6278// :159:30: error: use of undefined value here causes illegal behavior6250// :159:30: error: use of undefined value here causes illegal behavior
6279// :159:30: note: when computing vector element at index '0'6251// :159:30: note: when computing vector element at index '0'
6280// :159:30: error: use of undefined value here causes illegal behavior6252// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6284,19 +6256,25 @@ const std = @import("std");...@@ -6284,19 +6256,25 @@ const std = @import("std");
6284// :159:30: error: use of undefined value here causes illegal behavior6256// :159:30: error: use of undefined value here causes illegal behavior
6285// :159:30: note: when computing vector element at index '0'6257// :159:30: note: when computing vector element at index '0'
6286// :159:30: error: use of undefined value here causes illegal behavior6258// :159:30: error: use of undefined value here causes illegal behavior
6259// :159:30: note: when computing vector element at index '0'
6287// :159:30: error: use of undefined value here causes illegal behavior6260// :159:30: error: use of undefined value here causes illegal behavior
6261// :159:30: note: when computing vector element at index '0'
6288// :159:30: error: use of undefined value here causes illegal behavior6262// :159:30: error: use of undefined value here causes illegal behavior
6263// :159:30: note: when computing vector element at index '0'
6289// :159:30: error: use of undefined value here causes illegal behavior6264// :159:30: error: use of undefined value here causes illegal behavior
6265// :159:30: note: when computing vector element at index '0'
6290// :159:30: error: use of undefined value here causes illegal behavior6266// :159:30: error: use of undefined value here causes illegal behavior
6267// :159:30: note: when computing vector element at index '0'
6291// :159:30: error: use of undefined value here causes illegal behavior6268// :159:30: error: use of undefined value here causes illegal behavior
6269// :159:30: note: when computing vector element at index '0'
6292// :159:30: error: use of undefined value here causes illegal behavior6270// :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'
6294// :159:30: error: use of undefined value here causes illegal behavior6272// :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'
6296// :159:30: error: use of undefined value here causes illegal behavior6274// :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'
6298// :159:30: error: use of undefined value here causes illegal behavior6276// :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'
6300// :159:30: error: use of undefined value here causes illegal behavior6278// :159:30: error: use of undefined value here causes illegal behavior
6301// :159:30: note: when computing vector element at index '0'6279// :159:30: note: when computing vector element at index '0'
6302// :159:30: error: use of undefined value here causes illegal behavior6280// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6306,11 +6284,17 @@ const std = @import("std");...@@ -6306,11 +6284,17 @@ const std = @import("std");
6306// :159:30: error: use of undefined value here causes illegal behavior6284// :159:30: error: use of undefined value here causes illegal behavior
6307// :159:30: note: when computing vector element at index '0'6285// :159:30: note: when computing vector element at index '0'
6308// :159:30: error: use of undefined value here causes illegal behavior6286// :159:30: error: use of undefined value here causes illegal behavior
6287// :159:30: note: when computing vector element at index '1'
6309// :159:30: error: use of undefined value here causes illegal behavior6288// :159:30: error: use of undefined value here causes illegal behavior
6289// :159:30: note: when computing vector element at index '1'
6310// :159:30: error: use of undefined value here causes illegal behavior6290// :159:30: error: use of undefined value here causes illegal behavior
6291// :159:30: note: when computing vector element at index '1'
6311// :159:30: error: use of undefined value here causes illegal behavior6292// :159:30: error: use of undefined value here causes illegal behavior
6293// :159:30: note: when computing vector element at index '1'
6312// :159:30: error: use of undefined value here causes illegal behavior6294// :159:30: error: use of undefined value here causes illegal behavior
6295// :159:30: note: when computing vector element at index '1'
6313// :159:30: error: use of undefined value here causes illegal behavior6296// :159:30: error: use of undefined value here causes illegal behavior
6297// :159:30: note: when computing vector element at index '1'
6314// :159:30: error: use of undefined value here causes illegal behavior6298// :159:30: error: use of undefined value here causes illegal behavior
6315// :159:30: note: when computing vector element at index '1'6299// :159:30: note: when computing vector element at index '1'
6316// :159:30: error: use of undefined value here causes illegal behavior6300// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6320,19 +6304,25 @@ const std = @import("std");...@@ -6320,19 +6304,25 @@ const std = @import("std");
6320// :159:30: error: use of undefined value here causes illegal behavior6304// :159:30: error: use of undefined value here causes illegal behavior
6321// :159:30: note: when computing vector element at index '1'6305// :159:30: note: when computing vector element at index '1'
6322// :159:30: error: use of undefined value here causes illegal behavior6306// :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'
6324// :159:30: error: use of undefined value here causes illegal behavior6308// :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'
6326// :159:30: error: use of undefined value here causes illegal behavior6310// :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'
6328// :159:30: error: use of undefined value here causes illegal behavior6312// :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'
6330// :159:30: error: use of undefined value here causes illegal behavior6314// :159:30: error: use of undefined value here causes illegal behavior
6315// :159:30: note: when computing vector element at index '1'
6331// :159:30: error: use of undefined value here causes illegal behavior6316// :159:30: error: use of undefined value here causes illegal behavior
6317// :159:30: note: when computing vector element at index '1'
6332// :159:30: error: use of undefined value here causes illegal behavior6318// :159:30: error: use of undefined value here causes illegal behavior
6319// :159:30: note: when computing vector element at index '1'
6333// :159:30: error: use of undefined value here causes illegal behavior6320// :159:30: error: use of undefined value here causes illegal behavior
6321// :159:30: note: when computing vector element at index '1'
6334// :159:30: error: use of undefined value here causes illegal behavior6322// :159:30: error: use of undefined value here causes illegal behavior
6323// :159:30: note: when computing vector element at index '1'
6335// :159:30: error: use of undefined value here causes illegal behavior6324// :159:30: error: use of undefined value here causes illegal behavior
6325// :159:30: note: when computing vector element at index '1'
6336// :159:30: error: use of undefined value here causes illegal behavior6326// :159:30: error: use of undefined value here causes illegal behavior
6337// :159:30: note: when computing vector element at index '1'6327// :159:30: note: when computing vector element at index '1'
6338// :159:30: error: use of undefined value here causes illegal behavior6328// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6342,19 +6332,27 @@ const std = @import("std");...@@ -6342,19 +6332,27 @@ const std = @import("std");
6342// :159:30: error: use of undefined value here causes illegal behavior6332// :159:30: error: use of undefined value here causes illegal behavior
6343// :159:30: note: when computing vector element at index '1'6333// :159:30: note: when computing vector element at index '1'
6344// :159:30: error: use of undefined value here causes illegal behavior6334// :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'
6346// :159:30: error: use of undefined value here causes illegal behavior6336// :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'
6348// :159:30: error: use of undefined value here causes illegal behavior6338// :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'
6350// :159:30: error: use of undefined value here causes illegal behavior6340// :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'
6352// :159:30: error: use of undefined value here causes illegal behavior6344// :159:30: error: use of undefined value here causes illegal behavior
6345// :159:30: note: when computing vector element at index '1'
6353// :159:30: error: use of undefined value here causes illegal behavior6346// :159:30: error: use of undefined value here causes illegal behavior
6347// :159:30: note: when computing vector element at index '1'
6354// :159:30: error: use of undefined value here causes illegal behavior6348// :159:30: error: use of undefined value here causes illegal behavior
6349// :159:30: note: when computing vector element at index '1'
6355// :159:30: error: use of undefined value here causes illegal behavior6350// :159:30: error: use of undefined value here causes illegal behavior
6351// :159:30: note: when computing vector element at index '1'
6356// :159:30: error: use of undefined value here causes illegal behavior6352// :159:30: error: use of undefined value here causes illegal behavior
6353// :159:30: note: when computing vector element at index '1'
6357// :159:30: error: use of undefined value here causes illegal behavior6354// :159:30: error: use of undefined value here causes illegal behavior
6355// :159:30: note: when computing vector element at index '1'
6358// :159:30: error: use of undefined value here causes illegal behavior6356// :159:30: error: use of undefined value here causes illegal behavior
6359// :159:30: note: when computing vector element at index '1'6357// :159:30: note: when computing vector element at index '1'
6360// :159:30: error: use of undefined value here causes illegal behavior6358// :159:30: error: use of undefined value here causes illegal behavior
...@@ -6364,13 +6362,15 @@ const std = @import("std");...@@ -6364,13 +6362,15 @@ const std = @import("std");
6364// :159:30: error: use of undefined value here causes illegal behavior6362// :159:30: error: use of undefined value here causes illegal behavior
6365// :159:30: note: when computing vector element at index '1'6363// :159:30: note: when computing vector element at index '1'
6366// :159:30: error: use of undefined value here causes illegal behavior6364// :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'
6368// :159:30: error: use of undefined value here causes illegal behavior6366// :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'
6370// :159:30: error: use of undefined value here causes illegal behavior6368// :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'
6372// :159:30: error: use of undefined value here causes illegal behavior6370// :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'
6374// :163:30: error: use of undefined value here causes illegal behavior6374// :163:30: error: use of undefined value here causes illegal behavior
6375// :163:30: error: use of undefined value here causes illegal behavior6375// :163:30: error: use of undefined value here causes illegal behavior
6376// :163:30: error: use of undefined value here causes illegal behavior6376// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6378,21 +6378,13 @@ const std = @import("std");...@@ -6378,21 +6378,13 @@ const std = @import("std");
6378// :163:30: error: use of undefined value here causes illegal behavior6378// :163:30: error: use of undefined value here causes illegal behavior
6379// :163:30: error: use of undefined value here causes illegal behavior6379// :163:30: error: use of undefined value here causes illegal behavior
6380// :163:30: error: use of undefined value here causes illegal behavior6380// :163:30: error: use of undefined value here causes illegal behavior
6381// :163:30: note: when computing vector element at index '1'
6382// :163:30: error: use of undefined value here causes illegal behavior6381// :163:30: error: use of undefined value here causes illegal behavior
6383// :163:30: note: when computing vector element at index '1'
6384// :163:30: error: use of undefined value here causes illegal behavior6382// :163:30: error: use of undefined value here causes illegal behavior
6385// :163:30: note: when computing vector element at index '1'
6386// :163:30: error: use of undefined value here causes illegal behavior6383// :163:30: error: use of undefined value here causes illegal behavior
6387// :163:30: note: when computing vector element at index '1'
6388// :163:30: error: use of undefined value here causes illegal behavior6384// :163:30: error: use of undefined value here causes illegal behavior
6389// :163:30: note: when computing vector element at index '0'
6390// :163:30: error: use of undefined value here causes illegal behavior6385// :163:30: error: use of undefined value here causes illegal behavior
6391// :163:30: note: when computing vector element at index '0'
6392// :163:30: error: use of undefined value here causes illegal behavior6386// :163:30: error: use of undefined value here causes illegal behavior
6393// :163:30: note: when computing vector element at index '0'
6394// :163:30: error: use of undefined value here causes illegal behavior6387// :163:30: error: use of undefined value here causes illegal behavior
6395// :163:30: note: when computing vector element at index '0'
6396// :163:30: error: use of undefined value here causes illegal behavior6388// :163:30: error: use of undefined value here causes illegal behavior
6397// :163:30: error: use of undefined value here causes illegal behavior6389// :163:30: error: use of undefined value here causes illegal behavior
6398// :163:30: error: use of undefined value here causes illegal behavior6390// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6400,21 +6392,13 @@ const std = @import("std");...@@ -6400,21 +6392,13 @@ const std = @import("std");
6400// :163:30: error: use of undefined value here causes illegal behavior6392// :163:30: error: use of undefined value here causes illegal behavior
6401// :163:30: error: use of undefined value here causes illegal behavior6393// :163:30: error: use of undefined value here causes illegal behavior
6402// :163:30: error: use of undefined value here causes illegal behavior6394// :163:30: error: use of undefined value here causes illegal behavior
6403// :163:30: note: when computing vector element at index '1'
6404// :163:30: error: use of undefined value here causes illegal behavior6395// :163:30: error: use of undefined value here causes illegal behavior
6405// :163:30: note: when computing vector element at index '1'
6406// :163:30: error: use of undefined value here causes illegal behavior6396// :163:30: error: use of undefined value here causes illegal behavior
6407// :163:30: note: when computing vector element at index '1'
6408// :163:30: error: use of undefined value here causes illegal behavior6397// :163:30: error: use of undefined value here causes illegal behavior
6409// :163:30: note: when computing vector element at index '1'
6410// :163:30: error: use of undefined value here causes illegal behavior6398// :163:30: error: use of undefined value here causes illegal behavior
6411// :163:30: note: when computing vector element at index '0'
6412// :163:30: error: use of undefined value here causes illegal behavior6399// :163:30: error: use of undefined value here causes illegal behavior
6413// :163:30: note: when computing vector element at index '0'
6414// :163:30: error: use of undefined value here causes illegal behavior6400// :163:30: error: use of undefined value here causes illegal behavior
6415// :163:30: note: when computing vector element at index '0'
6416// :163:30: error: use of undefined value here causes illegal behavior6401// :163:30: error: use of undefined value here causes illegal behavior
6417// :163:30: note: when computing vector element at index '0'
6418// :163:30: error: use of undefined value here causes illegal behavior6402// :163:30: error: use of undefined value here causes illegal behavior
6419// :163:30: error: use of undefined value here causes illegal behavior6403// :163:30: error: use of undefined value here causes illegal behavior
6420// :163:30: error: use of undefined value here causes illegal behavior6404// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6422,21 +6406,13 @@ const std = @import("std");...@@ -6422,21 +6406,13 @@ const std = @import("std");
6422// :163:30: error: use of undefined value here causes illegal behavior6406// :163:30: error: use of undefined value here causes illegal behavior
6423// :163:30: error: use of undefined value here causes illegal behavior6407// :163:30: error: use of undefined value here causes illegal behavior
6424// :163:30: error: use of undefined value here causes illegal behavior6408// :163:30: error: use of undefined value here causes illegal behavior
6425// :163:30: note: when computing vector element at index '1'
6426// :163:30: error: use of undefined value here causes illegal behavior6409// :163:30: error: use of undefined value here causes illegal behavior
6427// :163:30: note: when computing vector element at index '1'
6428// :163:30: error: use of undefined value here causes illegal behavior6410// :163:30: error: use of undefined value here causes illegal behavior
6429// :163:30: note: when computing vector element at index '1'
6430// :163:30: error: use of undefined value here causes illegal behavior6411// :163:30: error: use of undefined value here causes illegal behavior
6431// :163:30: note: when computing vector element at index '1'
6432// :163:30: error: use of undefined value here causes illegal behavior6412// :163:30: error: use of undefined value here causes illegal behavior
6433// :163:30: note: when computing vector element at index '0'
6434// :163:30: error: use of undefined value here causes illegal behavior6413// :163:30: error: use of undefined value here causes illegal behavior
6435// :163:30: note: when computing vector element at index '0'
6436// :163:30: error: use of undefined value here causes illegal behavior6414// :163:30: error: use of undefined value here causes illegal behavior
6437// :163:30: note: when computing vector element at index '0'
6438// :163:30: error: use of undefined value here causes illegal behavior6415// :163:30: error: use of undefined value here causes illegal behavior
6439// :163:30: note: when computing vector element at index '0'
6440// :163:30: error: use of undefined value here causes illegal behavior6416// :163:30: error: use of undefined value here causes illegal behavior
6441// :163:30: error: use of undefined value here causes illegal behavior6417// :163:30: error: use of undefined value here causes illegal behavior
6442// :163:30: error: use of undefined value here causes illegal behavior6418// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6444,21 +6420,13 @@ const std = @import("std");...@@ -6444,21 +6420,13 @@ const std = @import("std");
6444// :163:30: error: use of undefined value here causes illegal behavior6420// :163:30: error: use of undefined value here causes illegal behavior
6445// :163:30: error: use of undefined value here causes illegal behavior6421// :163:30: error: use of undefined value here causes illegal behavior
6446// :163:30: error: use of undefined value here causes illegal behavior6422// :163:30: error: use of undefined value here causes illegal behavior
6447// :163:30: note: when computing vector element at index '1'
6448// :163:30: error: use of undefined value here causes illegal behavior6423// :163:30: error: use of undefined value here causes illegal behavior
6449// :163:30: note: when computing vector element at index '1'
6450// :163:30: error: use of undefined value here causes illegal behavior6424// :163:30: error: use of undefined value here causes illegal behavior
6451// :163:30: note: when computing vector element at index '1'
6452// :163:30: error: use of undefined value here causes illegal behavior6425// :163:30: error: use of undefined value here causes illegal behavior
6453// :163:30: note: when computing vector element at index '1'
6454// :163:30: error: use of undefined value here causes illegal behavior6426// :163:30: error: use of undefined value here causes illegal behavior
6455// :163:30: note: when computing vector element at index '0'
6456// :163:30: error: use of undefined value here causes illegal behavior6427// :163:30: error: use of undefined value here causes illegal behavior
6457// :163:30: note: when computing vector element at index '0'
6458// :163:30: error: use of undefined value here causes illegal behavior6428// :163:30: error: use of undefined value here causes illegal behavior
6459// :163:30: note: when computing vector element at index '0'
6460// :163:30: error: use of undefined value here causes illegal behavior6429// :163:30: error: use of undefined value here causes illegal behavior
6461// :163:30: note: when computing vector element at index '0'
6462// :163:30: error: use of undefined value here causes illegal behavior6430// :163:30: error: use of undefined value here causes illegal behavior
6463// :163:30: error: use of undefined value here causes illegal behavior6431// :163:30: error: use of undefined value here causes illegal behavior
6464// :163:30: error: use of undefined value here causes illegal behavior6432// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6466,13 +6434,9 @@ const std = @import("std");...@@ -6466,13 +6434,9 @@ const std = @import("std");
6466// :163:30: error: use of undefined value here causes illegal behavior6434// :163:30: error: use of undefined value here causes illegal behavior
6467// :163:30: error: use of undefined value here causes illegal behavior6435// :163:30: error: use of undefined value here causes illegal behavior
6468// :163:30: error: use of undefined value here causes illegal behavior6436// :163:30: error: use of undefined value here causes illegal behavior
6469// :163:30: note: when computing vector element at index '1'
6470// :163:30: error: use of undefined value here causes illegal behavior6437// :163:30: error: use of undefined value here causes illegal behavior
6471// :163:30: note: when computing vector element at index '1'
6472// :163:30: error: use of undefined value here causes illegal behavior6438// :163:30: error: use of undefined value here causes illegal behavior
6473// :163:30: note: when computing vector element at index '1'
6474// :163:30: error: use of undefined value here causes illegal behavior6439// :163:30: error: use of undefined value here causes illegal behavior
6475// :163:30: note: when computing vector element at index '1'
6476// :163:30: error: use of undefined value here causes illegal behavior6440// :163:30: error: use of undefined value here causes illegal behavior
6477// :163:30: note: when computing vector element at index '0'6441// :163:30: note: when computing vector element at index '0'
6478// :163:30: error: use of undefined value here causes illegal behavior6442// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6482,19 +6446,21 @@ const std = @import("std");...@@ -6482,19 +6446,21 @@ const std = @import("std");
6482// :163:30: error: use of undefined value here causes illegal behavior6446// :163:30: error: use of undefined value here causes illegal behavior
6483// :163:30: note: when computing vector element at index '0'6447// :163:30: note: when computing vector element at index '0'
6484// :163:30: error: use of undefined value here causes illegal behavior6448// :163:30: error: use of undefined value here causes illegal behavior
6449// :163:30: note: when computing vector element at index '0'
6485// :163:30: error: use of undefined value here causes illegal behavior6450// :163:30: error: use of undefined value here causes illegal behavior
6451// :163:30: note: when computing vector element at index '0'
6486// :163:30: error: use of undefined value here causes illegal behavior6452// :163:30: error: use of undefined value here causes illegal behavior
6453// :163:30: note: when computing vector element at index '0'
6487// :163:30: error: use of undefined value here causes illegal behavior6454// :163:30: error: use of undefined value here causes illegal behavior
6455// :163:30: note: when computing vector element at index '0'
6488// :163:30: error: use of undefined value here causes illegal behavior6456// :163:30: error: use of undefined value here causes illegal behavior
6457// :163:30: note: when computing vector element at index '0'
6489// :163:30: error: use of undefined value here causes illegal behavior6458// :163:30: error: use of undefined value here causes illegal behavior
6459// :163:30: note: when computing vector element at index '0'
6490// :163:30: error: use of undefined value here causes illegal behavior6460// :163:30: error: use of undefined value here causes illegal behavior
6491// :163:30: note: when computing vector element at index '1'6461// :163:30: note: when computing vector element at index '0'
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'
6496// :163:30: error: use of undefined value here causes illegal behavior6462// :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'
6498// :163:30: error: use of undefined value here causes illegal behavior6464// :163:30: error: use of undefined value here causes illegal behavior
6499// :163:30: note: when computing vector element at index '0'6465// :163:30: note: when computing vector element at index '0'
6500// :163:30: error: use of undefined value here causes illegal behavior6466// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6504,19 +6470,25 @@ const std = @import("std");...@@ -6504,19 +6470,25 @@ const std = @import("std");
6504// :163:30: error: use of undefined value here causes illegal behavior6470// :163:30: error: use of undefined value here causes illegal behavior
6505// :163:30: note: when computing vector element at index '0'6471// :163:30: note: when computing vector element at index '0'
6506// :163:30: error: use of undefined value here causes illegal behavior6472// :163:30: error: use of undefined value here causes illegal behavior
6473// :163:30: note: when computing vector element at index '0'
6507// :163:30: error: use of undefined value here causes illegal behavior6474// :163:30: error: use of undefined value here causes illegal behavior
6475// :163:30: note: when computing vector element at index '0'
6508// :163:30: error: use of undefined value here causes illegal behavior6476// :163:30: error: use of undefined value here causes illegal behavior
6477// :163:30: note: when computing vector element at index '0'
6509// :163:30: error: use of undefined value here causes illegal behavior6478// :163:30: error: use of undefined value here causes illegal behavior
6479// :163:30: note: when computing vector element at index '0'
6510// :163:30: error: use of undefined value here causes illegal behavior6480// :163:30: error: use of undefined value here causes illegal behavior
6481// :163:30: note: when computing vector element at index '0'
6511// :163:30: error: use of undefined value here causes illegal behavior6482// :163:30: error: use of undefined value here causes illegal behavior
6483// :163:30: note: when computing vector element at index '0'
6512// :163:30: error: use of undefined value here causes illegal behavior6484// :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'
6514// :163:30: error: use of undefined value here causes illegal behavior6486// :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'
6516// :163:30: error: use of undefined value here causes illegal behavior6488// :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'
6518// :163:30: error: use of undefined value here causes illegal behavior6490// :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'
6520// :163:30: error: use of undefined value here causes illegal behavior6492// :163:30: error: use of undefined value here causes illegal behavior
6521// :163:30: note: when computing vector element at index '0'6493// :163:30: note: when computing vector element at index '0'
6522// :163:30: error: use of undefined value here causes illegal behavior6494// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6526,19 +6498,25 @@ const std = @import("std");...@@ -6526,19 +6498,25 @@ const std = @import("std");
6526// :163:30: error: use of undefined value here causes illegal behavior6498// :163:30: error: use of undefined value here causes illegal behavior
6527// :163:30: note: when computing vector element at index '0'6499// :163:30: note: when computing vector element at index '0'
6528// :163:30: error: use of undefined value here causes illegal behavior6500// :163:30: error: use of undefined value here causes illegal behavior
6501// :163:30: note: when computing vector element at index '0'
6529// :163:30: error: use of undefined value here causes illegal behavior6502// :163:30: error: use of undefined value here causes illegal behavior
6503// :163:30: note: when computing vector element at index '0'
6530// :163:30: error: use of undefined value here causes illegal behavior6504// :163:30: error: use of undefined value here causes illegal behavior
6505// :163:30: note: when computing vector element at index '0'
6531// :163:30: error: use of undefined value here causes illegal behavior6506// :163:30: error: use of undefined value here causes illegal behavior
6507// :163:30: note: when computing vector element at index '0'
6532// :163:30: error: use of undefined value here causes illegal behavior6508// :163:30: error: use of undefined value here causes illegal behavior
6509// :163:30: note: when computing vector element at index '0'
6533// :163:30: error: use of undefined value here causes illegal behavior6510// :163:30: error: use of undefined value here causes illegal behavior
6511// :163:30: note: when computing vector element at index '0'
6534// :163:30: error: use of undefined value here causes illegal behavior6512// :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'
6536// :163:30: error: use of undefined value here causes illegal behavior6514// :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'
6538// :163:30: error: use of undefined value here causes illegal behavior6516// :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'
6540// :163:30: error: use of undefined value here causes illegal behavior6518// :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'
6542// :163:30: error: use of undefined value here causes illegal behavior6520// :163:30: error: use of undefined value here causes illegal behavior
6543// :163:30: note: when computing vector element at index '0'6521// :163:30: note: when computing vector element at index '0'
6544// :163:30: error: use of undefined value here causes illegal behavior6522// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6548,11 +6526,19 @@ const std = @import("std");...@@ -6548,11 +6526,19 @@ const std = @import("std");
6548// :163:30: error: use of undefined value here causes illegal behavior6526// :163:30: error: use of undefined value here causes illegal behavior
6549// :163:30: note: when computing vector element at index '0'6527// :163:30: note: when computing vector element at index '0'
6550// :163:30: error: use of undefined value here causes illegal behavior6528// :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'
6551// :163:30: error: use of undefined value here causes illegal behavior6532// :163:30: error: use of undefined value here causes illegal behavior
6533// :163:30: note: when computing vector element at index '1'
6552// :163:30: error: use of undefined value here causes illegal behavior6534// :163:30: error: use of undefined value here causes illegal behavior
6535// :163:30: note: when computing vector element at index '1'
6553// :163:30: error: use of undefined value here causes illegal behavior6536// :163:30: error: use of undefined value here causes illegal behavior
6537// :163:30: note: when computing vector element at index '1'
6554// :163:30: error: use of undefined value here causes illegal behavior6538// :163:30: error: use of undefined value here causes illegal behavior
6539// :163:30: note: when computing vector element at index '1'
6555// :163:30: error: use of undefined value here causes illegal behavior6540// :163:30: error: use of undefined value here causes illegal behavior
6541// :163:30: note: when computing vector element at index '1'
6556// :163:30: error: use of undefined value here causes illegal behavior6542// :163:30: error: use of undefined value here causes illegal behavior
6557// :163:30: note: when computing vector element at index '1'6543// :163:30: note: when computing vector element at index '1'
6558// :163:30: error: use of undefined value here causes illegal behavior6544// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6562,19 +6548,27 @@ const std = @import("std");...@@ -6562,19 +6548,27 @@ const std = @import("std");
6562// :163:30: error: use of undefined value here causes illegal behavior6548// :163:30: error: use of undefined value here causes illegal behavior
6563// :163:30: note: when computing vector element at index '1'6549// :163:30: note: when computing vector element at index '1'
6564// :163:30: error: use of undefined value here causes illegal behavior6550// :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'
6566// :163:30: error: use of undefined value here causes illegal behavior6552// :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'
6568// :163:30: error: use of undefined value here causes illegal behavior6554// :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'
6570// :163:30: error: use of undefined value here causes illegal behavior6556// :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'
6572// :163:30: error: use of undefined value here causes illegal behavior6560// :163:30: error: use of undefined value here causes illegal behavior
6561// :163:30: note: when computing vector element at index '1'
6573// :163:30: error: use of undefined value here causes illegal behavior6562// :163:30: error: use of undefined value here causes illegal behavior
6563// :163:30: note: when computing vector element at index '1'
6574// :163:30: error: use of undefined value here causes illegal behavior6564// :163:30: error: use of undefined value here causes illegal behavior
6565// :163:30: note: when computing vector element at index '1'
6575// :163:30: error: use of undefined value here causes illegal behavior6566// :163:30: error: use of undefined value here causes illegal behavior
6567// :163:30: note: when computing vector element at index '1'
6576// :163:30: error: use of undefined value here causes illegal behavior6568// :163:30: error: use of undefined value here causes illegal behavior
6569// :163:30: note: when computing vector element at index '1'
6577// :163:30: error: use of undefined value here causes illegal behavior6570// :163:30: error: use of undefined value here causes illegal behavior
6571// :163:30: note: when computing vector element at index '1'
6578// :163:30: error: use of undefined value here causes illegal behavior6572// :163:30: error: use of undefined value here causes illegal behavior
6579// :163:30: note: when computing vector element at index '1'6573// :163:30: note: when computing vector element at index '1'
6580// :163:30: error: use of undefined value here causes illegal behavior6574// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6584,19 +6578,25 @@ const std = @import("std");...@@ -6584,19 +6578,25 @@ const std = @import("std");
6584// :163:30: error: use of undefined value here causes illegal behavior6578// :163:30: error: use of undefined value here causes illegal behavior
6585// :163:30: note: when computing vector element at index '1'6579// :163:30: note: when computing vector element at index '1'
6586// :163:30: error: use of undefined value here causes illegal behavior6580// :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'
6588// :163:30: error: use of undefined value here causes illegal behavior6582// :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'
6590// :163:30: error: use of undefined value here causes illegal behavior6584// :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'
6592// :163:30: error: use of undefined value here causes illegal behavior6586// :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'
6594// :163:30: error: use of undefined value here causes illegal behavior6588// :163:30: error: use of undefined value here causes illegal behavior
6589// :163:30: note: when computing vector element at index '1'
6595// :163:30: error: use of undefined value here causes illegal behavior6590// :163:30: error: use of undefined value here causes illegal behavior
6591// :163:30: note: when computing vector element at index '1'
6596// :163:30: error: use of undefined value here causes illegal behavior6592// :163:30: error: use of undefined value here causes illegal behavior
6593// :163:30: note: when computing vector element at index '1'
6597// :163:30: error: use of undefined value here causes illegal behavior6594// :163:30: error: use of undefined value here causes illegal behavior
6595// :163:30: note: when computing vector element at index '1'
6598// :163:30: error: use of undefined value here causes illegal behavior6596// :163:30: error: use of undefined value here causes illegal behavior
6597// :163:30: note: when computing vector element at index '1'
6599// :163:30: error: use of undefined value here causes illegal behavior6598// :163:30: error: use of undefined value here causes illegal behavior
6599// :163:30: note: when computing vector element at index '1'
6600// :163:30: error: use of undefined value here causes illegal behavior6600// :163:30: error: use of undefined value here causes illegal behavior
6601// :163:30: note: when computing vector element at index '1'6601// :163:30: note: when computing vector element at index '1'
6602// :163:30: error: use of undefined value here causes illegal behavior6602// :163:30: error: use of undefined value here causes illegal behavior
...@@ -6606,13 +6606,13 @@ const std = @import("std");...@@ -6606,13 +6606,13 @@ const std = @import("std");
6606// :163:30: error: use of undefined value here causes illegal behavior6606// :163:30: error: use of undefined value here causes illegal behavior
6607// :163:30: note: when computing vector element at index '1'6607// :163:30: note: when computing vector element at index '1'
6608// :163:30: error: use of undefined value here causes illegal behavior6608// :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'
6610// :163:30: error: use of undefined value here causes illegal behavior6610// :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'
6612// :163:30: error: use of undefined value here causes illegal behavior6612// :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'
6614// :163:30: error: use of undefined value here causes illegal behavior6614// :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'
6616// :167:25: error: use of undefined value here causes illegal behavior6616// :167:25: error: use of undefined value here causes illegal behavior
6617// :167:25: error: use of undefined value here causes illegal behavior6617// :167:25: error: use of undefined value here causes illegal behavior
6618// :167:25: error: use of undefined value here causes illegal behavior6618// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6620,21 +6620,13 @@ const std = @import("std");...@@ -6620,21 +6620,13 @@ const std = @import("std");
6620// :167:25: error: use of undefined value here causes illegal behavior6620// :167:25: error: use of undefined value here causes illegal behavior
6621// :167:25: error: use of undefined value here causes illegal behavior6621// :167:25: error: use of undefined value here causes illegal behavior
6622// :167:25: error: use of undefined value here causes illegal behavior6622// :167:25: error: use of undefined value here causes illegal behavior
6623// :167:25: note: when computing vector element at index '1'
6624// :167:25: error: use of undefined value here causes illegal behavior6623// :167:25: error: use of undefined value here causes illegal behavior
6625// :167:25: note: when computing vector element at index '1'
6626// :167:25: error: use of undefined value here causes illegal behavior6624// :167:25: error: use of undefined value here causes illegal behavior
6627// :167:25: note: when computing vector element at index '1'
6628// :167:25: error: use of undefined value here causes illegal behavior6625// :167:25: error: use of undefined value here causes illegal behavior
6629// :167:25: note: when computing vector element at index '1'
6630// :167:25: error: use of undefined value here causes illegal behavior6626// :167:25: error: use of undefined value here causes illegal behavior
6631// :167:25: note: when computing vector element at index '0'
6632// :167:25: error: use of undefined value here causes illegal behavior6627// :167:25: error: use of undefined value here causes illegal behavior
6633// :167:25: note: when computing vector element at index '0'
6634// :167:25: error: use of undefined value here causes illegal behavior6628// :167:25: error: use of undefined value here causes illegal behavior
6635// :167:25: note: when computing vector element at index '0'
6636// :167:25: error: use of undefined value here causes illegal behavior6629// :167:25: error: use of undefined value here causes illegal behavior
6637// :167:25: note: when computing vector element at index '0'
6638// :167:25: error: use of undefined value here causes illegal behavior6630// :167:25: error: use of undefined value here causes illegal behavior
6639// :167:25: error: use of undefined value here causes illegal behavior6631// :167:25: error: use of undefined value here causes illegal behavior
6640// :167:25: error: use of undefined value here causes illegal behavior6632// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6642,21 +6634,13 @@ const std = @import("std");...@@ -6642,21 +6634,13 @@ const std = @import("std");
6642// :167:25: error: use of undefined value here causes illegal behavior6634// :167:25: error: use of undefined value here causes illegal behavior
6643// :167:25: error: use of undefined value here causes illegal behavior6635// :167:25: error: use of undefined value here causes illegal behavior
6644// :167:25: error: use of undefined value here causes illegal behavior6636// :167:25: error: use of undefined value here causes illegal behavior
6645// :167:25: note: when computing vector element at index '1'
6646// :167:25: error: use of undefined value here causes illegal behavior6637// :167:25: error: use of undefined value here causes illegal behavior
6647// :167:25: note: when computing vector element at index '1'
6648// :167:25: error: use of undefined value here causes illegal behavior6638// :167:25: error: use of undefined value here causes illegal behavior
6649// :167:25: note: when computing vector element at index '1'
6650// :167:25: error: use of undefined value here causes illegal behavior6639// :167:25: error: use of undefined value here causes illegal behavior
6651// :167:25: note: when computing vector element at index '1'
6652// :167:25: error: use of undefined value here causes illegal behavior6640// :167:25: error: use of undefined value here causes illegal behavior
6653// :167:25: note: when computing vector element at index '0'
6654// :167:25: error: use of undefined value here causes illegal behavior6641// :167:25: error: use of undefined value here causes illegal behavior
6655// :167:25: note: when computing vector element at index '0'
6656// :167:25: error: use of undefined value here causes illegal behavior6642// :167:25: error: use of undefined value here causes illegal behavior
6657// :167:25: note: when computing vector element at index '0'
6658// :167:25: error: use of undefined value here causes illegal behavior6643// :167:25: error: use of undefined value here causes illegal behavior
6659// :167:25: note: when computing vector element at index '0'
6660// :167:25: error: use of undefined value here causes illegal behavior6644// :167:25: error: use of undefined value here causes illegal behavior
6661// :167:25: error: use of undefined value here causes illegal behavior6645// :167:25: error: use of undefined value here causes illegal behavior
6662// :167:25: error: use of undefined value here causes illegal behavior6646// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6664,21 +6648,13 @@ const std = @import("std");...@@ -6664,21 +6648,13 @@ const std = @import("std");
6664// :167:25: error: use of undefined value here causes illegal behavior6648// :167:25: error: use of undefined value here causes illegal behavior
6665// :167:25: error: use of undefined value here causes illegal behavior6649// :167:25: error: use of undefined value here causes illegal behavior
6666// :167:25: error: use of undefined value here causes illegal behavior6650// :167:25: error: use of undefined value here causes illegal behavior
6667// :167:25: note: when computing vector element at index '1'
6668// :167:25: error: use of undefined value here causes illegal behavior6651// :167:25: error: use of undefined value here causes illegal behavior
6669// :167:25: note: when computing vector element at index '1'
6670// :167:25: error: use of undefined value here causes illegal behavior6652// :167:25: error: use of undefined value here causes illegal behavior
6671// :167:25: note: when computing vector element at index '1'
6672// :167:25: error: use of undefined value here causes illegal behavior6653// :167:25: error: use of undefined value here causes illegal behavior
6673// :167:25: note: when computing vector element at index '1'
6674// :167:25: error: use of undefined value here causes illegal behavior6654// :167:25: error: use of undefined value here causes illegal behavior
6675// :167:25: note: when computing vector element at index '0'
6676// :167:25: error: use of undefined value here causes illegal behavior6655// :167:25: error: use of undefined value here causes illegal behavior
6677// :167:25: note: when computing vector element at index '0'
6678// :167:25: error: use of undefined value here causes illegal behavior6656// :167:25: error: use of undefined value here causes illegal behavior
6679// :167:25: note: when computing vector element at index '0'
6680// :167:25: error: use of undefined value here causes illegal behavior6657// :167:25: error: use of undefined value here causes illegal behavior
6681// :167:25: note: when computing vector element at index '0'
6682// :167:25: error: use of undefined value here causes illegal behavior6658// :167:25: error: use of undefined value here causes illegal behavior
6683// :167:25: error: use of undefined value here causes illegal behavior6659// :167:25: error: use of undefined value here causes illegal behavior
6684// :167:25: error: use of undefined value here causes illegal behavior6660// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6686,21 +6662,13 @@ const std = @import("std");...@@ -6686,21 +6662,13 @@ const std = @import("std");
6686// :167:25: error: use of undefined value here causes illegal behavior6662// :167:25: error: use of undefined value here causes illegal behavior
6687// :167:25: error: use of undefined value here causes illegal behavior6663// :167:25: error: use of undefined value here causes illegal behavior
6688// :167:25: error: use of undefined value here causes illegal behavior6664// :167:25: error: use of undefined value here causes illegal behavior
6689// :167:25: note: when computing vector element at index '1'
6690// :167:25: error: use of undefined value here causes illegal behavior6665// :167:25: error: use of undefined value here causes illegal behavior
6691// :167:25: note: when computing vector element at index '1'
6692// :167:25: error: use of undefined value here causes illegal behavior6666// :167:25: error: use of undefined value here causes illegal behavior
6693// :167:25: note: when computing vector element at index '1'
6694// :167:25: error: use of undefined value here causes illegal behavior6667// :167:25: error: use of undefined value here causes illegal behavior
6695// :167:25: note: when computing vector element at index '1'
6696// :167:25: error: use of undefined value here causes illegal behavior6668// :167:25: error: use of undefined value here causes illegal behavior
6697// :167:25: note: when computing vector element at index '0'
6698// :167:25: error: use of undefined value here causes illegal behavior6669// :167:25: error: use of undefined value here causes illegal behavior
6699// :167:25: note: when computing vector element at index '0'
6700// :167:25: error: use of undefined value here causes illegal behavior6670// :167:25: error: use of undefined value here causes illegal behavior
6701// :167:25: note: when computing vector element at index '0'
6702// :167:25: error: use of undefined value here causes illegal behavior6671// :167:25: error: use of undefined value here causes illegal behavior
6703// :167:25: note: when computing vector element at index '0'
6704// :167:25: error: use of undefined value here causes illegal behavior6672// :167:25: error: use of undefined value here causes illegal behavior
6705// :167:25: error: use of undefined value here causes illegal behavior6673// :167:25: error: use of undefined value here causes illegal behavior
6706// :167:25: error: use of undefined value here causes illegal behavior6674// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6708,13 +6676,9 @@ const std = @import("std");...@@ -6708,13 +6676,9 @@ const std = @import("std");
6708// :167:25: error: use of undefined value here causes illegal behavior6676// :167:25: error: use of undefined value here causes illegal behavior
6709// :167:25: error: use of undefined value here causes illegal behavior6677// :167:25: error: use of undefined value here causes illegal behavior
6710// :167:25: error: use of undefined value here causes illegal behavior6678// :167:25: error: use of undefined value here causes illegal behavior
6711// :167:25: note: when computing vector element at index '1'
6712// :167:25: error: use of undefined value here causes illegal behavior6679// :167:25: error: use of undefined value here causes illegal behavior
6713// :167:25: note: when computing vector element at index '1'
6714// :167:25: error: use of undefined value here causes illegal behavior6680// :167:25: error: use of undefined value here causes illegal behavior
6715// :167:25: note: when computing vector element at index '1'
6716// :167:25: error: use of undefined value here causes illegal behavior6681// :167:25: error: use of undefined value here causes illegal behavior
6717// :167:25: note: when computing vector element at index '1'
6718// :167:25: error: use of undefined value here causes illegal behavior6682// :167:25: error: use of undefined value here causes illegal behavior
6719// :167:25: note: when computing vector element at index '0'6683// :167:25: note: when computing vector element at index '0'
6720// :167:25: error: use of undefined value here causes illegal behavior6684// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6724,19 +6688,21 @@ const std = @import("std");...@@ -6724,19 +6688,21 @@ const std = @import("std");
6724// :167:25: error: use of undefined value here causes illegal behavior6688// :167:25: error: use of undefined value here causes illegal behavior
6725// :167:25: note: when computing vector element at index '0'6689// :167:25: note: when computing vector element at index '0'
6726// :167:25: error: use of undefined value here causes illegal behavior6690// :167:25: error: use of undefined value here causes illegal behavior
6691// :167:25: note: when computing vector element at index '0'
6727// :167:25: error: use of undefined value here causes illegal behavior6692// :167:25: error: use of undefined value here causes illegal behavior
6693// :167:25: note: when computing vector element at index '0'
6728// :167:25: error: use of undefined value here causes illegal behavior6694// :167:25: error: use of undefined value here causes illegal behavior
6695// :167:25: note: when computing vector element at index '0'
6729// :167:25: error: use of undefined value here causes illegal behavior6696// :167:25: error: use of undefined value here causes illegal behavior
6697// :167:25: note: when computing vector element at index '0'
6730// :167:25: error: use of undefined value here causes illegal behavior6698// :167:25: error: use of undefined value here causes illegal behavior
6699// :167:25: note: when computing vector element at index '0'
6731// :167:25: error: use of undefined value here causes illegal behavior6700// :167:25: error: use of undefined value here causes illegal behavior
6701// :167:25: note: when computing vector element at index '0'
6732// :167:25: error: use of undefined value here causes illegal behavior6702// :167:25: error: use of undefined value here causes illegal behavior
6733// :167:25: note: when computing vector element at index '1'6703// :167:25: note: when computing vector element at index '0'
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'
6738// :167:25: error: use of undefined value here causes illegal behavior6704// :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'
6740// :167:25: error: use of undefined value here causes illegal behavior6706// :167:25: error: use of undefined value here causes illegal behavior
6741// :167:25: note: when computing vector element at index '0'6707// :167:25: note: when computing vector element at index '0'
6742// :167:25: error: use of undefined value here causes illegal behavior6708// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6746,19 +6712,25 @@ const std = @import("std");...@@ -6746,19 +6712,25 @@ const std = @import("std");
6746// :167:25: error: use of undefined value here causes illegal behavior6712// :167:25: error: use of undefined value here causes illegal behavior
6747// :167:25: note: when computing vector element at index '0'6713// :167:25: note: when computing vector element at index '0'
6748// :167:25: error: use of undefined value here causes illegal behavior6714// :167:25: error: use of undefined value here causes illegal behavior
6715// :167:25: note: when computing vector element at index '0'
6749// :167:25: error: use of undefined value here causes illegal behavior6716// :167:25: error: use of undefined value here causes illegal behavior
6717// :167:25: note: when computing vector element at index '0'
6750// :167:25: error: use of undefined value here causes illegal behavior6718// :167:25: error: use of undefined value here causes illegal behavior
6719// :167:25: note: when computing vector element at index '0'
6751// :167:25: error: use of undefined value here causes illegal behavior6720// :167:25: error: use of undefined value here causes illegal behavior
6721// :167:25: note: when computing vector element at index '0'
6752// :167:25: error: use of undefined value here causes illegal behavior6722// :167:25: error: use of undefined value here causes illegal behavior
6723// :167:25: note: when computing vector element at index '0'
6753// :167:25: error: use of undefined value here causes illegal behavior6724// :167:25: error: use of undefined value here causes illegal behavior
6725// :167:25: note: when computing vector element at index '0'
6754// :167:25: error: use of undefined value here causes illegal behavior6726// :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'
6756// :167:25: error: use of undefined value here causes illegal behavior6728// :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'
6758// :167:25: error: use of undefined value here causes illegal behavior6730// :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'
6760// :167:25: error: use of undefined value here causes illegal behavior6732// :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'
6762// :167:25: error: use of undefined value here causes illegal behavior6734// :167:25: error: use of undefined value here causes illegal behavior
6763// :167:25: note: when computing vector element at index '0'6735// :167:25: note: when computing vector element at index '0'
6764// :167:25: error: use of undefined value here causes illegal behavior6736// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6768,19 +6740,25 @@ const std = @import("std");...@@ -6768,19 +6740,25 @@ const std = @import("std");
6768// :167:25: error: use of undefined value here causes illegal behavior6740// :167:25: error: use of undefined value here causes illegal behavior
6769// :167:25: note: when computing vector element at index '0'6741// :167:25: note: when computing vector element at index '0'
6770// :167:25: error: use of undefined value here causes illegal behavior6742// :167:25: error: use of undefined value here causes illegal behavior
6743// :167:25: note: when computing vector element at index '0'
6771// :167:25: error: use of undefined value here causes illegal behavior6744// :167:25: error: use of undefined value here causes illegal behavior
6745// :167:25: note: when computing vector element at index '0'
6772// :167:25: error: use of undefined value here causes illegal behavior6746// :167:25: error: use of undefined value here causes illegal behavior
6747// :167:25: note: when computing vector element at index '0'
6773// :167:25: error: use of undefined value here causes illegal behavior6748// :167:25: error: use of undefined value here causes illegal behavior
6749// :167:25: note: when computing vector element at index '0'
6774// :167:25: error: use of undefined value here causes illegal behavior6750// :167:25: error: use of undefined value here causes illegal behavior
6751// :167:25: note: when computing vector element at index '0'
6775// :167:25: error: use of undefined value here causes illegal behavior6752// :167:25: error: use of undefined value here causes illegal behavior
6753// :167:25: note: when computing vector element at index '0'
6776// :167:25: error: use of undefined value here causes illegal behavior6754// :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'
6778// :167:25: error: use of undefined value here causes illegal behavior6756// :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'
6780// :167:25: error: use of undefined value here causes illegal behavior6758// :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'
6782// :167:25: error: use of undefined value here causes illegal behavior6760// :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'
6784// :167:25: error: use of undefined value here causes illegal behavior6762// :167:25: error: use of undefined value here causes illegal behavior
6785// :167:25: note: when computing vector element at index '0'6763// :167:25: note: when computing vector element at index '0'
6786// :167:25: error: use of undefined value here causes illegal behavior6764// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6790,11 +6768,21 @@ const std = @import("std");...@@ -6790,11 +6768,21 @@ const std = @import("std");
6790// :167:25: error: use of undefined value here causes illegal behavior6768// :167:25: error: use of undefined value here causes illegal behavior
6791// :167:25: note: when computing vector element at index '0'6769// :167:25: note: when computing vector element at index '0'
6792// :167:25: error: use of undefined value here causes illegal behavior6770// :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'
6793// :167:25: error: use of undefined value here causes illegal behavior6776// :167:25: error: use of undefined value here causes illegal behavior
6777// :167:25: note: when computing vector element at index '1'
6794// :167:25: error: use of undefined value here causes illegal behavior6778// :167:25: error: use of undefined value here causes illegal behavior
6779// :167:25: note: when computing vector element at index '1'
6795// :167:25: error: use of undefined value here causes illegal behavior6780// :167:25: error: use of undefined value here causes illegal behavior
6781// :167:25: note: when computing vector element at index '1'
6796// :167:25: error: use of undefined value here causes illegal behavior6782// :167:25: error: use of undefined value here causes illegal behavior
6783// :167:25: note: when computing vector element at index '1'
6797// :167:25: error: use of undefined value here causes illegal behavior6784// :167:25: error: use of undefined value here causes illegal behavior
6785// :167:25: note: when computing vector element at index '1'
6798// :167:25: error: use of undefined value here causes illegal behavior6786// :167:25: error: use of undefined value here causes illegal behavior
6799// :167:25: note: when computing vector element at index '1'6787// :167:25: note: when computing vector element at index '1'
6800// :167:25: error: use of undefined value here causes illegal behavior6788// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6804,19 +6792,25 @@ const std = @import("std");...@@ -6804,19 +6792,25 @@ const std = @import("std");
6804// :167:25: error: use of undefined value here causes illegal behavior6792// :167:25: error: use of undefined value here causes illegal behavior
6805// :167:25: note: when computing vector element at index '1'6793// :167:25: note: when computing vector element at index '1'
6806// :167:25: error: use of undefined value here causes illegal behavior6794// :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'
6808// :167:25: error: use of undefined value here causes illegal behavior6796// :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'
6810// :167:25: error: use of undefined value here causes illegal behavior6798// :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'
6812// :167:25: error: use of undefined value here causes illegal behavior6800// :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'
6814// :167:25: error: use of undefined value here causes illegal behavior6802// :167:25: error: use of undefined value here causes illegal behavior
6803// :167:25: note: when computing vector element at index '1'
6815// :167:25: error: use of undefined value here causes illegal behavior6804// :167:25: error: use of undefined value here causes illegal behavior
6805// :167:25: note: when computing vector element at index '1'
6816// :167:25: error: use of undefined value here causes illegal behavior6806// :167:25: error: use of undefined value here causes illegal behavior
6807// :167:25: note: when computing vector element at index '1'
6817// :167:25: error: use of undefined value here causes illegal behavior6808// :167:25: error: use of undefined value here causes illegal behavior
6809// :167:25: note: when computing vector element at index '1'
6818// :167:25: error: use of undefined value here causes illegal behavior6810// :167:25: error: use of undefined value here causes illegal behavior
6811// :167:25: note: when computing vector element at index '1'
6819// :167:25: error: use of undefined value here causes illegal behavior6812// :167:25: error: use of undefined value here causes illegal behavior
6813// :167:25: note: when computing vector element at index '1'
6820// :167:25: error: use of undefined value here causes illegal behavior6814// :167:25: error: use of undefined value here causes illegal behavior
6821// :167:25: note: when computing vector element at index '1'6815// :167:25: note: when computing vector element at index '1'
6822// :167:25: error: use of undefined value here causes illegal behavior6816// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6826,19 +6820,25 @@ const std = @import("std");...@@ -6826,19 +6820,25 @@ const std = @import("std");
6826// :167:25: error: use of undefined value here causes illegal behavior6820// :167:25: error: use of undefined value here causes illegal behavior
6827// :167:25: note: when computing vector element at index '1'6821// :167:25: note: when computing vector element at index '1'
6828// :167:25: error: use of undefined value here causes illegal behavior6822// :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'
6830// :167:25: error: use of undefined value here causes illegal behavior6824// :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'
6832// :167:25: error: use of undefined value here causes illegal behavior6826// :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'
6834// :167:25: error: use of undefined value here causes illegal behavior6828// :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'
6836// :167:25: error: use of undefined value here causes illegal behavior6830// :167:25: error: use of undefined value here causes illegal behavior
6831// :167:25: note: when computing vector element at index '1'
6837// :167:25: error: use of undefined value here causes illegal behavior6832// :167:25: error: use of undefined value here causes illegal behavior
6833// :167:25: note: when computing vector element at index '1'
6838// :167:25: error: use of undefined value here causes illegal behavior6834// :167:25: error: use of undefined value here causes illegal behavior
6835// :167:25: note: when computing vector element at index '1'
6839// :167:25: error: use of undefined value here causes illegal behavior6836// :167:25: error: use of undefined value here causes illegal behavior
6837// :167:25: note: when computing vector element at index '1'
6840// :167:25: error: use of undefined value here causes illegal behavior6838// :167:25: error: use of undefined value here causes illegal behavior
6839// :167:25: note: when computing vector element at index '1'
6841// :167:25: error: use of undefined value here causes illegal behavior6840// :167:25: error: use of undefined value here causes illegal behavior
6841// :167:25: note: when computing vector element at index '1'
6842// :167:25: error: use of undefined value here causes illegal behavior6842// :167:25: error: use of undefined value here causes illegal behavior
6843// :167:25: note: when computing vector element at index '1'6843// :167:25: note: when computing vector element at index '1'
6844// :167:25: error: use of undefined value here causes illegal behavior6844// :167:25: error: use of undefined value here causes illegal behavior
...@@ -6848,13 +6848,13 @@ const std = @import("std");...@@ -6848,13 +6848,13 @@ const std = @import("std");
6848// :167:25: error: use of undefined value here causes illegal behavior6848// :167:25: error: use of undefined value here causes illegal behavior
6849// :167:25: note: when computing vector element at index '1'6849// :167:25: note: when computing vector element at index '1'
6850// :167:25: error: use of undefined value here causes illegal behavior6850// :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'
6852// :167:25: error: use of undefined value here causes illegal behavior6852// :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'
6854// :167:25: error: use of undefined value here causes illegal behavior6854// :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'
6856// :167:25: error: use of undefined value here causes illegal behavior6856// :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'
6858// :171:25: error: use of undefined value here causes illegal behavior6858// :171:25: error: use of undefined value here causes illegal behavior
6859// :171:25: error: use of undefined value here causes illegal behavior6859// :171:25: error: use of undefined value here causes illegal behavior
6860// :171:25: error: use of undefined value here causes illegal behavior6860// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6862,21 +6862,13 @@ const std = @import("std");...@@ -6862,21 +6862,13 @@ const std = @import("std");
6862// :171:25: error: use of undefined value here causes illegal behavior6862// :171:25: error: use of undefined value here causes illegal behavior
6863// :171:25: error: use of undefined value here causes illegal behavior6863// :171:25: error: use of undefined value here causes illegal behavior
6864// :171:25: error: use of undefined value here causes illegal behavior6864// :171:25: error: use of undefined value here causes illegal behavior
6865// :171:25: note: when computing vector element at index '1'
6866// :171:25: error: use of undefined value here causes illegal behavior6865// :171:25: error: use of undefined value here causes illegal behavior
6867// :171:25: note: when computing vector element at index '1'
6868// :171:25: error: use of undefined value here causes illegal behavior6866// :171:25: error: use of undefined value here causes illegal behavior
6869// :171:25: note: when computing vector element at index '1'
6870// :171:25: error: use of undefined value here causes illegal behavior6867// :171:25: error: use of undefined value here causes illegal behavior
6871// :171:25: note: when computing vector element at index '1'
6872// :171:25: error: use of undefined value here causes illegal behavior6868// :171:25: error: use of undefined value here causes illegal behavior
6873// :171:25: note: when computing vector element at index '0'
6874// :171:25: error: use of undefined value here causes illegal behavior6869// :171:25: error: use of undefined value here causes illegal behavior
6875// :171:25: note: when computing vector element at index '0'
6876// :171:25: error: use of undefined value here causes illegal behavior6870// :171:25: error: use of undefined value here causes illegal behavior
6877// :171:25: note: when computing vector element at index '0'
6878// :171:25: error: use of undefined value here causes illegal behavior6871// :171:25: error: use of undefined value here causes illegal behavior
6879// :171:25: note: when computing vector element at index '0'
6880// :171:25: error: use of undefined value here causes illegal behavior6872// :171:25: error: use of undefined value here causes illegal behavior
6881// :171:25: error: use of undefined value here causes illegal behavior6873// :171:25: error: use of undefined value here causes illegal behavior
6882// :171:25: error: use of undefined value here causes illegal behavior6874// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6884,21 +6876,13 @@ const std = @import("std");...@@ -6884,21 +6876,13 @@ const std = @import("std");
6884// :171:25: error: use of undefined value here causes illegal behavior6876// :171:25: error: use of undefined value here causes illegal behavior
6885// :171:25: error: use of undefined value here causes illegal behavior6877// :171:25: error: use of undefined value here causes illegal behavior
6886// :171:25: error: use of undefined value here causes illegal behavior6878// :171:25: error: use of undefined value here causes illegal behavior
6887// :171:25: note: when computing vector element at index '1'
6888// :171:25: error: use of undefined value here causes illegal behavior6879// :171:25: error: use of undefined value here causes illegal behavior
6889// :171:25: note: when computing vector element at index '1'
6890// :171:25: error: use of undefined value here causes illegal behavior6880// :171:25: error: use of undefined value here causes illegal behavior
6891// :171:25: note: when computing vector element at index '1'
6892// :171:25: error: use of undefined value here causes illegal behavior6881// :171:25: error: use of undefined value here causes illegal behavior
6893// :171:25: note: when computing vector element at index '1'
6894// :171:25: error: use of undefined value here causes illegal behavior6882// :171:25: error: use of undefined value here causes illegal behavior
6895// :171:25: note: when computing vector element at index '0'
6896// :171:25: error: use of undefined value here causes illegal behavior6883// :171:25: error: use of undefined value here causes illegal behavior
6897// :171:25: note: when computing vector element at index '0'
6898// :171:25: error: use of undefined value here causes illegal behavior6884// :171:25: error: use of undefined value here causes illegal behavior
6899// :171:25: note: when computing vector element at index '0'
6900// :171:25: error: use of undefined value here causes illegal behavior6885// :171:25: error: use of undefined value here causes illegal behavior
6901// :171:25: note: when computing vector element at index '0'
6902// :171:25: error: use of undefined value here causes illegal behavior6886// :171:25: error: use of undefined value here causes illegal behavior
6903// :171:25: error: use of undefined value here causes illegal behavior6887// :171:25: error: use of undefined value here causes illegal behavior
6904// :171:25: error: use of undefined value here causes illegal behavior6888// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6906,21 +6890,13 @@ const std = @import("std");...@@ -6906,21 +6890,13 @@ const std = @import("std");
6906// :171:25: error: use of undefined value here causes illegal behavior6890// :171:25: error: use of undefined value here causes illegal behavior
6907// :171:25: error: use of undefined value here causes illegal behavior6891// :171:25: error: use of undefined value here causes illegal behavior
6908// :171:25: error: use of undefined value here causes illegal behavior6892// :171:25: error: use of undefined value here causes illegal behavior
6909// :171:25: note: when computing vector element at index '1'
6910// :171:25: error: use of undefined value here causes illegal behavior6893// :171:25: error: use of undefined value here causes illegal behavior
6911// :171:25: note: when computing vector element at index '1'
6912// :171:25: error: use of undefined value here causes illegal behavior6894// :171:25: error: use of undefined value here causes illegal behavior
6913// :171:25: note: when computing vector element at index '1'
6914// :171:25: error: use of undefined value here causes illegal behavior6895// :171:25: error: use of undefined value here causes illegal behavior
6915// :171:25: note: when computing vector element at index '1'
6916// :171:25: error: use of undefined value here causes illegal behavior6896// :171:25: error: use of undefined value here causes illegal behavior
6917// :171:25: note: when computing vector element at index '0'
6918// :171:25: error: use of undefined value here causes illegal behavior6897// :171:25: error: use of undefined value here causes illegal behavior
6919// :171:25: note: when computing vector element at index '0'
6920// :171:25: error: use of undefined value here causes illegal behavior6898// :171:25: error: use of undefined value here causes illegal behavior
6921// :171:25: note: when computing vector element at index '0'
6922// :171:25: error: use of undefined value here causes illegal behavior6899// :171:25: error: use of undefined value here causes illegal behavior
6923// :171:25: note: when computing vector element at index '0'
6924// :171:25: error: use of undefined value here causes illegal behavior6900// :171:25: error: use of undefined value here causes illegal behavior
6925// :171:25: error: use of undefined value here causes illegal behavior6901// :171:25: error: use of undefined value here causes illegal behavior
6926// :171:25: error: use of undefined value here causes illegal behavior6902// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6928,21 +6904,13 @@ const std = @import("std");...@@ -6928,21 +6904,13 @@ const std = @import("std");
6928// :171:25: error: use of undefined value here causes illegal behavior6904// :171:25: error: use of undefined value here causes illegal behavior
6929// :171:25: error: use of undefined value here causes illegal behavior6905// :171:25: error: use of undefined value here causes illegal behavior
6930// :171:25: error: use of undefined value here causes illegal behavior6906// :171:25: error: use of undefined value here causes illegal behavior
6931// :171:25: note: when computing vector element at index '1'
6932// :171:25: error: use of undefined value here causes illegal behavior6907// :171:25: error: use of undefined value here causes illegal behavior
6933// :171:25: note: when computing vector element at index '1'
6934// :171:25: error: use of undefined value here causes illegal behavior6908// :171:25: error: use of undefined value here causes illegal behavior
6935// :171:25: note: when computing vector element at index '1'
6936// :171:25: error: use of undefined value here causes illegal behavior6909// :171:25: error: use of undefined value here causes illegal behavior
6937// :171:25: note: when computing vector element at index '1'
6938// :171:25: error: use of undefined value here causes illegal behavior6910// :171:25: error: use of undefined value here causes illegal behavior
6939// :171:25: note: when computing vector element at index '0'
6940// :171:25: error: use of undefined value here causes illegal behavior6911// :171:25: error: use of undefined value here causes illegal behavior
6941// :171:25: note: when computing vector element at index '0'
6942// :171:25: error: use of undefined value here causes illegal behavior6912// :171:25: error: use of undefined value here causes illegal behavior
6943// :171:25: note: when computing vector element at index '0'
6944// :171:25: error: use of undefined value here causes illegal behavior6913// :171:25: error: use of undefined value here causes illegal behavior
6945// :171:25: note: when computing vector element at index '0'
6946// :171:25: error: use of undefined value here causes illegal behavior6914// :171:25: error: use of undefined value here causes illegal behavior
6947// :171:25: error: use of undefined value here causes illegal behavior6915// :171:25: error: use of undefined value here causes illegal behavior
6948// :171:25: error: use of undefined value here causes illegal behavior6916// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6950,13 +6918,9 @@ const std = @import("std");...@@ -6950,13 +6918,9 @@ const std = @import("std");
6950// :171:25: error: use of undefined value here causes illegal behavior6918// :171:25: error: use of undefined value here causes illegal behavior
6951// :171:25: error: use of undefined value here causes illegal behavior6919// :171:25: error: use of undefined value here causes illegal behavior
6952// :171:25: error: use of undefined value here causes illegal behavior6920// :171:25: error: use of undefined value here causes illegal behavior
6953// :171:25: note: when computing vector element at index '1'
6954// :171:25: error: use of undefined value here causes illegal behavior6921// :171:25: error: use of undefined value here causes illegal behavior
6955// :171:25: note: when computing vector element at index '1'
6956// :171:25: error: use of undefined value here causes illegal behavior6922// :171:25: error: use of undefined value here causes illegal behavior
6957// :171:25: note: when computing vector element at index '1'
6958// :171:25: error: use of undefined value here causes illegal behavior6923// :171:25: error: use of undefined value here causes illegal behavior
6959// :171:25: note: when computing vector element at index '1'
6960// :171:25: error: use of undefined value here causes illegal behavior6924// :171:25: error: use of undefined value here causes illegal behavior
6961// :171:25: note: when computing vector element at index '0'6925// :171:25: note: when computing vector element at index '0'
6962// :171:25: error: use of undefined value here causes illegal behavior6926// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6966,19 +6930,21 @@ const std = @import("std");...@@ -6966,19 +6930,21 @@ const std = @import("std");
6966// :171:25: error: use of undefined value here causes illegal behavior6930// :171:25: error: use of undefined value here causes illegal behavior
6967// :171:25: note: when computing vector element at index '0'6931// :171:25: note: when computing vector element at index '0'
6968// :171:25: error: use of undefined value here causes illegal behavior6932// :171:25: error: use of undefined value here causes illegal behavior
6933// :171:25: note: when computing vector element at index '0'
6969// :171:25: error: use of undefined value here causes illegal behavior6934// :171:25: error: use of undefined value here causes illegal behavior
6935// :171:25: note: when computing vector element at index '0'
6970// :171:25: error: use of undefined value here causes illegal behavior6936// :171:25: error: use of undefined value here causes illegal behavior
6937// :171:25: note: when computing vector element at index '0'
6971// :171:25: error: use of undefined value here causes illegal behavior6938// :171:25: error: use of undefined value here causes illegal behavior
6939// :171:25: note: when computing vector element at index '0'
6972// :171:25: error: use of undefined value here causes illegal behavior6940// :171:25: error: use of undefined value here causes illegal behavior
6941// :171:25: note: when computing vector element at index '0'
6973// :171:25: error: use of undefined value here causes illegal behavior6942// :171:25: error: use of undefined value here causes illegal behavior
6943// :171:25: note: when computing vector element at index '0'
6974// :171:25: error: use of undefined value here causes illegal behavior6944// :171:25: error: use of undefined value here causes illegal behavior
6975// :171:25: note: when computing vector element at index '1'6945// :171:25: note: when computing vector element at index '0'
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'
6980// :171:25: error: use of undefined value here causes illegal behavior6946// :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'
6982// :171:25: error: use of undefined value here causes illegal behavior6948// :171:25: error: use of undefined value here causes illegal behavior
6983// :171:25: note: when computing vector element at index '0'6949// :171:25: note: when computing vector element at index '0'
6984// :171:25: error: use of undefined value here causes illegal behavior6950// :171:25: error: use of undefined value here causes illegal behavior
...@@ -6988,19 +6954,25 @@ const std = @import("std");...@@ -6988,19 +6954,25 @@ const std = @import("std");
6988// :171:25: error: use of undefined value here causes illegal behavior6954// :171:25: error: use of undefined value here causes illegal behavior
6989// :171:25: note: when computing vector element at index '0'6955// :171:25: note: when computing vector element at index '0'
6990// :171:25: error: use of undefined value here causes illegal behavior6956// :171:25: error: use of undefined value here causes illegal behavior
6957// :171:25: note: when computing vector element at index '0'
6991// :171:25: error: use of undefined value here causes illegal behavior6958// :171:25: error: use of undefined value here causes illegal behavior
6959// :171:25: note: when computing vector element at index '0'
6992// :171:25: error: use of undefined value here causes illegal behavior6960// :171:25: error: use of undefined value here causes illegal behavior
6961// :171:25: note: when computing vector element at index '0'
6993// :171:25: error: use of undefined value here causes illegal behavior6962// :171:25: error: use of undefined value here causes illegal behavior
6963// :171:25: note: when computing vector element at index '0'
6994// :171:25: error: use of undefined value here causes illegal behavior6964// :171:25: error: use of undefined value here causes illegal behavior
6965// :171:25: note: when computing vector element at index '0'
6995// :171:25: error: use of undefined value here causes illegal behavior6966// :171:25: error: use of undefined value here causes illegal behavior
6967// :171:25: note: when computing vector element at index '0'
6996// :171:25: error: use of undefined value here causes illegal behavior6968// :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'
6998// :171:25: error: use of undefined value here causes illegal behavior6970// :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'
7000// :171:25: error: use of undefined value here causes illegal behavior6972// :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'
7002// :171:25: error: use of undefined value here causes illegal behavior6974// :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'
7004// :171:25: error: use of undefined value here causes illegal behavior6976// :171:25: error: use of undefined value here causes illegal behavior
7005// :171:25: note: when computing vector element at index '0'6977// :171:25: note: when computing vector element at index '0'
7006// :171:25: error: use of undefined value here causes illegal behavior6978// :171:25: error: use of undefined value here causes illegal behavior
...@@ -7010,19 +6982,25 @@ const std = @import("std");...@@ -7010,19 +6982,25 @@ const std = @import("std");
7010// :171:25: error: use of undefined value here causes illegal behavior6982// :171:25: error: use of undefined value here causes illegal behavior
7011// :171:25: note: when computing vector element at index '0'6983// :171:25: note: when computing vector element at index '0'
7012// :171:25: error: use of undefined value here causes illegal behavior6984// :171:25: error: use of undefined value here causes illegal behavior
6985// :171:25: note: when computing vector element at index '0'
7013// :171:25: error: use of undefined value here causes illegal behavior6986// :171:25: error: use of undefined value here causes illegal behavior
6987// :171:25: note: when computing vector element at index '0'
7014// :171:25: error: use of undefined value here causes illegal behavior6988// :171:25: error: use of undefined value here causes illegal behavior
6989// :171:25: note: when computing vector element at index '0'
7015// :171:25: error: use of undefined value here causes illegal behavior6990// :171:25: error: use of undefined value here causes illegal behavior
6991// :171:25: note: when computing vector element at index '0'
7016// :171:25: error: use of undefined value here causes illegal behavior6992// :171:25: error: use of undefined value here causes illegal behavior
6993// :171:25: note: when computing vector element at index '0'
7017// :171:25: error: use of undefined value here causes illegal behavior6994// :171:25: error: use of undefined value here causes illegal behavior
6995// :171:25: note: when computing vector element at index '0'
7018// :171:25: error: use of undefined value here causes illegal behavior6996// :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'
7020// :171:25: error: use of undefined value here causes illegal behavior6998// :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'
7022// :171:25: error: use of undefined value here causes illegal behavior7000// :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'
7024// :171:25: error: use of undefined value here causes illegal behavior7002// :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'
7026// :171:25: error: use of undefined value here causes illegal behavior7004// :171:25: error: use of undefined value here causes illegal behavior
7027// :171:25: note: when computing vector element at index '0'7005// :171:25: note: when computing vector element at index '0'
7028// :171:25: error: use of undefined value here causes illegal behavior7006// :171:25: error: use of undefined value here causes illegal behavior
...@@ -7032,11 +7010,17 @@ const std = @import("std");...@@ -7032,11 +7010,17 @@ const std = @import("std");
7032// :171:25: error: use of undefined value here causes illegal behavior7010// :171:25: error: use of undefined value here causes illegal behavior
7033// :171:25: note: when computing vector element at index '0'7011// :171:25: note: when computing vector element at index '0'
7034// :171:25: error: use of undefined value here causes illegal behavior7012// :171:25: error: use of undefined value here causes illegal behavior
7013// :171:25: note: when computing vector element at index '1'
7035// :171:25: error: use of undefined value here causes illegal behavior7014// :171:25: error: use of undefined value here causes illegal behavior
7015// :171:25: note: when computing vector element at index '1'
7036// :171:25: error: use of undefined value here causes illegal behavior7016// :171:25: error: use of undefined value here causes illegal behavior
7017// :171:25: note: when computing vector element at index '1'
7037// :171:25: error: use of undefined value here causes illegal behavior7018// :171:25: error: use of undefined value here causes illegal behavior
7019// :171:25: note: when computing vector element at index '1'
7038// :171:25: error: use of undefined value here causes illegal behavior7020// :171:25: error: use of undefined value here causes illegal behavior
7021// :171:25: note: when computing vector element at index '1'
7039// :171:25: error: use of undefined value here causes illegal behavior7022// :171:25: error: use of undefined value here causes illegal behavior
7023// :171:25: note: when computing vector element at index '1'
7040// :171:25: error: use of undefined value here causes illegal behavior7024// :171:25: error: use of undefined value here causes illegal behavior
7041// :171:25: note: when computing vector element at index '1'7025// :171:25: note: when computing vector element at index '1'
7042// :171:25: error: use of undefined value here causes illegal behavior7026// :171:25: error: use of undefined value here causes illegal behavior
...@@ -7046,19 +7030,25 @@ const std = @import("std");...@@ -7046,19 +7030,25 @@ const std = @import("std");
7046// :171:25: error: use of undefined value here causes illegal behavior7030// :171:25: error: use of undefined value here causes illegal behavior
7047// :171:25: note: when computing vector element at index '1'7031// :171:25: note: when computing vector element at index '1'
7048// :171:25: error: use of undefined value here causes illegal behavior7032// :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'
7050// :171:25: error: use of undefined value here causes illegal behavior7034// :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'
7052// :171:25: error: use of undefined value here causes illegal behavior7036// :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'
7054// :171:25: error: use of undefined value here causes illegal behavior7038// :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'
7056// :171:25: error: use of undefined value here causes illegal behavior7040// :171:25: error: use of undefined value here causes illegal behavior
7041// :171:25: note: when computing vector element at index '1'
7057// :171:25: error: use of undefined value here causes illegal behavior7042// :171:25: error: use of undefined value here causes illegal behavior
7043// :171:25: note: when computing vector element at index '1'
7058// :171:25: error: use of undefined value here causes illegal behavior7044// :171:25: error: use of undefined value here causes illegal behavior
7045// :171:25: note: when computing vector element at index '1'
7059// :171:25: error: use of undefined value here causes illegal behavior7046// :171:25: error: use of undefined value here causes illegal behavior
7047// :171:25: note: when computing vector element at index '1'
7060// :171:25: error: use of undefined value here causes illegal behavior7048// :171:25: error: use of undefined value here causes illegal behavior
7049// :171:25: note: when computing vector element at index '1'
7061// :171:25: error: use of undefined value here causes illegal behavior7050// :171:25: error: use of undefined value here causes illegal behavior
7051// :171:25: note: when computing vector element at index '1'
7062// :171:25: error: use of undefined value here causes illegal behavior7052// :171:25: error: use of undefined value here causes illegal behavior
7063// :171:25: note: when computing vector element at index '1'7053// :171:25: note: when computing vector element at index '1'
7064// :171:25: error: use of undefined value here causes illegal behavior7054// :171:25: error: use of undefined value here causes illegal behavior
...@@ -7068,19 +7058,25 @@ const std = @import("std");...@@ -7068,19 +7058,25 @@ const std = @import("std");
7068// :171:25: error: use of undefined value here causes illegal behavior7058// :171:25: error: use of undefined value here causes illegal behavior
7069// :171:25: note: when computing vector element at index '1'7059// :171:25: note: when computing vector element at index '1'
7070// :171:25: error: use of undefined value here causes illegal behavior7060// :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'
7072// :171:25: error: use of undefined value here causes illegal behavior7062// :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'
7074// :171:25: error: use of undefined value here causes illegal behavior7064// :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'
7076// :171:25: error: use of undefined value here causes illegal behavior7066// :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'
7078// :171:25: error: use of undefined value here causes illegal behavior7068// :171:25: error: use of undefined value here causes illegal behavior
7069// :171:25: note: when computing vector element at index '1'
7079// :171:25: error: use of undefined value here causes illegal behavior7070// :171:25: error: use of undefined value here causes illegal behavior
7071// :171:25: note: when computing vector element at index '1'
7080// :171:25: error: use of undefined value here causes illegal behavior7072// :171:25: error: use of undefined value here causes illegal behavior
7073// :171:25: note: when computing vector element at index '1'
7081// :171:25: error: use of undefined value here causes illegal behavior7074// :171:25: error: use of undefined value here causes illegal behavior
7075// :171:25: note: when computing vector element at index '1'
7082// :171:25: error: use of undefined value here causes illegal behavior7076// :171:25: error: use of undefined value here causes illegal behavior
7077// :171:25: note: when computing vector element at index '1'
7083// :171:25: error: use of undefined value here causes illegal behavior7078// :171:25: error: use of undefined value here causes illegal behavior
7079// :171:25: note: when computing vector element at index '1'
7084// :171:25: error: use of undefined value here causes illegal behavior7080// :171:25: error: use of undefined value here causes illegal behavior
7085// :171:25: note: when computing vector element at index '1'7081// :171:25: note: when computing vector element at index '1'
7086// :171:25: error: use of undefined value here causes illegal behavior7082// :171:25: error: use of undefined value here causes illegal behavior
...@@ -7090,37 +7086,33 @@ const std = @import("std");...@@ -7090,37 +7086,33 @@ const std = @import("std");
7090// :171:25: error: use of undefined value here causes illegal behavior7086// :171:25: error: use of undefined value here causes illegal behavior
7091// :171:25: note: when computing vector element at index '1'7087// :171:25: note: when computing vector element at index '1'
7092// :171:25: error: use of undefined value here causes illegal behavior7088// :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'
7094// :171:25: error: use of undefined value here causes illegal behavior7090// :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'
7096// :171:25: error: use of undefined value here causes illegal behavior7092// :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'
7098// :171:25: error: use of undefined value here causes illegal behavior7094// :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'
7100// :177:17: error: use of undefined value here causes illegal behavior7100// :177:17: error: use of undefined value here causes illegal behavior
7101// :177:17: error: use of undefined value here causes illegal behavior7101// :177:17: error: use of undefined value here causes illegal behavior
7102// :177:17: error: use of undefined value here causes illegal behavior7102// :177:17: error: use of undefined value here causes illegal behavior
7103// :177:17: note: when computing vector element at index '0'
7104// :177:17: error: use of undefined value here causes illegal behavior7103// :177:17: error: use of undefined value here causes illegal behavior
7105// :177:17: note: when computing vector element at index '0'
7106// :177:17: error: use of undefined value here causes illegal behavior7104// :177:17: error: use of undefined value here causes illegal behavior
7107// :177:17: note: when computing vector element at index '0'
7108// :177:17: error: use of undefined value here causes illegal behavior7105// :177:17: error: use of undefined value here causes illegal behavior
7109// :177:17: note: when computing vector element at index '0'
7110// :177:17: error: use of undefined value here causes illegal behavior7106// :177:17: error: use of undefined value here causes illegal behavior
7111// :177:17: note: when computing vector element at index '1'
7112// :177:17: error: use of undefined value here causes illegal behavior7107// :177:17: error: use of undefined value here causes illegal behavior
7113// :177:17: note: when computing vector element at index '1'
7114// :177:17: error: use of undefined value here causes illegal behavior7108// :177:17: error: use of undefined value here causes illegal behavior
7115// :177:17: note: when computing vector element at index '0'
7116// :177:17: error: use of undefined value here causes illegal behavior7109// :177:17: error: use of undefined value here causes illegal behavior
7117// :177:17: note: when computing vector element at index '0'
7118// :177:17: error: use of undefined value here causes illegal behavior7110// :177:17: error: use of undefined value here causes illegal behavior
7119// :177:17: note: when computing vector element at index '0'
7120// :177:17: error: use of undefined value here causes illegal behavior7111// :177:17: error: use of undefined value here causes illegal behavior
7121// :177:17: note: when computing vector element at index '0'
7122// :177:17: error: use of undefined value here causes illegal behavior7112// :177:17: error: use of undefined value here causes illegal behavior
7113// :177:17: note: when computing vector element at index '0'
7123// :177:17: error: use of undefined value here causes illegal behavior7114// :177:17: error: use of undefined value here causes illegal behavior
7115// :177:17: note: when computing vector element at index '0'
7124// :177:17: error: use of undefined value here causes illegal behavior7116// :177:17: error: use of undefined value here causes illegal behavior
7125// :177:17: note: when computing vector element at index '0'7117// :177:17: note: when computing vector element at index '0'
7126// :177:17: error: use of undefined value here causes illegal behavior7118// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7130,9 +7122,9 @@ const std = @import("std");...@@ -7130,9 +7122,9 @@ const std = @import("std");
7130// :177:17: error: use of undefined value here causes illegal behavior7122// :177:17: error: use of undefined value here causes illegal behavior
7131// :177:17: note: when computing vector element at index '0'7123// :177:17: note: when computing vector element at index '0'
7132// :177:17: error: use of undefined value here causes illegal behavior7124// :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'
7134// :177:17: error: use of undefined value here causes illegal behavior7126// :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'
7136// :177:17: error: use of undefined value here causes illegal behavior7128// :177:17: error: use of undefined value here causes illegal behavior
7137// :177:17: note: when computing vector element at index '0'7129// :177:17: note: when computing vector element at index '0'
7138// :177:17: error: use of undefined value here causes illegal behavior7130// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7142,7 +7134,9 @@ const std = @import("std");...@@ -7142,7 +7134,9 @@ const std = @import("std");
7142// :177:17: error: use of undefined value here causes illegal behavior7134// :177:17: error: use of undefined value here causes illegal behavior
7143// :177:17: note: when computing vector element at index '0'7135// :177:17: note: when computing vector element at index '0'
7144// :177:17: error: use of undefined value here causes illegal behavior7136// :177:17: error: use of undefined value here causes illegal behavior
7137// :177:17: note: when computing vector element at index '0'
7145// :177:17: error: use of undefined value here causes illegal behavior7138// :177:17: error: use of undefined value here causes illegal behavior
7139// :177:17: note: when computing vector element at index '0'
7146// :177:17: error: use of undefined value here causes illegal behavior7140// :177:17: error: use of undefined value here causes illegal behavior
7147// :177:17: note: when computing vector element at index '0'7141// :177:17: note: when computing vector element at index '0'
7148// :177:17: error: use of undefined value here causes illegal behavior7142// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7152,9 +7146,9 @@ const std = @import("std");...@@ -7152,9 +7146,9 @@ const std = @import("std");
7152// :177:17: error: use of undefined value here causes illegal behavior7146// :177:17: error: use of undefined value here causes illegal behavior
7153// :177:17: note: when computing vector element at index '0'7147// :177:17: note: when computing vector element at index '0'
7154// :177:17: error: use of undefined value here causes illegal behavior7148// :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'
7156// :177:17: error: use of undefined value here causes illegal behavior7150// :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'
7158// :177:17: error: use of undefined value here causes illegal behavior7152// :177:17: error: use of undefined value here causes illegal behavior
7159// :177:17: note: when computing vector element at index '0'7153// :177:17: note: when computing vector element at index '0'
7160// :177:17: error: use of undefined value here causes illegal behavior7154// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7164,7 +7158,9 @@ const std = @import("std");...@@ -7164,7 +7158,9 @@ const std = @import("std");
7164// :177:17: error: use of undefined value here causes illegal behavior7158// :177:17: error: use of undefined value here causes illegal behavior
7165// :177:17: note: when computing vector element at index '0'7159// :177:17: note: when computing vector element at index '0'
7166// :177:17: error: use of undefined value here causes illegal behavior7160// :177:17: error: use of undefined value here causes illegal behavior
7161// :177:17: note: when computing vector element at index '0'
7167// :177:17: error: use of undefined value here causes illegal behavior7162// :177:17: error: use of undefined value here causes illegal behavior
7163// :177:17: note: when computing vector element at index '0'
7168// :177:17: error: use of undefined value here causes illegal behavior7164// :177:17: error: use of undefined value here causes illegal behavior
7169// :177:17: note: when computing vector element at index '0'7165// :177:17: note: when computing vector element at index '0'
7170// :177:17: error: use of undefined value here causes illegal behavior7166// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7174,9 +7170,9 @@ const std = @import("std");...@@ -7174,9 +7170,9 @@ const std = @import("std");
7174// :177:17: error: use of undefined value here causes illegal behavior7170// :177:17: error: use of undefined value here causes illegal behavior
7175// :177:17: note: when computing vector element at index '0'7171// :177:17: note: when computing vector element at index '0'
7176// :177:17: error: use of undefined value here causes illegal behavior7172// :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'
7178// :177:17: error: use of undefined value here causes illegal behavior7174// :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'
7180// :177:17: error: use of undefined value here causes illegal behavior7176// :177:17: error: use of undefined value here causes illegal behavior
7181// :177:17: note: when computing vector element at index '0'7177// :177:17: note: when computing vector element at index '0'
7182// :177:17: error: use of undefined value here causes illegal behavior7178// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7186,7 +7182,9 @@ const std = @import("std");...@@ -7186,7 +7182,9 @@ const std = @import("std");
7186// :177:17: error: use of undefined value here causes illegal behavior7182// :177:17: error: use of undefined value here causes illegal behavior
7187// :177:17: note: when computing vector element at index '0'7183// :177:17: note: when computing vector element at index '0'
7188// :177:17: error: use of undefined value here causes illegal behavior7184// :177:17: error: use of undefined value here causes illegal behavior
7185// :177:17: note: when computing vector element at index '0'
7189// :177:17: error: use of undefined value here causes illegal behavior7186// :177:17: error: use of undefined value here causes illegal behavior
7187// :177:17: note: when computing vector element at index '0'
7190// :177:17: error: use of undefined value here causes illegal behavior7188// :177:17: error: use of undefined value here causes illegal behavior
7191// :177:17: note: when computing vector element at index '0'7189// :177:17: note: when computing vector element at index '0'
7192// :177:17: error: use of undefined value here causes illegal behavior7190// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7196,9 +7194,9 @@ const std = @import("std");...@@ -7196,9 +7194,9 @@ const std = @import("std");
7196// :177:17: error: use of undefined value here causes illegal behavior7194// :177:17: error: use of undefined value here causes illegal behavior
7197// :177:17: note: when computing vector element at index '0'7195// :177:17: note: when computing vector element at index '0'
7198// :177:17: error: use of undefined value here causes illegal behavior7196// :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'
7200// :177:17: error: use of undefined value here causes illegal behavior7198// :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'
7202// :177:17: error: use of undefined value here causes illegal behavior7200// :177:17: error: use of undefined value here causes illegal behavior
7203// :177:17: note: when computing vector element at index '0'7201// :177:17: note: when computing vector element at index '0'
7204// :177:17: error: use of undefined value here causes illegal behavior7202// :177:17: error: use of undefined value here causes illegal behavior
...@@ -7208,27 +7206,29 @@ const std = @import("std");...@@ -7208,27 +7206,29 @@ const std = @import("std");
7208// :177:17: error: use of undefined value here causes illegal behavior7206// :177:17: error: use of undefined value here causes illegal behavior
7209// :177:17: note: when computing vector element at index '0'7207// :177:17: note: when computing vector element at index '0'
7210// :177:17: error: use of undefined value here causes illegal behavior7208// :177:17: error: use of undefined value here causes illegal behavior
7209// :177:17: note: when computing vector element at index '1'
7211// :177:17: error: use of undefined value here causes illegal behavior7210// :177:17: error: use of undefined value here causes illegal behavior
7211// :177:17: note: when computing vector element at index '1'
7212// :177:17: error: use of undefined value here causes illegal behavior7212// :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'
7214// :177:17: error: use of undefined value here causes illegal behavior7214// :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'
7216// :177:17: error: use of undefined value here causes illegal behavior7216// :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'
7218// :177:17: error: use of undefined value here causes illegal behavior7218// :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'
7220// :177:17: error: use of undefined value here causes illegal behavior7220// :177:17: error: use of undefined value here causes illegal behavior
7221// :177:17: note: when computing vector element at index '1'7221// :177:17: note: when computing vector element at index '1'
7222// :177:17: error: use of undefined value here causes illegal behavior7222// :177:17: error: use of undefined value here causes illegal behavior
7223// :177:17: note: when computing vector element at index '1'7223// :177:17: note: when computing vector element at index '1'
7224// :177:17: error: use of undefined value here causes illegal behavior7224// :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'
7226// :177:17: error: use of undefined value here causes illegal behavior7226// :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'
7228// :177:17: error: use of undefined value here causes illegal behavior7228// :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'
7230// :177:17: error: use of undefined value here causes illegal behavior7230// :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'
7232// :177:21: error: use of undefined value here causes illegal behavior7232// :177:21: error: use of undefined value here causes illegal behavior
7233// :177:21: note: when computing vector element at index '0'7233// :177:21: note: when computing vector element at index '0'
7234// :177:21: error: use of undefined value here causes illegal behavior7234// :177:21: error: use of undefined value here causes illegal behavior
...@@ -7256,27 +7256,19 @@ const std = @import("std");...@@ -7256,27 +7256,19 @@ const std = @import("std");
7256// :180:17: error: use of undefined value here causes illegal behavior7256// :180:17: error: use of undefined value here causes illegal behavior
7257// :180:17: error: use of undefined value here causes illegal behavior7257// :180:17: error: use of undefined value here causes illegal behavior
7258// :180:17: error: use of undefined value here causes illegal behavior7258// :180:17: error: use of undefined value here causes illegal behavior
7259// :180:17: note: when computing vector element at index '0'
7260// :180:17: error: use of undefined value here causes illegal behavior7259// :180:17: error: use of undefined value here causes illegal behavior
7261// :180:17: note: when computing vector element at index '0'
7262// :180:17: error: use of undefined value here causes illegal behavior7260// :180:17: error: use of undefined value here causes illegal behavior
7263// :180:17: note: when computing vector element at index '0'
7264// :180:17: error: use of undefined value here causes illegal behavior7261// :180:17: error: use of undefined value here causes illegal behavior
7265// :180:17: note: when computing vector element at index '0'
7266// :180:17: error: use of undefined value here causes illegal behavior7262// :180:17: error: use of undefined value here causes illegal behavior
7267// :180:17: note: when computing vector element at index '1'
7268// :180:17: error: use of undefined value here causes illegal behavior7263// :180:17: error: use of undefined value here causes illegal behavior
7269// :180:17: note: when computing vector element at index '1'
7270// :180:17: error: use of undefined value here causes illegal behavior7264// :180:17: error: use of undefined value here causes illegal behavior
7271// :180:17: note: when computing vector element at index '0'
7272// :180:17: error: use of undefined value here causes illegal behavior7265// :180:17: error: use of undefined value here causes illegal behavior
7273// :180:17: note: when computing vector element at index '0'
7274// :180:17: error: use of undefined value here causes illegal behavior7266// :180:17: error: use of undefined value here causes illegal behavior
7275// :180:17: note: when computing vector element at index '0'
7276// :180:17: error: use of undefined value here causes illegal behavior7267// :180:17: error: use of undefined value here causes illegal behavior
7277// :180:17: note: when computing vector element at index '0'
7278// :180:17: error: use of undefined value here causes illegal behavior7268// :180:17: error: use of undefined value here causes illegal behavior
7269// :180:17: note: when computing vector element at index '0'
7279// :180:17: error: use of undefined value here causes illegal behavior7270// :180:17: error: use of undefined value here causes illegal behavior
7271// :180:17: note: when computing vector element at index '0'
7280// :180:17: error: use of undefined value here causes illegal behavior7272// :180:17: error: use of undefined value here causes illegal behavior
7281// :180:17: note: when computing vector element at index '0'7273// :180:17: note: when computing vector element at index '0'
7282// :180:17: error: use of undefined value here causes illegal behavior7274// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7286,9 +7278,9 @@ const std = @import("std");...@@ -7286,9 +7278,9 @@ const std = @import("std");
7286// :180:17: error: use of undefined value here causes illegal behavior7278// :180:17: error: use of undefined value here causes illegal behavior
7287// :180:17: note: when computing vector element at index '0'7279// :180:17: note: when computing vector element at index '0'
7288// :180:17: error: use of undefined value here causes illegal behavior7280// :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'
7290// :180:17: error: use of undefined value here causes illegal behavior7282// :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'
7292// :180:17: error: use of undefined value here causes illegal behavior7284// :180:17: error: use of undefined value here causes illegal behavior
7293// :180:17: note: when computing vector element at index '0'7285// :180:17: note: when computing vector element at index '0'
7294// :180:17: error: use of undefined value here causes illegal behavior7286// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7298,7 +7290,9 @@ const std = @import("std");...@@ -7298,7 +7290,9 @@ const std = @import("std");
7298// :180:17: error: use of undefined value here causes illegal behavior7290// :180:17: error: use of undefined value here causes illegal behavior
7299// :180:17: note: when computing vector element at index '0'7291// :180:17: note: when computing vector element at index '0'
7300// :180:17: error: use of undefined value here causes illegal behavior7292// :180:17: error: use of undefined value here causes illegal behavior
7293// :180:17: note: when computing vector element at index '0'
7301// :180:17: error: use of undefined value here causes illegal behavior7294// :180:17: error: use of undefined value here causes illegal behavior
7295// :180:17: note: when computing vector element at index '0'
7302// :180:17: error: use of undefined value here causes illegal behavior7296// :180:17: error: use of undefined value here causes illegal behavior
7303// :180:17: note: when computing vector element at index '0'7297// :180:17: note: when computing vector element at index '0'
7304// :180:17: error: use of undefined value here causes illegal behavior7298// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7308,9 +7302,9 @@ const std = @import("std");...@@ -7308,9 +7302,9 @@ const std = @import("std");
7308// :180:17: error: use of undefined value here causes illegal behavior7302// :180:17: error: use of undefined value here causes illegal behavior
7309// :180:17: note: when computing vector element at index '0'7303// :180:17: note: when computing vector element at index '0'
7310// :180:17: error: use of undefined value here causes illegal behavior7304// :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'
7312// :180:17: error: use of undefined value here causes illegal behavior7306// :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'
7314// :180:17: error: use of undefined value here causes illegal behavior7308// :180:17: error: use of undefined value here causes illegal behavior
7315// :180:17: note: when computing vector element at index '0'7309// :180:17: note: when computing vector element at index '0'
7316// :180:17: error: use of undefined value here causes illegal behavior7310// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7320,7 +7314,9 @@ const std = @import("std");...@@ -7320,7 +7314,9 @@ const std = @import("std");
7320// :180:17: error: use of undefined value here causes illegal behavior7314// :180:17: error: use of undefined value here causes illegal behavior
7321// :180:17: note: when computing vector element at index '0'7315// :180:17: note: when computing vector element at index '0'
7322// :180:17: error: use of undefined value here causes illegal behavior7316// :180:17: error: use of undefined value here causes illegal behavior
7317// :180:17: note: when computing vector element at index '0'
7323// :180:17: error: use of undefined value here causes illegal behavior7318// :180:17: error: use of undefined value here causes illegal behavior
7319// :180:17: note: when computing vector element at index '0'
7324// :180:17: error: use of undefined value here causes illegal behavior7320// :180:17: error: use of undefined value here causes illegal behavior
7325// :180:17: note: when computing vector element at index '0'7321// :180:17: note: when computing vector element at index '0'
7326// :180:17: error: use of undefined value here causes illegal behavior7322// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7330,9 +7326,9 @@ const std = @import("std");...@@ -7330,9 +7326,9 @@ const std = @import("std");
7330// :180:17: error: use of undefined value here causes illegal behavior7326// :180:17: error: use of undefined value here causes illegal behavior
7331// :180:17: note: when computing vector element at index '0'7327// :180:17: note: when computing vector element at index '0'
7332// :180:17: error: use of undefined value here causes illegal behavior7328// :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'
7334// :180:17: error: use of undefined value here causes illegal behavior7330// :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'
7336// :180:17: error: use of undefined value here causes illegal behavior7332// :180:17: error: use of undefined value here causes illegal behavior
7337// :180:17: note: when computing vector element at index '0'7333// :180:17: note: when computing vector element at index '0'
7338// :180:17: error: use of undefined value here causes illegal behavior7334// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7342,7 +7338,9 @@ const std = @import("std");...@@ -7342,7 +7338,9 @@ const std = @import("std");
7342// :180:17: error: use of undefined value here causes illegal behavior7338// :180:17: error: use of undefined value here causes illegal behavior
7343// :180:17: note: when computing vector element at index '0'7339// :180:17: note: when computing vector element at index '0'
7344// :180:17: error: use of undefined value here causes illegal behavior7340// :180:17: error: use of undefined value here causes illegal behavior
7341// :180:17: note: when computing vector element at index '0'
7345// :180:17: error: use of undefined value here causes illegal behavior7342// :180:17: error: use of undefined value here causes illegal behavior
7343// :180:17: note: when computing vector element at index '0'
7346// :180:17: error: use of undefined value here causes illegal behavior7344// :180:17: error: use of undefined value here causes illegal behavior
7347// :180:17: note: when computing vector element at index '0'7345// :180:17: note: when computing vector element at index '0'
7348// :180:17: error: use of undefined value here causes illegal behavior7346// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7352,9 +7350,9 @@ const std = @import("std");...@@ -7352,9 +7350,9 @@ const std = @import("std");
7352// :180:17: error: use of undefined value here causes illegal behavior7350// :180:17: error: use of undefined value here causes illegal behavior
7353// :180:17: note: when computing vector element at index '0'7351// :180:17: note: when computing vector element at index '0'
7354// :180:17: error: use of undefined value here causes illegal behavior7352// :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'
7356// :180:17: error: use of undefined value here causes illegal behavior7354// :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'
7358// :180:17: error: use of undefined value here causes illegal behavior7356// :180:17: error: use of undefined value here causes illegal behavior
7359// :180:17: note: when computing vector element at index '0'7357// :180:17: note: when computing vector element at index '0'
7360// :180:17: error: use of undefined value here causes illegal behavior7358// :180:17: error: use of undefined value here causes illegal behavior
...@@ -7364,27 +7362,29 @@ const std = @import("std");...@@ -7364,27 +7362,29 @@ const std = @import("std");
7364// :180:17: error: use of undefined value here causes illegal behavior7362// :180:17: error: use of undefined value here causes illegal behavior
7365// :180:17: note: when computing vector element at index '0'7363// :180:17: note: when computing vector element at index '0'
7366// :180:17: error: use of undefined value here causes illegal behavior7364// :180:17: error: use of undefined value here causes illegal behavior
7365// :180:17: note: when computing vector element at index '1'
7367// :180:17: error: use of undefined value here causes illegal behavior7366// :180:17: error: use of undefined value here causes illegal behavior
7367// :180:17: note: when computing vector element at index '1'
7368// :180:17: error: use of undefined value here causes illegal behavior7368// :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'
7370// :180:17: error: use of undefined value here causes illegal behavior7370// :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'
7372// :180:17: error: use of undefined value here causes illegal behavior7372// :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'
7374// :180:17: error: use of undefined value here causes illegal behavior7374// :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'
7376// :180:17: error: use of undefined value here causes illegal behavior7376// :180:17: error: use of undefined value here causes illegal behavior
7377// :180:17: note: when computing vector element at index '1'7377// :180:17: note: when computing vector element at index '1'
7378// :180:17: error: use of undefined value here causes illegal behavior7378// :180:17: error: use of undefined value here causes illegal behavior
7379// :180:17: note: when computing vector element at index '1'7379// :180:17: note: when computing vector element at index '1'
7380// :180:17: error: use of undefined value here causes illegal behavior7380// :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'
7382// :180:17: error: use of undefined value here causes illegal behavior7382// :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'
7384// :180:17: error: use of undefined value here causes illegal behavior7384// :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'
7386// :180:17: error: use of undefined value here causes illegal behavior7386// :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'
7388// :180:21: error: use of undefined value here causes illegal behavior7388// :180:21: error: use of undefined value here causes illegal behavior
7389// :180:21: note: when computing vector element at index '0'7389// :180:21: note: when computing vector element at index '0'
7390// :180:21: error: use of undefined value here causes illegal behavior7390// :180:21: error: use of undefined value here causes illegal behavior
...@@ -7412,27 +7412,19 @@ const std = @import("std");...@@ -7412,27 +7412,19 @@ const std = @import("std");
7412// :183:17: error: use of undefined value here causes illegal behavior7412// :183:17: error: use of undefined value here causes illegal behavior
7413// :183:17: error: use of undefined value here causes illegal behavior7413// :183:17: error: use of undefined value here causes illegal behavior
7414// :183:17: error: use of undefined value here causes illegal behavior7414// :183:17: error: use of undefined value here causes illegal behavior
7415// :183:17: note: when computing vector element at index '0'
7416// :183:17: error: use of undefined value here causes illegal behavior7415// :183:17: error: use of undefined value here causes illegal behavior
7417// :183:17: note: when computing vector element at index '0'
7418// :183:17: error: use of undefined value here causes illegal behavior7416// :183:17: error: use of undefined value here causes illegal behavior
7419// :183:17: note: when computing vector element at index '0'
7420// :183:17: error: use of undefined value here causes illegal behavior7417// :183:17: error: use of undefined value here causes illegal behavior
7421// :183:17: note: when computing vector element at index '0'
7422// :183:17: error: use of undefined value here causes illegal behavior7418// :183:17: error: use of undefined value here causes illegal behavior
7423// :183:17: note: when computing vector element at index '1'
7424// :183:17: error: use of undefined value here causes illegal behavior7419// :183:17: error: use of undefined value here causes illegal behavior
7425// :183:17: note: when computing vector element at index '1'
7426// :183:17: error: use of undefined value here causes illegal behavior7420// :183:17: error: use of undefined value here causes illegal behavior
7427// :183:17: note: when computing vector element at index '0'
7428// :183:17: error: use of undefined value here causes illegal behavior7421// :183:17: error: use of undefined value here causes illegal behavior
7429// :183:17: note: when computing vector element at index '0'
7430// :183:17: error: use of undefined value here causes illegal behavior7422// :183:17: error: use of undefined value here causes illegal behavior
7431// :183:17: note: when computing vector element at index '0'
7432// :183:17: error: use of undefined value here causes illegal behavior7423// :183:17: error: use of undefined value here causes illegal behavior
7433// :183:17: note: when computing vector element at index '0'
7434// :183:17: error: use of undefined value here causes illegal behavior7424// :183:17: error: use of undefined value here causes illegal behavior
7425// :183:17: note: when computing vector element at index '0'
7435// :183:17: error: use of undefined value here causes illegal behavior7426// :183:17: error: use of undefined value here causes illegal behavior
7427// :183:17: note: when computing vector element at index '0'
7436// :183:17: error: use of undefined value here causes illegal behavior7428// :183:17: error: use of undefined value here causes illegal behavior
7437// :183:17: note: when computing vector element at index '0'7429// :183:17: note: when computing vector element at index '0'
7438// :183:17: error: use of undefined value here causes illegal behavior7430// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7442,9 +7434,9 @@ const std = @import("std");...@@ -7442,9 +7434,9 @@ const std = @import("std");
7442// :183:17: error: use of undefined value here causes illegal behavior7434// :183:17: error: use of undefined value here causes illegal behavior
7443// :183:17: note: when computing vector element at index '0'7435// :183:17: note: when computing vector element at index '0'
7444// :183:17: error: use of undefined value here causes illegal behavior7436// :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'
7446// :183:17: error: use of undefined value here causes illegal behavior7438// :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'
7448// :183:17: error: use of undefined value here causes illegal behavior7440// :183:17: error: use of undefined value here causes illegal behavior
7449// :183:17: note: when computing vector element at index '0'7441// :183:17: note: when computing vector element at index '0'
7450// :183:17: error: use of undefined value here causes illegal behavior7442// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7454,7 +7446,9 @@ const std = @import("std");...@@ -7454,7 +7446,9 @@ const std = @import("std");
7454// :183:17: error: use of undefined value here causes illegal behavior7446// :183:17: error: use of undefined value here causes illegal behavior
7455// :183:17: note: when computing vector element at index '0'7447// :183:17: note: when computing vector element at index '0'
7456// :183:17: error: use of undefined value here causes illegal behavior7448// :183:17: error: use of undefined value here causes illegal behavior
7449// :183:17: note: when computing vector element at index '0'
7457// :183:17: error: use of undefined value here causes illegal behavior7450// :183:17: error: use of undefined value here causes illegal behavior
7451// :183:17: note: when computing vector element at index '0'
7458// :183:17: error: use of undefined value here causes illegal behavior7452// :183:17: error: use of undefined value here causes illegal behavior
7459// :183:17: note: when computing vector element at index '0'7453// :183:17: note: when computing vector element at index '0'
7460// :183:17: error: use of undefined value here causes illegal behavior7454// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7464,9 +7458,9 @@ const std = @import("std");...@@ -7464,9 +7458,9 @@ const std = @import("std");
7464// :183:17: error: use of undefined value here causes illegal behavior7458// :183:17: error: use of undefined value here causes illegal behavior
7465// :183:17: note: when computing vector element at index '0'7459// :183:17: note: when computing vector element at index '0'
7466// :183:17: error: use of undefined value here causes illegal behavior7460// :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'
7468// :183:17: error: use of undefined value here causes illegal behavior7462// :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'
7470// :183:17: error: use of undefined value here causes illegal behavior7464// :183:17: error: use of undefined value here causes illegal behavior
7471// :183:17: note: when computing vector element at index '0'7465// :183:17: note: when computing vector element at index '0'
7472// :183:17: error: use of undefined value here causes illegal behavior7466// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7476,7 +7470,9 @@ const std = @import("std");...@@ -7476,7 +7470,9 @@ const std = @import("std");
7476// :183:17: error: use of undefined value here causes illegal behavior7470// :183:17: error: use of undefined value here causes illegal behavior
7477// :183:17: note: when computing vector element at index '0'7471// :183:17: note: when computing vector element at index '0'
7478// :183:17: error: use of undefined value here causes illegal behavior7472// :183:17: error: use of undefined value here causes illegal behavior
7473// :183:17: note: when computing vector element at index '0'
7479// :183:17: error: use of undefined value here causes illegal behavior7474// :183:17: error: use of undefined value here causes illegal behavior
7475// :183:17: note: when computing vector element at index '0'
7480// :183:17: error: use of undefined value here causes illegal behavior7476// :183:17: error: use of undefined value here causes illegal behavior
7481// :183:17: note: when computing vector element at index '0'7477// :183:17: note: when computing vector element at index '0'
7482// :183:17: error: use of undefined value here causes illegal behavior7478// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7486,9 +7482,9 @@ const std = @import("std");...@@ -7486,9 +7482,9 @@ const std = @import("std");
7486// :183:17: error: use of undefined value here causes illegal behavior7482// :183:17: error: use of undefined value here causes illegal behavior
7487// :183:17: note: when computing vector element at index '0'7483// :183:17: note: when computing vector element at index '0'
7488// :183:17: error: use of undefined value here causes illegal behavior7484// :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'
7490// :183:17: error: use of undefined value here causes illegal behavior7486// :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'
7492// :183:17: error: use of undefined value here causes illegal behavior7488// :183:17: error: use of undefined value here causes illegal behavior
7493// :183:17: note: when computing vector element at index '0'7489// :183:17: note: when computing vector element at index '0'
7494// :183:17: error: use of undefined value here causes illegal behavior7490// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7498,7 +7494,9 @@ const std = @import("std");...@@ -7498,7 +7494,9 @@ const std = @import("std");
7498// :183:17: error: use of undefined value here causes illegal behavior7494// :183:17: error: use of undefined value here causes illegal behavior
7499// :183:17: note: when computing vector element at index '0'7495// :183:17: note: when computing vector element at index '0'
7500// :183:17: error: use of undefined value here causes illegal behavior7496// :183:17: error: use of undefined value here causes illegal behavior
7497// :183:17: note: when computing vector element at index '0'
7501// :183:17: error: use of undefined value here causes illegal behavior7498// :183:17: error: use of undefined value here causes illegal behavior
7499// :183:17: note: when computing vector element at index '0'
7502// :183:17: error: use of undefined value here causes illegal behavior7500// :183:17: error: use of undefined value here causes illegal behavior
7503// :183:17: note: when computing vector element at index '0'7501// :183:17: note: when computing vector element at index '0'
7504// :183:17: error: use of undefined value here causes illegal behavior7502// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7508,9 +7506,9 @@ const std = @import("std");...@@ -7508,9 +7506,9 @@ const std = @import("std");
7508// :183:17: error: use of undefined value here causes illegal behavior7506// :183:17: error: use of undefined value here causes illegal behavior
7509// :183:17: note: when computing vector element at index '0'7507// :183:17: note: when computing vector element at index '0'
7510// :183:17: error: use of undefined value here causes illegal behavior7508// :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'
7512// :183:17: error: use of undefined value here causes illegal behavior7510// :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'
7514// :183:17: error: use of undefined value here causes illegal behavior7512// :183:17: error: use of undefined value here causes illegal behavior
7515// :183:17: note: when computing vector element at index '0'7513// :183:17: note: when computing vector element at index '0'
7516// :183:17: error: use of undefined value here causes illegal behavior7514// :183:17: error: use of undefined value here causes illegal behavior
...@@ -7520,27 +7518,29 @@ const std = @import("std");...@@ -7520,27 +7518,29 @@ const std = @import("std");
7520// :183:17: error: use of undefined value here causes illegal behavior7518// :183:17: error: use of undefined value here causes illegal behavior
7521// :183:17: note: when computing vector element at index '0'7519// :183:17: note: when computing vector element at index '0'
7522// :183:17: error: use of undefined value here causes illegal behavior7520// :183:17: error: use of undefined value here causes illegal behavior
7521// :183:17: note: when computing vector element at index '1'
7523// :183:17: error: use of undefined value here causes illegal behavior7522// :183:17: error: use of undefined value here causes illegal behavior
7523// :183:17: note: when computing vector element at index '1'
7524// :183:17: error: use of undefined value here causes illegal behavior7524// :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'
7526// :183:17: error: use of undefined value here causes illegal behavior7526// :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'
7528// :183:17: error: use of undefined value here causes illegal behavior7528// :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'
7530// :183:17: error: use of undefined value here causes illegal behavior7530// :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'
7532// :183:17: error: use of undefined value here causes illegal behavior7532// :183:17: error: use of undefined value here causes illegal behavior
7533// :183:17: note: when computing vector element at index '1'7533// :183:17: note: when computing vector element at index '1'
7534// :183:17: error: use of undefined value here causes illegal behavior7534// :183:17: error: use of undefined value here causes illegal behavior
7535// :183:17: note: when computing vector element at index '1'7535// :183:17: note: when computing vector element at index '1'
7536// :183:17: error: use of undefined value here causes illegal behavior7536// :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'
7538// :183:17: error: use of undefined value here causes illegal behavior7538// :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'
7540// :183:17: error: use of undefined value here causes illegal behavior7540// :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'
7542// :183:17: error: use of undefined value here causes illegal behavior7542// :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'
7544// :183:21: error: use of undefined value here causes illegal behavior7544// :183:21: error: use of undefined value here causes illegal behavior
7545// :183:21: note: when computing vector element at index '0'7545// :183:21: note: when computing vector element at index '0'
7546// :183:21: error: use of undefined value here causes illegal behavior7546// :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 {...@@ -681,1800 +681,1360 @@ inline fn testFloatWithValue(comptime Float: type, x: Float) void {
681// @as(@Vector(2, u8), undefined)681// @as(@Vector(2, u8), undefined)
682// @as(@Vector(2, u8), [runtime value])682// @as(@Vector(2, u8), [runtime value])
683// @as(@Vector(2, u8), [runtime value])683// @as(@Vector(2, u8), [runtime value])
684// @as(i8, undefined)684// @as(i500, undefined)
685// @as(i8, undefined)685// @as(i500, undefined)
686// @as(@Vector(2, i8), .{ 6, undefined })686// @as(@Vector(2, i500), .{ 6, undefined })
687// @as(@Vector(2, i8), .{ undefined, 6 })687// @as(@Vector(2, i500), .{ undefined, 6 })
688// @as(@Vector(2, i8), undefined)688// @as(@Vector(2, i500), undefined)
689// @as(@Vector(2, i8), .{ 6, undefined })689// @as(@Vector(2, i500), .{ 6, undefined })
690// @as(@Vector(2, i8), .{ 6, undefined })690// @as(@Vector(2, i500), .{ 6, undefined })
691// @as(@Vector(2, i8), undefined)691// @as(@Vector(2, i500), undefined)
692// @as(@Vector(2, i8), undefined)692// @as(@Vector(2, i500), undefined)
693// @as(@Vector(2, i8), .{ undefined, 6 })693// @as(@Vector(2, i500), .{ undefined, 6 })
694// @as(@Vector(2, i8), undefined)694// @as(@Vector(2, i500), undefined)
695// @as(@Vector(2, i8), .{ undefined, 6 })695// @as(@Vector(2, i500), .{ undefined, 6 })
696// @as(@Vector(2, i8), undefined)696// @as(@Vector(2, i500), undefined)
697// @as(@Vector(2, i8), undefined)697// @as(@Vector(2, i500), undefined)
698// @as(@Vector(2, i8), undefined)698// @as(@Vector(2, i500), undefined)
699// @as(@Vector(2, i8), undefined)699// @as(@Vector(2, i500), undefined)
700// @as(@Vector(2, i8), undefined)700// @as(@Vector(2, i500), undefined)
701// @as(i8, undefined)701// @as(i500, undefined)
702// @as(i8, undefined)702// @as(i500, undefined)
703// @as(@Vector(2, i8), .{ 6, undefined })703// @as(@Vector(2, i500), .{ 6, undefined })
704// @as(@Vector(2, i8), .{ undefined, 6 })704// @as(@Vector(2, i500), .{ undefined, 6 })
705// @as(@Vector(2, i8), undefined)705// @as(@Vector(2, i500), undefined)
706// @as(@Vector(2, i8), .{ 6, undefined })706// @as(@Vector(2, i500), .{ 6, undefined })
707// @as(@Vector(2, i8), .{ 6, undefined })707// @as(@Vector(2, i500), .{ 6, undefined })
708// @as(@Vector(2, i8), undefined)708// @as(@Vector(2, i500), undefined)
709// @as(@Vector(2, i8), undefined)709// @as(@Vector(2, i500), undefined)
710// @as(@Vector(2, i8), .{ undefined, 6 })710// @as(@Vector(2, i500), .{ undefined, 6 })
711// @as(@Vector(2, i8), undefined)711// @as(@Vector(2, i500), undefined)
712// @as(@Vector(2, i8), .{ undefined, 6 })712// @as(@Vector(2, i500), .{ undefined, 6 })
713// @as(@Vector(2, i8), undefined)713// @as(@Vector(2, i500), undefined)
714// @as(@Vector(2, i8), undefined)714// @as(@Vector(2, i500), undefined)
715// @as(@Vector(2, i8), undefined)715// @as(@Vector(2, i500), undefined)
716// @as(@Vector(2, i8), undefined)716// @as(@Vector(2, i500), undefined)
717// @as(@Vector(2, i8), undefined)717// @as(@Vector(2, i500), undefined)
718// @as(i8, undefined)718// @as(i500, undefined)
719// @as(i8, undefined)719// @as(i500, undefined)
720// @as(@Vector(2, i8), .{ 0, undefined })720// @as(@Vector(2, i500), .{ 0, undefined })
721// @as(@Vector(2, i8), .{ undefined, 0 })721// @as(@Vector(2, i500), .{ undefined, 0 })
722// @as(@Vector(2, i8), undefined)722// @as(@Vector(2, i500), undefined)
723// @as(@Vector(2, i8), .{ 0, undefined })723// @as(@Vector(2, i500), .{ 0, undefined })
724// @as(@Vector(2, i8), .{ 0, undefined })724// @as(@Vector(2, i500), .{ 0, undefined })
725// @as(@Vector(2, i8), undefined)725// @as(@Vector(2, i500), undefined)
726// @as(@Vector(2, i8), undefined)726// @as(@Vector(2, i500), undefined)
727// @as(@Vector(2, i8), .{ undefined, 0 })727// @as(@Vector(2, i500), .{ undefined, 0 })
728// @as(@Vector(2, i8), undefined)728// @as(@Vector(2, i500), undefined)
729// @as(@Vector(2, i8), .{ undefined, 0 })729// @as(@Vector(2, i500), .{ undefined, 0 })
730// @as(@Vector(2, i8), undefined)730// @as(@Vector(2, i500), undefined)
731// @as(@Vector(2, i8), undefined)731// @as(@Vector(2, i500), undefined)
732// @as(@Vector(2, i8), undefined)732// @as(@Vector(2, i500), undefined)
733// @as(@Vector(2, i8), undefined)733// @as(@Vector(2, i500), undefined)
734// @as(@Vector(2, i8), undefined)734// @as(@Vector(2, i500), undefined)
735// @as(i8, undefined)735// @as(i500, undefined)
736// @as(i8, undefined)736// @as(i500, undefined)
737// @as(@Vector(2, i8), .{ 0, undefined })737// @as(@Vector(2, i500), .{ 0, undefined })
738// @as(@Vector(2, i8), .{ undefined, 0 })738// @as(@Vector(2, i500), .{ undefined, 0 })
739// @as(@Vector(2, i8), undefined)739// @as(@Vector(2, i500), undefined)
740// @as(@Vector(2, i8), .{ 0, undefined })740// @as(@Vector(2, i500), .{ 0, undefined })
741// @as(@Vector(2, i8), .{ 0, undefined })741// @as(@Vector(2, i500), .{ 0, undefined })
742// @as(@Vector(2, i8), undefined)742// @as(@Vector(2, i500), undefined)
743// @as(@Vector(2, i8), undefined)743// @as(@Vector(2, i500), undefined)
744// @as(@Vector(2, i8), .{ undefined, 0 })744// @as(@Vector(2, i500), .{ undefined, 0 })
745// @as(@Vector(2, i8), undefined)745// @as(@Vector(2, i500), undefined)
746// @as(@Vector(2, i8), .{ undefined, 0 })746// @as(@Vector(2, i500), .{ undefined, 0 })
747// @as(@Vector(2, i8), undefined)747// @as(@Vector(2, i500), undefined)
748// @as(@Vector(2, i8), undefined)748// @as(@Vector(2, i500), undefined)
749// @as(@Vector(2, i8), undefined)749// @as(@Vector(2, i500), undefined)
750// @as(@Vector(2, i8), undefined)750// @as(@Vector(2, i500), undefined)
751// @as(@Vector(2, i8), undefined)751// @as(@Vector(2, i500), undefined)
752// @as(i8, undefined)752// @as(i500, undefined)
753// @as(i8, undefined)753// @as(i500, undefined)
754// @as(@Vector(2, i8), .{ 9, undefined })754// @as(@Vector(2, i500), .{ 9, undefined })
755// @as(@Vector(2, i8), .{ undefined, 9 })755// @as(@Vector(2, i500), .{ undefined, 9 })
756// @as(@Vector(2, i8), undefined)756// @as(@Vector(2, i500), undefined)
757// @as(@Vector(2, i8), .{ 9, undefined })757// @as(@Vector(2, i500), .{ 9, undefined })
758// @as(@Vector(2, i8), .{ 9, undefined })758// @as(@Vector(2, i500), .{ 9, undefined })
759// @as(@Vector(2, i8), undefined)759// @as(@Vector(2, i500), undefined)
760// @as(@Vector(2, i8), undefined)760// @as(@Vector(2, i500), undefined)
761// @as(@Vector(2, i8), .{ undefined, 9 })761// @as(@Vector(2, i500), .{ undefined, 9 })
762// @as(@Vector(2, i8), undefined)762// @as(@Vector(2, i500), undefined)
763// @as(@Vector(2, i8), .{ undefined, 9 })763// @as(@Vector(2, i500), .{ undefined, 9 })
764// @as(@Vector(2, i8), undefined)764// @as(@Vector(2, i500), undefined)
765// @as(@Vector(2, i8), undefined)765// @as(@Vector(2, i500), undefined)
766// @as(@Vector(2, i8), undefined)766// @as(@Vector(2, i500), undefined)
767// @as(@Vector(2, i8), undefined)767// @as(@Vector(2, i500), undefined)
768// @as(@Vector(2, i8), undefined)768// @as(@Vector(2, i500), undefined)
769// @as(i8, undefined)769// @as(i500, undefined)
770// @as(i8, undefined)770// @as(i500, undefined)
771// @as(@Vector(2, i8), .{ 9, undefined })771// @as(@Vector(2, i500), .{ 9, undefined })
772// @as(@Vector(2, i8), .{ undefined, 9 })772// @as(@Vector(2, i500), .{ undefined, 9 })
773// @as(@Vector(2, i8), undefined)773// @as(@Vector(2, i500), undefined)
774// @as(@Vector(2, i8), .{ 9, undefined })774// @as(@Vector(2, i500), .{ 9, undefined })
775// @as(@Vector(2, i8), .{ 9, undefined })775// @as(@Vector(2, i500), .{ 9, undefined })
776// @as(@Vector(2, i8), undefined)776// @as(@Vector(2, i500), undefined)
777// @as(@Vector(2, i8), undefined)777// @as(@Vector(2, i500), undefined)
778// @as(@Vector(2, i8), .{ undefined, 9 })778// @as(@Vector(2, i500), .{ undefined, 9 })
779// @as(@Vector(2, i8), undefined)779// @as(@Vector(2, i500), undefined)
780// @as(@Vector(2, i8), .{ undefined, 9 })780// @as(@Vector(2, i500), .{ undefined, 9 })
781// @as(@Vector(2, i8), undefined)781// @as(@Vector(2, i500), undefined)
782// @as(@Vector(2, i8), undefined)782// @as(@Vector(2, i500), undefined)
783// @as(@Vector(2, i8), undefined)783// @as(@Vector(2, i500), undefined)
784// @as(@Vector(2, i8), undefined)784// @as(@Vector(2, i500), undefined)
785// @as(@Vector(2, i8), undefined)785// @as(@Vector(2, i500), undefined)
786// @as(i8, undefined)786// @as(i500, undefined)
787// @as(i8, undefined)787// @as(i500, undefined)
788// @as(@Vector(2, i8), .{ 0, undefined })788// @as(@Vector(2, i500), .{ 0, undefined })
789// @as(@Vector(2, i8), .{ undefined, 0 })789// @as(@Vector(2, i500), .{ undefined, 0 })
790// @as(@Vector(2, i8), undefined)790// @as(@Vector(2, i500), undefined)
791// @as(@Vector(2, i8), .{ 0, undefined })791// @as(@Vector(2, i500), .{ 0, undefined })
792// @as(@Vector(2, i8), .{ 0, undefined })792// @as(@Vector(2, i500), .{ 0, undefined })
793// @as(@Vector(2, i8), undefined)793// @as(@Vector(2, i500), undefined)
794// @as(@Vector(2, i8), undefined)794// @as(@Vector(2, i500), undefined)
795// @as(@Vector(2, i8), .{ undefined, 0 })795// @as(@Vector(2, i500), .{ undefined, 0 })
796// @as(@Vector(2, i8), undefined)796// @as(@Vector(2, i500), undefined)
797// @as(@Vector(2, i8), .{ undefined, 0 })797// @as(@Vector(2, i500), .{ undefined, 0 })
798// @as(@Vector(2, i8), undefined)798// @as(@Vector(2, i500), undefined)
799// @as(@Vector(2, i8), undefined)799// @as(@Vector(2, i500), undefined)
800// @as(@Vector(2, i8), undefined)800// @as(@Vector(2, i500), undefined)
801// @as(@Vector(2, i8), undefined)801// @as(@Vector(2, i500), undefined)
802// @as(@Vector(2, i8), undefined)802// @as(@Vector(2, i500), undefined)
803// @as(i8, undefined)803// @as(i500, undefined)
804// @as(@Vector(2, i8), undefined)804// @as(@Vector(2, i500), undefined)
805// @as(i8, undefined)805// @as(i500, undefined)
806// @as(i8, undefined)806// @as(i500, undefined)
807// @as(@Vector(2, i8), undefined)807// @as(@Vector(2, i500), undefined)
808// @as(@Vector(2, i8), undefined)808// @as(@Vector(2, i500), undefined)
809// @as(i8, undefined)809// @as(i500, undefined)
810// @as(@Vector(2, i8), undefined)810// @as(@Vector(2, i500), undefined)
811// @as(i8, undefined)811// @as(i500, undefined)
812// @as(i8, undefined)812// @as(i500, undefined)
813// @as(@Vector(2, i8), [runtime value])813// @as(@Vector(2, i500), [runtime value])
814// @as(@Vector(2, i8), [runtime value])814// @as(@Vector(2, i500), [runtime value])
815// @as(@Vector(2, i8), undefined)815// @as(@Vector(2, i500), undefined)
816// @as(@Vector(2, i8), [runtime value])816// @as(@Vector(2, i500), [runtime value])
817// @as(@Vector(2, i8), [runtime value])817// @as(@Vector(2, i500), [runtime value])
818// @as(@Vector(2, i8), [runtime value])818// @as(@Vector(2, i500), [runtime value])
819// @as(@Vector(2, i8), undefined)819// @as(@Vector(2, i500), undefined)
820// @as(@Vector(2, i8), [runtime value])820// @as(@Vector(2, i500), [runtime value])
821// @as(@Vector(2, i8), [runtime value])821// @as(@Vector(2, i500), [runtime value])
822// @as(@Vector(2, i8), [runtime value])822// @as(@Vector(2, i500), [runtime value])
823// @as(@Vector(2, i8), undefined)823// @as(@Vector(2, i500), undefined)
824// @as(@Vector(2, i8), undefined)824// @as(@Vector(2, i500), undefined)
825// @as(@Vector(2, i8), undefined)825// @as(@Vector(2, i500), undefined)
826// @as(@Vector(2, i8), undefined)826// @as(@Vector(2, i500), undefined)
827// @as(@Vector(2, i8), undefined)827// @as(@Vector(2, i500), undefined)
828// @as(i8, undefined)828// @as(i500, undefined)
829// @as(i8, undefined)829// @as(i500, undefined)
830// @as(@Vector(2, i8), [runtime value])830// @as(@Vector(2, i500), [runtime value])
831// @as(@Vector(2, i8), [runtime value])831// @as(@Vector(2, i500), [runtime value])
832// @as(@Vector(2, i8), undefined)832// @as(@Vector(2, i500), undefined)
833// @as(@Vector(2, i8), [runtime value])833// @as(@Vector(2, i500), [runtime value])
834// @as(@Vector(2, i8), [runtime value])834// @as(@Vector(2, i500), [runtime value])
835// @as(@Vector(2, i8), [runtime value])835// @as(@Vector(2, i500), [runtime value])
836// @as(@Vector(2, i8), undefined)836// @as(@Vector(2, i500), undefined)
837// @as(@Vector(2, i8), [runtime value])837// @as(@Vector(2, i500), [runtime value])
838// @as(@Vector(2, i8), [runtime value])838// @as(@Vector(2, i500), [runtime value])
839// @as(@Vector(2, i8), [runtime value])839// @as(@Vector(2, i500), [runtime value])
840// @as(@Vector(2, i8), undefined)840// @as(@Vector(2, i500), undefined)
841// @as(@Vector(2, i8), undefined)841// @as(@Vector(2, i500), undefined)
842// @as(@Vector(2, i8), undefined)842// @as(@Vector(2, i500), undefined)
843// @as(@Vector(2, i8), undefined)843// @as(@Vector(2, i500), undefined)
844// @as(@Vector(2, i8), undefined)844// @as(@Vector(2, i500), undefined)
845// @as(i8, undefined)845// @as(i500, undefined)
846// @as(i8, undefined)846// @as(i500, undefined)
847// @as(@Vector(2, i8), [runtime value])847// @as(@Vector(2, i500), [runtime value])
848// @as(@Vector(2, i8), [runtime value])848// @as(@Vector(2, i500), [runtime value])
849// @as(@Vector(2, i8), undefined)849// @as(@Vector(2, i500), undefined)
850// @as(@Vector(2, i8), [runtime value])850// @as(@Vector(2, i500), [runtime value])
851// @as(@Vector(2, i8), [runtime value])851// @as(@Vector(2, i500), [runtime value])
852// @as(@Vector(2, i8), [runtime value])852// @as(@Vector(2, i500), [runtime value])
853// @as(@Vector(2, i8), undefined)853// @as(@Vector(2, i500), undefined)
854// @as(@Vector(2, i8), [runtime value])854// @as(@Vector(2, i500), [runtime value])
855// @as(@Vector(2, i8), [runtime value])855// @as(@Vector(2, i500), [runtime value])
856// @as(@Vector(2, i8), [runtime value])856// @as(@Vector(2, i500), [runtime value])
857// @as(@Vector(2, i8), undefined)857// @as(@Vector(2, i500), undefined)
858// @as(@Vector(2, i8), undefined)858// @as(@Vector(2, i500), undefined)
859// @as(@Vector(2, i8), undefined)859// @as(@Vector(2, i500), undefined)
860// @as(@Vector(2, i8), undefined)860// @as(@Vector(2, i500), undefined)
861// @as(@Vector(2, i8), undefined)861// @as(@Vector(2, i500), undefined)
862// @as(i8, undefined)862// @as(i500, undefined)
863// @as(i8, undefined)863// @as(i500, undefined)
864// @as(@Vector(2, i8), [runtime value])864// @as(@Vector(2, i500), [runtime value])
865// @as(@Vector(2, i8), [runtime value])865// @as(@Vector(2, i500), [runtime value])
866// @as(@Vector(2, i8), undefined)866// @as(@Vector(2, i500), undefined)
867// @as(@Vector(2, i8), [runtime value])867// @as(@Vector(2, i500), [runtime value])
868// @as(@Vector(2, i8), [runtime value])868// @as(@Vector(2, i500), [runtime value])
869// @as(@Vector(2, i8), [runtime value])869// @as(@Vector(2, i500), [runtime value])
870// @as(@Vector(2, i8), undefined)870// @as(@Vector(2, i500), undefined)
871// @as(@Vector(2, i8), [runtime value])871// @as(@Vector(2, i500), [runtime value])
872// @as(@Vector(2, i8), [runtime value])872// @as(@Vector(2, i500), [runtime value])
873// @as(@Vector(2, i8), [runtime value])873// @as(@Vector(2, i500), [runtime value])
874// @as(@Vector(2, i8), undefined)874// @as(@Vector(2, i500), undefined)
875// @as(@Vector(2, i8), undefined)875// @as(@Vector(2, i500), undefined)
876// @as(@Vector(2, i8), undefined)876// @as(@Vector(2, i500), undefined)
877// @as(@Vector(2, i8), undefined)877// @as(@Vector(2, i500), undefined)
878// @as(@Vector(2, i8), undefined)878// @as(@Vector(2, i500), undefined)
879// @as(i8, undefined)879// @as(i500, undefined)
880// @as(i8, undefined)880// @as(i500, undefined)
881// @as(@Vector(2, i8), [runtime value])881// @as(@Vector(2, i500), [runtime value])
882// @as(@Vector(2, i8), [runtime value])882// @as(@Vector(2, i500), [runtime value])
883// @as(@Vector(2, i8), undefined)883// @as(@Vector(2, i500), undefined)
884// @as(@Vector(2, i8), [runtime value])884// @as(@Vector(2, i500), [runtime value])
885// @as(@Vector(2, i8), [runtime value])885// @as(@Vector(2, i500), [runtime value])
886// @as(@Vector(2, i8), [runtime value])886// @as(@Vector(2, i500), [runtime value])
887// @as(@Vector(2, i8), undefined)887// @as(@Vector(2, i500), undefined)
888// @as(@Vector(2, i8), [runtime value])888// @as(@Vector(2, i500), [runtime value])
889// @as(@Vector(2, i8), [runtime value])889// @as(@Vector(2, i500), [runtime value])
890// @as(@Vector(2, i8), [runtime value])890// @as(@Vector(2, i500), [runtime value])
891// @as(@Vector(2, i8), undefined)891// @as(@Vector(2, i500), undefined)
892// @as(@Vector(2, i8), undefined)892// @as(@Vector(2, i500), undefined)
893// @as(@Vector(2, i8), undefined)893// @as(@Vector(2, i500), undefined)
894// @as(@Vector(2, i8), undefined)894// @as(@Vector(2, i500), undefined)
895// @as(@Vector(2, i8), undefined)895// @as(@Vector(2, i500), undefined)
896// @as(i8, undefined)896// @as(i500, undefined)
897// @as(i8, undefined)897// @as(i500, undefined)
898// @as(@Vector(2, i8), [runtime value])898// @as(@Vector(2, i500), [runtime value])
899// @as(@Vector(2, i8), [runtime value])899// @as(@Vector(2, i500), [runtime value])
900// @as(@Vector(2, i8), undefined)900// @as(@Vector(2, i500), undefined)
901// @as(@Vector(2, i8), [runtime value])901// @as(@Vector(2, i500), [runtime value])
902// @as(@Vector(2, i8), [runtime value])902// @as(@Vector(2, i500), [runtime value])
903// @as(@Vector(2, i8), [runtime value])903// @as(@Vector(2, i500), [runtime value])
904// @as(@Vector(2, i8), undefined)904// @as(@Vector(2, i500), undefined)
905// @as(@Vector(2, i8), [runtime value])905// @as(@Vector(2, i500), [runtime value])
906// @as(@Vector(2, i8), [runtime value])906// @as(@Vector(2, i500), [runtime value])
907// @as(@Vector(2, i8), [runtime value])907// @as(@Vector(2, i500), [runtime value])
908// @as(@Vector(2, i8), undefined)908// @as(@Vector(2, i500), undefined)
909// @as(@Vector(2, i8), undefined)909// @as(@Vector(2, i500), undefined)
910// @as(@Vector(2, i8), undefined)910// @as(@Vector(2, i500), undefined)
911// @as(@Vector(2, i8), undefined)911// @as(@Vector(2, i500), undefined)
912// @as(@Vector(2, i8), undefined)912// @as(@Vector(2, i500), undefined)
913// @as(i8, [runtime value])913// @as(i500, [runtime value])
914// @as(i8, [runtime value])914// @as(i500, [runtime value])
915// @as(@Vector(2, i8), [runtime value])915// @as(@Vector(2, i500), [runtime value])
916// @as(@Vector(2, i8), [runtime value])916// @as(@Vector(2, i500), [runtime value])
917// @as(@Vector(2, i8), [runtime value])917// @as(@Vector(2, i500), [runtime value])
918// @as(@Vector(2, i8), [runtime value])918// @as(@Vector(2, i500), [runtime value])
919// @as(@Vector(2, i8), [runtime value])919// @as(@Vector(2, i500), [runtime value])
920// @as(@Vector(2, i8), [runtime value])920// @as(@Vector(2, i500), [runtime value])
921// @as(@Vector(2, i8), [runtime value])921// @as(@Vector(2, i500), [runtime value])
922// @as(@Vector(2, i8), [runtime value])922// @as(@Vector(2, i500), [runtime value])
923// @as(@Vector(2, i8), [runtime value])923// @as(@Vector(2, i500), [runtime value])
924// @as(@Vector(2, i8), [runtime value])924// @as(@Vector(2, i500), [runtime value])
925// @as(@Vector(2, i8), [runtime value])925// @as(@Vector(2, i500), [runtime value])
926// @as(@Vector(2, i8), [runtime value])926// @as(@Vector(2, i500), [runtime value])
927// @as(@Vector(2, i8), [runtime value])927// @as(@Vector(2, i500), [runtime value])
928// @as(@Vector(2, i8), [runtime value])928// @as(@Vector(2, i500), [runtime value])
929// @as(@Vector(2, i8), undefined)929// @as(@Vector(2, i500), undefined)
930// @as(i8, undefined)930// @as(i500, undefined)
931// @as(@Vector(2, i8), undefined)931// @as(@Vector(2, i500), undefined)
932// @as(i8, undefined)932// @as(i500, undefined)
933// @as(i8, undefined)933// @as(i500, undefined)
934// @as(@Vector(2, i8), undefined)934// @as(@Vector(2, i500), undefined)
935// @as(@Vector(2, i8), undefined)935// @as(@Vector(2, i500), undefined)
936// @as(i8, undefined)936// @as(i500, undefined)
937// @as(@Vector(2, i8), undefined)937// @as(@Vector(2, i500), undefined)
938// @as(u32, undefined)938// @as(u500, undefined)
939// @as(u32, undefined)939// @as(u500, undefined)
940// @as(@Vector(2, u32), .{ 6, undefined })940// @as(@Vector(2, u500), .{ 6, undefined })
941// @as(@Vector(2, u32), .{ undefined, 6 })941// @as(@Vector(2, u500), .{ undefined, 6 })
942// @as(@Vector(2, u32), undefined)942// @as(@Vector(2, u500), undefined)
943// @as(@Vector(2, u32), .{ 6, undefined })943// @as(@Vector(2, u500), .{ 6, undefined })
944// @as(@Vector(2, u32), .{ 6, undefined })944// @as(@Vector(2, u500), .{ 6, undefined })
945// @as(@Vector(2, u32), undefined)945// @as(@Vector(2, u500), undefined)
946// @as(@Vector(2, u32), undefined)946// @as(@Vector(2, u500), undefined)
947// @as(@Vector(2, u32), .{ undefined, 6 })947// @as(@Vector(2, u500), .{ undefined, 6 })
948// @as(@Vector(2, u32), undefined)948// @as(@Vector(2, u500), undefined)
949// @as(@Vector(2, u32), .{ undefined, 6 })949// @as(@Vector(2, u500), .{ undefined, 6 })
950// @as(@Vector(2, u32), undefined)950// @as(@Vector(2, u500), undefined)
951// @as(@Vector(2, u32), undefined)951// @as(@Vector(2, u500), undefined)
952// @as(@Vector(2, u32), undefined)952// @as(@Vector(2, u500), undefined)
953// @as(@Vector(2, u32), undefined)953// @as(@Vector(2, u500), undefined)
954// @as(@Vector(2, u32), undefined)954// @as(@Vector(2, u500), undefined)
955// @as(u32, undefined)955// @as(u500, undefined)
956// @as(u32, undefined)956// @as(u500, undefined)
957// @as(@Vector(2, u32), .{ 6, undefined })957// @as(@Vector(2, u500), .{ 6, undefined })
958// @as(@Vector(2, u32), .{ undefined, 6 })958// @as(@Vector(2, u500), .{ undefined, 6 })
959// @as(@Vector(2, u32), undefined)959// @as(@Vector(2, u500), undefined)
960// @as(@Vector(2, u32), .{ 6, undefined })960// @as(@Vector(2, u500), .{ 6, undefined })
961// @as(@Vector(2, u32), .{ 6, undefined })961// @as(@Vector(2, u500), .{ 6, undefined })
962// @as(@Vector(2, u32), undefined)962// @as(@Vector(2, u500), undefined)
963// @as(@Vector(2, u32), undefined)963// @as(@Vector(2, u500), undefined)
964// @as(@Vector(2, u32), .{ undefined, 6 })964// @as(@Vector(2, u500), .{ undefined, 6 })
965// @as(@Vector(2, u32), undefined)965// @as(@Vector(2, u500), undefined)
966// @as(@Vector(2, u32), .{ undefined, 6 })966// @as(@Vector(2, u500), .{ undefined, 6 })
967// @as(@Vector(2, u32), undefined)967// @as(@Vector(2, u500), undefined)
968// @as(@Vector(2, u32), undefined)968// @as(@Vector(2, u500), undefined)
969// @as(@Vector(2, u32), undefined)969// @as(@Vector(2, u500), undefined)
970// @as(@Vector(2, u32), undefined)970// @as(@Vector(2, u500), undefined)
971// @as(@Vector(2, u32), undefined)971// @as(@Vector(2, u500), undefined)
972// @as(u32, undefined)972// @as(u500, undefined)
973// @as(u32, undefined)973// @as(u500, undefined)
974// @as(@Vector(2, u32), .{ 0, undefined })974// @as(@Vector(2, u500), .{ 0, undefined })
975// @as(@Vector(2, u32), .{ undefined, 0 })975// @as(@Vector(2, u500), .{ undefined, 0 })
976// @as(@Vector(2, u32), undefined)976// @as(@Vector(2, u500), undefined)
977// @as(@Vector(2, u32), .{ 0, undefined })977// @as(@Vector(2, u500), .{ 0, undefined })
978// @as(@Vector(2, u32), .{ 0, undefined })978// @as(@Vector(2, u500), .{ 0, undefined })
979// @as(@Vector(2, u32), undefined)979// @as(@Vector(2, u500), undefined)
980// @as(@Vector(2, u32), undefined)980// @as(@Vector(2, u500), undefined)
981// @as(@Vector(2, u32), .{ undefined, 0 })981// @as(@Vector(2, u500), .{ undefined, 0 })
982// @as(@Vector(2, u32), undefined)982// @as(@Vector(2, u500), undefined)
983// @as(@Vector(2, u32), .{ undefined, 0 })983// @as(@Vector(2, u500), .{ undefined, 0 })
984// @as(@Vector(2, u32), undefined)984// @as(@Vector(2, u500), undefined)
985// @as(@Vector(2, u32), undefined)985// @as(@Vector(2, u500), undefined)
986// @as(@Vector(2, u32), undefined)986// @as(@Vector(2, u500), undefined)
987// @as(@Vector(2, u32), undefined)987// @as(@Vector(2, u500), undefined)
988// @as(@Vector(2, u32), undefined)988// @as(@Vector(2, u500), undefined)
989// @as(u32, undefined)989// @as(u500, undefined)
990// @as(u32, undefined)990// @as(u500, undefined)
991// @as(@Vector(2, u32), .{ 0, undefined })991// @as(@Vector(2, u500), .{ 0, undefined })
992// @as(@Vector(2, u32), .{ undefined, 0 })992// @as(@Vector(2, u500), .{ undefined, 0 })
993// @as(@Vector(2, u32), undefined)993// @as(@Vector(2, u500), undefined)
994// @as(@Vector(2, u32), .{ 0, undefined })994// @as(@Vector(2, u500), .{ 0, undefined })
995// @as(@Vector(2, u32), .{ 0, undefined })995// @as(@Vector(2, u500), .{ 0, undefined })
996// @as(@Vector(2, u32), undefined)996// @as(@Vector(2, u500), undefined)
997// @as(@Vector(2, u32), undefined)997// @as(@Vector(2, u500), undefined)
998// @as(@Vector(2, u32), .{ undefined, 0 })998// @as(@Vector(2, u500), .{ undefined, 0 })
999// @as(@Vector(2, u32), undefined)999// @as(@Vector(2, u500), undefined)
1000// @as(@Vector(2, u32), .{ undefined, 0 })1000// @as(@Vector(2, u500), .{ undefined, 0 })
1001// @as(@Vector(2, u32), undefined)1001// @as(@Vector(2, u500), undefined)
1002// @as(@Vector(2, u32), undefined)1002// @as(@Vector(2, u500), undefined)
1003// @as(@Vector(2, u32), undefined)1003// @as(@Vector(2, u500), undefined)
1004// @as(@Vector(2, u32), undefined)1004// @as(@Vector(2, u500), undefined)
1005// @as(@Vector(2, u32), undefined)1005// @as(@Vector(2, u500), undefined)
1006// @as(u32, undefined)1006// @as(u500, undefined)
1007// @as(u32, undefined)1007// @as(u500, undefined)
1008// @as(@Vector(2, u32), .{ 9, undefined })1008// @as(@Vector(2, u500), .{ 9, undefined })
1009// @as(@Vector(2, u32), .{ undefined, 9 })1009// @as(@Vector(2, u500), .{ undefined, 9 })
1010// @as(@Vector(2, u32), undefined)1010// @as(@Vector(2, u500), undefined)
1011// @as(@Vector(2, u32), .{ 9, undefined })1011// @as(@Vector(2, u500), .{ 9, undefined })
1012// @as(@Vector(2, u32), .{ 9, undefined })1012// @as(@Vector(2, u500), .{ 9, undefined })
1013// @as(@Vector(2, u32), undefined)1013// @as(@Vector(2, u500), undefined)
1014// @as(@Vector(2, u32), undefined)1014// @as(@Vector(2, u500), undefined)
1015// @as(@Vector(2, u32), .{ undefined, 9 })1015// @as(@Vector(2, u500), .{ undefined, 9 })
1016// @as(@Vector(2, u32), undefined)1016// @as(@Vector(2, u500), undefined)
1017// @as(@Vector(2, u32), .{ undefined, 9 })1017// @as(@Vector(2, u500), .{ undefined, 9 })
1018// @as(@Vector(2, u32), undefined)1018// @as(@Vector(2, u500), undefined)
1019// @as(@Vector(2, u32), undefined)1019// @as(@Vector(2, u500), undefined)
1020// @as(@Vector(2, u32), undefined)1020// @as(@Vector(2, u500), undefined)
1021// @as(@Vector(2, u32), undefined)1021// @as(@Vector(2, u500), undefined)
1022// @as(@Vector(2, u32), undefined)1022// @as(@Vector(2, u500), undefined)
1023// @as(u32, undefined)1023// @as(u500, undefined)
1024// @as(u32, undefined)1024// @as(u500, undefined)
1025// @as(@Vector(2, u32), .{ 9, undefined })1025// @as(@Vector(2, u500), .{ 9, undefined })
1026// @as(@Vector(2, u32), .{ undefined, 9 })1026// @as(@Vector(2, u500), .{ undefined, 9 })
1027// @as(@Vector(2, u32), undefined)1027// @as(@Vector(2, u500), undefined)
1028// @as(@Vector(2, u32), .{ 9, undefined })1028// @as(@Vector(2, u500), .{ 9, undefined })
1029// @as(@Vector(2, u32), .{ 9, undefined })1029// @as(@Vector(2, u500), .{ 9, undefined })
1030// @as(@Vector(2, u32), undefined)1030// @as(@Vector(2, u500), undefined)
1031// @as(@Vector(2, u32), undefined)1031// @as(@Vector(2, u500), undefined)
1032// @as(@Vector(2, u32), .{ undefined, 9 })1032// @as(@Vector(2, u500), .{ undefined, 9 })
1033// @as(@Vector(2, u32), undefined)1033// @as(@Vector(2, u500), undefined)
1034// @as(@Vector(2, u32), .{ undefined, 9 })1034// @as(@Vector(2, u500), .{ undefined, 9 })
1035// @as(@Vector(2, u32), undefined)1035// @as(@Vector(2, u500), undefined)
1036// @as(@Vector(2, u32), undefined)1036// @as(@Vector(2, u500), undefined)
1037// @as(@Vector(2, u32), undefined)1037// @as(@Vector(2, u500), undefined)
1038// @as(@Vector(2, u32), undefined)1038// @as(@Vector(2, u500), undefined)
1039// @as(@Vector(2, u32), undefined)1039// @as(@Vector(2, u500), undefined)
1040// @as(u32, undefined)1040// @as(u500, undefined)
1041// @as(u32, undefined)1041// @as(u500, undefined)
1042// @as(@Vector(2, u32), .{ 24, undefined })1042// @as(@Vector(2, u500), .{ 24, undefined })
1043// @as(@Vector(2, u32), .{ undefined, 24 })1043// @as(@Vector(2, u500), .{ undefined, 24 })
1044// @as(@Vector(2, u32), undefined)1044// @as(@Vector(2, u500), undefined)
1045// @as(@Vector(2, u32), .{ 24, undefined })1045// @as(@Vector(2, u500), .{ 24, undefined })
1046// @as(@Vector(2, u32), .{ 24, undefined })1046// @as(@Vector(2, u500), .{ 24, undefined })
1047// @as(@Vector(2, u32), undefined)1047// @as(@Vector(2, u500), undefined)
1048// @as(@Vector(2, u32), undefined)1048// @as(@Vector(2, u500), undefined)
1049// @as(@Vector(2, u32), .{ undefined, 24 })1049// @as(@Vector(2, u500), .{ undefined, 24 })
1050// @as(@Vector(2, u32), undefined)1050// @as(@Vector(2, u500), undefined)
1051// @as(@Vector(2, u32), .{ undefined, 24 })1051// @as(@Vector(2, u500), .{ undefined, 24 })
1052// @as(@Vector(2, u32), undefined)1052// @as(@Vector(2, u500), undefined)
1053// @as(@Vector(2, u32), undefined)1053// @as(@Vector(2, u500), undefined)
1054// @as(@Vector(2, u32), undefined)1054// @as(@Vector(2, u500), undefined)
1055// @as(@Vector(2, u32), undefined)1055// @as(@Vector(2, u500), undefined)
1056// @as(@Vector(2, u32), undefined)1056// @as(@Vector(2, u500), undefined)
1057// @as(u32, undefined)1057// @as(u500, undefined)
1058// @as(u32, undefined)1058// @as(u500, undefined)
1059// @as(@Vector(2, u32), .{ 0, undefined })1059// @as(@Vector(2, u500), .{ 0, undefined })
1060// @as(@Vector(2, u32), .{ undefined, 0 })1060// @as(@Vector(2, u500), .{ undefined, 0 })
1061// @as(@Vector(2, u32), undefined)1061// @as(@Vector(2, u500), undefined)
1062// @as(@Vector(2, u32), .{ 0, undefined })1062// @as(@Vector(2, u500), .{ 0, undefined })
1063// @as(@Vector(2, u32), .{ 0, undefined })1063// @as(@Vector(2, u500), .{ 0, undefined })
1064// @as(@Vector(2, u32), undefined)1064// @as(@Vector(2, u500), undefined)
1065// @as(@Vector(2, u32), undefined)1065// @as(@Vector(2, u500), undefined)
1066// @as(@Vector(2, u32), .{ undefined, 0 })1066// @as(@Vector(2, u500), .{ undefined, 0 })
1067// @as(@Vector(2, u32), undefined)1067// @as(@Vector(2, u500), undefined)
1068// @as(@Vector(2, u32), .{ undefined, 0 })1068// @as(@Vector(2, u500), .{ undefined, 0 })
1069// @as(@Vector(2, u32), undefined)1069// @as(@Vector(2, u500), undefined)
1070// @as(@Vector(2, u32), undefined)1070// @as(@Vector(2, u500), undefined)
1071// @as(@Vector(2, u32), undefined)1071// @as(@Vector(2, u500), undefined)
1072// @as(@Vector(2, u32), undefined)1072// @as(@Vector(2, u500), undefined)
1073// @as(@Vector(2, u32), undefined)1073// @as(@Vector(2, u500), undefined)
1074// @as(u32, undefined)1074// @as(u500, undefined)
1075// @as(@Vector(2, u32), undefined)1075// @as(@Vector(2, u500), undefined)
1076// @as(u32, undefined)1076// @as(u500, undefined)
1077// @as(u32, undefined)1077// @as(u500, undefined)
1078// @as(@Vector(2, u32), undefined)1078// @as(@Vector(2, u500), undefined)
1079// @as(@Vector(2, u32), undefined)1079// @as(@Vector(2, u500), undefined)
1080// @as(u1, undefined)1080// @as(u1, undefined)
1081// @as(@Vector(2, u1), .{ 1, undefined })1081// @as(@Vector(2, u1), .{ 1, undefined })
1082// @as(@Vector(2, u1), .{ undefined, 1 })1082// @as(@Vector(2, u1), .{ undefined, 1 })
1083// @as(@Vector(2, u1), undefined)1083// @as(@Vector(2, u1), undefined)
1084// @as(u32, undefined)1084// @as(u500, undefined)
1085// @as(@Vector(2, u32), undefined)1085// @as(@Vector(2, u500), undefined)
1086// @as(u32, undefined)1086// @as(u500, undefined)
1087// @as(u32, undefined)1087// @as(u500, undefined)
1088// @as(@Vector(2, u32), [runtime value])1088// @as(@Vector(2, u500), [runtime value])
1089// @as(@Vector(2, u32), [runtime value])1089// @as(@Vector(2, u500), [runtime value])
1090// @as(@Vector(2, u32), undefined)1090// @as(@Vector(2, u500), undefined)
1091// @as(@Vector(2, u32), [runtime value])1091// @as(@Vector(2, u500), [runtime value])
1092// @as(@Vector(2, u32), [runtime value])1092// @as(@Vector(2, u500), [runtime value])
1093// @as(@Vector(2, u32), [runtime value])1093// @as(@Vector(2, u500), [runtime value])
1094// @as(@Vector(2, u32), undefined)1094// @as(@Vector(2, u500), undefined)
1095// @as(@Vector(2, u32), [runtime value])1095// @as(@Vector(2, u500), [runtime value])
1096// @as(@Vector(2, u32), [runtime value])1096// @as(@Vector(2, u500), [runtime value])
1097// @as(@Vector(2, u32), [runtime value])1097// @as(@Vector(2, u500), [runtime value])
1098// @as(@Vector(2, u32), undefined)1098// @as(@Vector(2, u500), undefined)
1099// @as(@Vector(2, u32), undefined)1099// @as(@Vector(2, u500), undefined)
1100// @as(@Vector(2, u32), undefined)1100// @as(@Vector(2, u500), undefined)
1101// @as(@Vector(2, u32), undefined)1101// @as(@Vector(2, u500), undefined)
1102// @as(@Vector(2, u32), undefined)1102// @as(@Vector(2, u500), undefined)
1103// @as(u32, undefined)1103// @as(u500, undefined)
1104// @as(u32, undefined)1104// @as(u500, undefined)
1105// @as(@Vector(2, u32), [runtime value])1105// @as(@Vector(2, u500), [runtime value])
1106// @as(@Vector(2, u32), [runtime value])1106// @as(@Vector(2, u500), [runtime value])
1107// @as(@Vector(2, u32), undefined)1107// @as(@Vector(2, u500), undefined)
1108// @as(@Vector(2, u32), [runtime value])1108// @as(@Vector(2, u500), [runtime value])
1109// @as(@Vector(2, u32), [runtime value])1109// @as(@Vector(2, u500), [runtime value])
1110// @as(@Vector(2, u32), [runtime value])1110// @as(@Vector(2, u500), [runtime value])
1111// @as(@Vector(2, u32), undefined)1111// @as(@Vector(2, u500), undefined)
1112// @as(@Vector(2, u32), [runtime value])1112// @as(@Vector(2, u500), [runtime value])
1113// @as(@Vector(2, u32), [runtime value])1113// @as(@Vector(2, u500), [runtime value])
1114// @as(@Vector(2, u32), [runtime value])1114// @as(@Vector(2, u500), [runtime value])
1115// @as(@Vector(2, u32), undefined)1115// @as(@Vector(2, u500), undefined)
1116// @as(@Vector(2, u32), undefined)1116// @as(@Vector(2, u500), undefined)
1117// @as(@Vector(2, u32), undefined)1117// @as(@Vector(2, u500), undefined)
1118// @as(@Vector(2, u32), undefined)1118// @as(@Vector(2, u500), undefined)
1119// @as(@Vector(2, u32), undefined)1119// @as(@Vector(2, u500), undefined)
1120// @as(u32, undefined)1120// @as(u500, undefined)
1121// @as(u32, undefined)1121// @as(u500, undefined)
1122// @as(@Vector(2, u32), [runtime value])1122// @as(@Vector(2, u500), [runtime value])
1123// @as(@Vector(2, u32), [runtime value])1123// @as(@Vector(2, u500), [runtime value])
1124// @as(@Vector(2, u32), undefined)1124// @as(@Vector(2, u500), undefined)
1125// @as(@Vector(2, u32), [runtime value])1125// @as(@Vector(2, u500), [runtime value])
1126// @as(@Vector(2, u32), [runtime value])1126// @as(@Vector(2, u500), [runtime value])
1127// @as(@Vector(2, u32), [runtime value])1127// @as(@Vector(2, u500), [runtime value])
1128// @as(@Vector(2, u32), undefined)1128// @as(@Vector(2, u500), undefined)
1129// @as(@Vector(2, u32), [runtime value])1129// @as(@Vector(2, u500), [runtime value])
1130// @as(@Vector(2, u32), [runtime value])1130// @as(@Vector(2, u500), [runtime value])
1131// @as(@Vector(2, u32), [runtime value])1131// @as(@Vector(2, u500), [runtime value])
1132// @as(@Vector(2, u32), undefined)1132// @as(@Vector(2, u500), undefined)
1133// @as(@Vector(2, u32), undefined)1133// @as(@Vector(2, u500), undefined)
1134// @as(@Vector(2, u32), undefined)1134// @as(@Vector(2, u500), undefined)
1135// @as(@Vector(2, u32), undefined)1135// @as(@Vector(2, u500), undefined)
1136// @as(@Vector(2, u32), undefined)1136// @as(@Vector(2, u500), undefined)
1137// @as(u32, undefined)1137// @as(u500, undefined)
1138// @as(u32, undefined)1138// @as(u500, undefined)
1139// @as(@Vector(2, u32), [runtime value])1139// @as(@Vector(2, u500), [runtime value])
1140// @as(@Vector(2, u32), [runtime value])1140// @as(@Vector(2, u500), [runtime value])
1141// @as(@Vector(2, u32), undefined)1141// @as(@Vector(2, u500), undefined)
1142// @as(@Vector(2, u32), [runtime value])1142// @as(@Vector(2, u500), [runtime value])
1143// @as(@Vector(2, u32), [runtime value])1143// @as(@Vector(2, u500), [runtime value])
1144// @as(@Vector(2, u32), [runtime value])1144// @as(@Vector(2, u500), [runtime value])
1145// @as(@Vector(2, u32), undefined)1145// @as(@Vector(2, u500), undefined)
1146// @as(@Vector(2, u32), [runtime value])1146// @as(@Vector(2, u500), [runtime value])
1147// @as(@Vector(2, u32), [runtime value])1147// @as(@Vector(2, u500), [runtime value])
1148// @as(@Vector(2, u32), [runtime value])1148// @as(@Vector(2, u500), [runtime value])
1149// @as(@Vector(2, u32), undefined)1149// @as(@Vector(2, u500), undefined)
1150// @as(@Vector(2, u32), undefined)1150// @as(@Vector(2, u500), undefined)
1151// @as(@Vector(2, u32), undefined)1151// @as(@Vector(2, u500), undefined)
1152// @as(@Vector(2, u32), undefined)1152// @as(@Vector(2, u500), undefined)
1153// @as(@Vector(2, u32), undefined)1153// @as(@Vector(2, u500), undefined)
1154// @as(u32, undefined)1154// @as(u500, undefined)
1155// @as(u32, undefined)1155// @as(u500, undefined)
1156// @as(@Vector(2, u32), [runtime value])1156// @as(@Vector(2, u500), [runtime value])
1157// @as(@Vector(2, u32), [runtime value])1157// @as(@Vector(2, u500), [runtime value])
1158// @as(@Vector(2, u32), undefined)1158// @as(@Vector(2, u500), undefined)
1159// @as(@Vector(2, u32), [runtime value])1159// @as(@Vector(2, u500), [runtime value])
1160// @as(@Vector(2, u32), [runtime value])1160// @as(@Vector(2, u500), [runtime value])
1161// @as(@Vector(2, u32), [runtime value])1161// @as(@Vector(2, u500), [runtime value])
1162// @as(@Vector(2, u32), undefined)1162// @as(@Vector(2, u500), undefined)
1163// @as(@Vector(2, u32), [runtime value])1163// @as(@Vector(2, u500), [runtime value])
1164// @as(@Vector(2, u32), [runtime value])1164// @as(@Vector(2, u500), [runtime value])
1165// @as(@Vector(2, u32), [runtime value])1165// @as(@Vector(2, u500), [runtime value])
1166// @as(@Vector(2, u32), undefined)1166// @as(@Vector(2, u500), undefined)
1167// @as(@Vector(2, u32), undefined)1167// @as(@Vector(2, u500), undefined)
1168// @as(@Vector(2, u32), undefined)1168// @as(@Vector(2, u500), undefined)
1169// @as(@Vector(2, u32), undefined)1169// @as(@Vector(2, u500), undefined)
1170// @as(@Vector(2, u32), undefined)1170// @as(@Vector(2, u500), undefined)
1171// @as(u32, undefined)1171// @as(u500, undefined)
1172// @as(u32, undefined)1172// @as(u500, undefined)
1173// @as(@Vector(2, u32), [runtime value])1173// @as(@Vector(2, u500), [runtime value])
1174// @as(@Vector(2, u32), [runtime value])1174// @as(@Vector(2, u500), [runtime value])
1175// @as(@Vector(2, u32), undefined)1175// @as(@Vector(2, u500), undefined)
1176// @as(@Vector(2, u32), [runtime value])1176// @as(@Vector(2, u500), [runtime value])
1177// @as(@Vector(2, u32), [runtime value])1177// @as(@Vector(2, u500), [runtime value])
1178// @as(@Vector(2, u32), [runtime value])1178// @as(@Vector(2, u500), [runtime value])
1179// @as(@Vector(2, u32), undefined)1179// @as(@Vector(2, u500), undefined)
1180// @as(@Vector(2, u32), [runtime value])1180// @as(@Vector(2, u500), [runtime value])
1181// @as(@Vector(2, u32), [runtime value])1181// @as(@Vector(2, u500), [runtime value])
1182// @as(@Vector(2, u32), [runtime value])1182// @as(@Vector(2, u500), [runtime value])
1183// @as(@Vector(2, u32), undefined)1183// @as(@Vector(2, u500), undefined)
1184// @as(@Vector(2, u32), undefined)1184// @as(@Vector(2, u500), undefined)
1185// @as(@Vector(2, u32), undefined)1185// @as(@Vector(2, u500), undefined)
1186// @as(@Vector(2, u32), undefined)1186// @as(@Vector(2, u500), undefined)
1187// @as(@Vector(2, u32), undefined)1187// @as(@Vector(2, u500), undefined)
1188// @as(u32, undefined)1188// @as(u500, undefined)
1189// @as(u32, undefined)1189// @as(u500, undefined)
1190// @as(@Vector(2, u32), [runtime value])1190// @as(@Vector(2, u500), [runtime value])
1191// @as(@Vector(2, u32), [runtime value])1191// @as(@Vector(2, u500), [runtime value])
1192// @as(@Vector(2, u32), undefined)1192// @as(@Vector(2, u500), undefined)
1193// @as(@Vector(2, u32), [runtime value])1193// @as(@Vector(2, u500), [runtime value])
1194// @as(@Vector(2, u32), [runtime value])1194// @as(@Vector(2, u500), [runtime value])
1195// @as(@Vector(2, u32), [runtime value])1195// @as(@Vector(2, u500), [runtime value])
1196// @as(@Vector(2, u32), undefined)1196// @as(@Vector(2, u500), undefined)
1197// @as(@Vector(2, u32), [runtime value])1197// @as(@Vector(2, u500), [runtime value])
1198// @as(@Vector(2, u32), [runtime value])1198// @as(@Vector(2, u500), [runtime value])
1199// @as(@Vector(2, u32), [runtime value])1199// @as(@Vector(2, u500), [runtime value])
1200// @as(@Vector(2, u32), undefined)1200// @as(@Vector(2, u500), undefined)
1201// @as(@Vector(2, u32), undefined)1201// @as(@Vector(2, u500), undefined)
1202// @as(@Vector(2, u32), undefined)1202// @as(@Vector(2, u500), undefined)
1203// @as(@Vector(2, u32), undefined)1203// @as(@Vector(2, u500), undefined)
1204// @as(@Vector(2, u32), undefined)1204// @as(@Vector(2, u500), undefined)
1205// @as(u32, [runtime value])1205// @as(u500, [runtime value])
1206// @as(u32, [runtime value])1206// @as(u500, [runtime value])
1207// @as(@Vector(2, u32), [runtime value])1207// @as(@Vector(2, u500), [runtime value])
1208// @as(@Vector(2, u32), [runtime value])1208// @as(@Vector(2, u500), [runtime value])
1209// @as(@Vector(2, u32), [runtime value])1209// @as(@Vector(2, u500), [runtime value])
1210// @as(@Vector(2, u32), [runtime value])1210// @as(@Vector(2, u500), [runtime value])
1211// @as(@Vector(2, u32), [runtime value])1211// @as(@Vector(2, u500), [runtime value])
1212// @as(@Vector(2, u32), [runtime value])1212// @as(@Vector(2, u500), [runtime value])
1213// @as(@Vector(2, u32), [runtime value])1213// @as(@Vector(2, u500), [runtime value])
1214// @as(@Vector(2, u32), [runtime value])1214// @as(@Vector(2, u500), [runtime value])
1215// @as(@Vector(2, u32), [runtime value])1215// @as(@Vector(2, u500), [runtime value])
1216// @as(@Vector(2, u32), [runtime value])1216// @as(@Vector(2, u500), [runtime value])
1217// @as(@Vector(2, u32), [runtime value])1217// @as(@Vector(2, u500), [runtime value])
1218// @as(@Vector(2, u32), [runtime value])1218// @as(@Vector(2, u500), [runtime value])
1219// @as(@Vector(2, u32), [runtime value])1219// @as(@Vector(2, u500), [runtime value])
1220// @as(@Vector(2, u32), [runtime value])1220// @as(@Vector(2, u500), [runtime value])
1221// @as(@Vector(2, u32), undefined)1221// @as(@Vector(2, u500), undefined)
1222// @as(u32, undefined)1222// @as(u500, undefined)
1223// @as(@Vector(2, u32), undefined)1223// @as(@Vector(2, u500), undefined)
1224// @as(u32, undefined)1224// @as(u500, undefined)
1225// @as(u32, undefined)1225// @as(u500, undefined)
1226// @as(@Vector(2, u32), undefined)1226// @as(@Vector(2, u500), undefined)
1227// @as(@Vector(2, u32), undefined)1227// @as(@Vector(2, u500), undefined)
1228// @as(u1, undefined)1228// @as(u1, undefined)
1229// @as(@Vector(2, u1), [runtime value])1229// @as(@Vector(2, u1), [runtime value])
1230// @as(@Vector(2, u1), [runtime value])1230// @as(@Vector(2, u1), [runtime value])
1231// @as(@Vector(2, u1), undefined)1231// @as(@Vector(2, u1), undefined)
1232// @as(u32, undefined)1232// @as(u500, undefined)
1233// @as(@Vector(2, u32), undefined)1233// @as(@Vector(2, u500), undefined)
1234// @as(i32, undefined)1234// @as(i32, undefined)
1235// @as(i32, undefined)1235// @as(i32, undefined)
1236// @as(@Vector(2, i32), .{ 6, undefined })1236// @as(@Vector(2, i32), .{ 6, undefined })
1237// @as(@Vector(2, i32), .{ undefined, 6 })1237// @as(@Vector(2, i32), .{ undefined, 6 })
1238// @as(@Vector(2, i32), undefined)1238// @as(@Vector(2, i32), undefined)
1239// @as(@Vector(2, i32), .{ 6, undefined })1239// @as(@Vector(2, i32), .{ 6, undefined })
1240// @as(@Vector(2, i32), .{ 6, undefined })1240// @as(@Vector(2, i32), .{ 6, undefined })
1241// @as(@Vector(2, i32), undefined)1241// @as(@Vector(2, i32), undefined)
1242// @as(@Vector(2, i32), undefined)1242// @as(@Vector(2, i32), undefined)
1243// @as(@Vector(2, i32), .{ undefined, 6 })1243// @as(@Vector(2, i32), .{ undefined, 6 })
1244// @as(@Vector(2, i32), undefined)1244// @as(@Vector(2, i32), undefined)
1245// @as(@Vector(2, i32), .{ undefined, 6 })1245// @as(@Vector(2, i32), .{ undefined, 6 })
1246// @as(@Vector(2, i32), undefined)1246// @as(@Vector(2, i32), undefined)
1247// @as(@Vector(2, i32), undefined)1247// @as(@Vector(2, i32), undefined)
1248// @as(@Vector(2, i32), undefined)1248// @as(@Vector(2, i32), undefined)
1249// @as(@Vector(2, i32), undefined)1249// @as(@Vector(2, i32), undefined)
1250// @as(@Vector(2, i32), undefined)1250// @as(@Vector(2, i32), undefined)
1251// @as(i32, undefined)1251// @as(i32, undefined)
1252// @as(i32, undefined)1252// @as(i32, undefined)
1253// @as(@Vector(2, i32), .{ 6, undefined })1253// @as(@Vector(2, i32), .{ 6, undefined })
1254// @as(@Vector(2, i32), .{ undefined, 6 })1254// @as(@Vector(2, i32), .{ undefined, 6 })
1255// @as(@Vector(2, i32), undefined)1255// @as(@Vector(2, i32), undefined)
1256// @as(@Vector(2, i32), .{ 6, undefined })1256// @as(@Vector(2, i32), .{ 6, undefined })
1257// @as(@Vector(2, i32), .{ 6, undefined })1257// @as(@Vector(2, i32), .{ 6, undefined })
1258// @as(@Vector(2, i32), undefined)1258// @as(@Vector(2, i32), undefined)
1259// @as(@Vector(2, i32), undefined)1259// @as(@Vector(2, i32), undefined)
1260// @as(@Vector(2, i32), .{ undefined, 6 })1260// @as(@Vector(2, i32), .{ undefined, 6 })
1261// @as(@Vector(2, i32), undefined)1261// @as(@Vector(2, i32), undefined)
1262// @as(@Vector(2, i32), .{ undefined, 6 })1262// @as(@Vector(2, i32), .{ undefined, 6 })
1263// @as(@Vector(2, i32), undefined)1263// @as(@Vector(2, i32), undefined)
1264// @as(@Vector(2, i32), undefined)1264// @as(@Vector(2, i32), undefined)
1265// @as(@Vector(2, i32), undefined)1265// @as(@Vector(2, i32), undefined)
1266// @as(@Vector(2, i32), undefined)1266// @as(@Vector(2, i32), undefined)
1267// @as(@Vector(2, i32), undefined)1267// @as(@Vector(2, i32), undefined)
1268// @as(i32, undefined)1268// @as(i32, undefined)
1269// @as(i32, undefined)1269// @as(i32, undefined)
1270// @as(@Vector(2, i32), .{ 0, undefined })1270// @as(@Vector(2, i32), .{ 0, undefined })
1271// @as(@Vector(2, i32), .{ undefined, 0 })1271// @as(@Vector(2, i32), .{ undefined, 0 })
1272// @as(@Vector(2, i32), undefined)1272// @as(@Vector(2, i32), undefined)
1273// @as(@Vector(2, i32), .{ 0, undefined })1273// @as(@Vector(2, i32), .{ 0, undefined })
1274// @as(@Vector(2, i32), .{ 0, undefined })1274// @as(@Vector(2, i32), .{ 0, undefined })
1275// @as(@Vector(2, i32), undefined)1275// @as(@Vector(2, i32), undefined)
1276// @as(@Vector(2, i32), undefined)1276// @as(@Vector(2, i32), undefined)
1277// @as(@Vector(2, i32), .{ undefined, 0 })1277// @as(@Vector(2, i32), .{ undefined, 0 })
1278// @as(@Vector(2, i32), undefined)1278// @as(@Vector(2, i32), undefined)
1279// @as(@Vector(2, i32), .{ undefined, 0 })1279// @as(@Vector(2, i32), .{ undefined, 0 })
1280// @as(@Vector(2, i32), undefined)1280// @as(@Vector(2, i32), undefined)
1281// @as(@Vector(2, i32), undefined)1281// @as(@Vector(2, i32), undefined)
1282// @as(@Vector(2, i32), undefined)1282// @as(@Vector(2, i32), undefined)
1283// @as(@Vector(2, i32), undefined)1283// @as(@Vector(2, i32), undefined)
1284// @as(@Vector(2, i32), undefined)1284// @as(@Vector(2, i32), undefined)
1285// @as(i32, undefined)1285// @as(i32, undefined)
1286// @as(i32, undefined)1286// @as(i32, undefined)
1287// @as(@Vector(2, i32), .{ 0, undefined })1287// @as(@Vector(2, i32), .{ 0, undefined })
1288// @as(@Vector(2, i32), .{ undefined, 0 })1288// @as(@Vector(2, i32), .{ undefined, 0 })
1289// @as(@Vector(2, i32), undefined)1289// @as(@Vector(2, i32), undefined)
1290// @as(@Vector(2, i32), .{ 0, undefined })1290// @as(@Vector(2, i32), .{ 0, undefined })
1291// @as(@Vector(2, i32), .{ 0, undefined })1291// @as(@Vector(2, i32), .{ 0, undefined })
1292// @as(@Vector(2, i32), undefined)1292// @as(@Vector(2, i32), undefined)
1293// @as(@Vector(2, i32), undefined)1293// @as(@Vector(2, i32), undefined)
1294// @as(@Vector(2, i32), .{ undefined, 0 })1294// @as(@Vector(2, i32), .{ undefined, 0 })
1295// @as(@Vector(2, i32), undefined)1295// @as(@Vector(2, i32), undefined)
1296// @as(@Vector(2, i32), .{ undefined, 0 })1296// @as(@Vector(2, i32), .{ undefined, 0 })
1297// @as(@Vector(2, i32), undefined)1297// @as(@Vector(2, i32), undefined)
1298// @as(@Vector(2, i32), undefined)1298// @as(@Vector(2, i32), undefined)
1299// @as(@Vector(2, i32), undefined)1299// @as(@Vector(2, i32), undefined)
1300// @as(@Vector(2, i32), undefined)1300// @as(@Vector(2, i32), undefined)
1301// @as(@Vector(2, i32), undefined)1301// @as(@Vector(2, i32), undefined)
1302// @as(i32, undefined)1302// @as(i32, undefined)
1303// @as(i32, undefined)1303// @as(i32, undefined)
1304// @as(@Vector(2, i32), .{ 9, undefined })1304// @as(@Vector(2, i32), .{ 9, undefined })
1305// @as(@Vector(2, i32), .{ undefined, 9 })1305// @as(@Vector(2, i32), .{ undefined, 9 })
1306// @as(@Vector(2, i32), undefined)1306// @as(@Vector(2, i32), undefined)
1307// @as(@Vector(2, i32), .{ 9, undefined })1307// @as(@Vector(2, i32), .{ 9, undefined })
1308// @as(@Vector(2, i32), .{ 9, undefined })1308// @as(@Vector(2, i32), .{ 9, undefined })
1309// @as(@Vector(2, i32), undefined)1309// @as(@Vector(2, i32), undefined)
1310// @as(@Vector(2, i32), undefined)1310// @as(@Vector(2, i32), undefined)
1311// @as(@Vector(2, i32), .{ undefined, 9 })1311// @as(@Vector(2, i32), .{ undefined, 9 })
1312// @as(@Vector(2, i32), undefined)1312// @as(@Vector(2, i32), undefined)
1313// @as(@Vector(2, i32), .{ undefined, 9 })1313// @as(@Vector(2, i32), .{ undefined, 9 })
1314// @as(@Vector(2, i32), undefined)1314// @as(@Vector(2, i32), undefined)
1315// @as(@Vector(2, i32), undefined)1315// @as(@Vector(2, i32), undefined)
1316// @as(@Vector(2, i32), undefined)1316// @as(@Vector(2, i32), undefined)
1317// @as(@Vector(2, i32), undefined)1317// @as(@Vector(2, i32), undefined)
1318// @as(@Vector(2, i32), undefined)1318// @as(@Vector(2, i32), undefined)
1319// @as(i32, undefined)1319// @as(i32, undefined)
1320// @as(i32, undefined)1320// @as(i32, undefined)
1321// @as(@Vector(2, i32), .{ 9, undefined })1321// @as(@Vector(2, i32), .{ 9, undefined })
1322// @as(@Vector(2, i32), .{ undefined, 9 })1322// @as(@Vector(2, i32), .{ undefined, 9 })
1323// @as(@Vector(2, i32), undefined)1323// @as(@Vector(2, i32), undefined)
1324// @as(@Vector(2, i32), .{ 9, undefined })1324// @as(@Vector(2, i32), .{ 9, undefined })
1325// @as(@Vector(2, i32), .{ 9, undefined })1325// @as(@Vector(2, i32), .{ 9, undefined })
1326// @as(@Vector(2, i32), undefined)1326// @as(@Vector(2, i32), undefined)
1327// @as(@Vector(2, i32), undefined)1327// @as(@Vector(2, i32), undefined)
1328// @as(@Vector(2, i32), .{ undefined, 9 })1328// @as(@Vector(2, i32), .{ undefined, 9 })
1329// @as(@Vector(2, i32), undefined)1329// @as(@Vector(2, i32), undefined)
1330// @as(@Vector(2, i32), .{ undefined, 9 })1330// @as(@Vector(2, i32), .{ undefined, 9 })
1331// @as(@Vector(2, i32), undefined)1331// @as(@Vector(2, i32), undefined)
1332// @as(@Vector(2, i32), undefined)1332// @as(@Vector(2, i32), undefined)
1333// @as(@Vector(2, i32), undefined)1333// @as(@Vector(2, i32), undefined)
1334// @as(@Vector(2, i32), undefined)1334// @as(@Vector(2, i32), undefined)
1335// @as(@Vector(2, i32), undefined)1335// @as(@Vector(2, i32), undefined)
1336// @as(i32, undefined)1336// @as(i32, undefined)
1337// @as(i32, undefined)1337// @as(i32, undefined)
1338// @as(@Vector(2, i32), .{ 0, undefined })1338// @as(@Vector(2, i32), .{ 0, undefined })
1339// @as(@Vector(2, i32), .{ undefined, 0 })1339// @as(@Vector(2, i32), .{ undefined, 0 })
1340// @as(@Vector(2, i32), undefined)1340// @as(@Vector(2, i32), undefined)
1341// @as(@Vector(2, i32), .{ 0, undefined })1341// @as(@Vector(2, i32), .{ 0, undefined })
1342// @as(@Vector(2, i32), .{ 0, undefined })1342// @as(@Vector(2, i32), .{ 0, undefined })
1343// @as(@Vector(2, i32), undefined)1343// @as(@Vector(2, i32), undefined)
1344// @as(@Vector(2, i32), undefined)1344// @as(@Vector(2, i32), undefined)
1345// @as(@Vector(2, i32), .{ undefined, 0 })1345// @as(@Vector(2, i32), .{ undefined, 0 })
1346// @as(@Vector(2, i32), undefined)1346// @as(@Vector(2, i32), undefined)
1347// @as(@Vector(2, i32), .{ undefined, 0 })1347// @as(@Vector(2, i32), .{ undefined, 0 })
1348// @as(@Vector(2, i32), undefined)1348// @as(@Vector(2, i32), undefined)
1349// @as(@Vector(2, i32), undefined)1349// @as(@Vector(2, i32), undefined)
1350// @as(@Vector(2, i32), undefined)1350// @as(@Vector(2, i32), undefined)
1351// @as(@Vector(2, i32), undefined)1351// @as(@Vector(2, i32), undefined)
1352// @as(@Vector(2, i32), undefined)1352// @as(@Vector(2, i32), undefined)
1353// @as(i32, undefined)1353// @as(i32, undefined)
1354// @as(@Vector(2, i32), undefined)1354// @as(@Vector(2, i32), undefined)
1355// @as(i32, undefined)1355// @as(i32, undefined)
1356// @as(i32, undefined)1356// @as(i32, undefined)
1357// @as(@Vector(2, i32), undefined)1357// @as(@Vector(2, i32), undefined)
1358// @as(@Vector(2, i32), undefined)1358// @as(@Vector(2, i32), undefined)
1359// @as(i32, undefined)1359// @as(i32, undefined)
1360// @as(@Vector(2, i32), undefined)1360// @as(@Vector(2, i32), undefined)
1361// @as(i32, undefined)1361// @as(i32, undefined)
1362// @as(i32, undefined)1362// @as(i32, undefined)
1363// @as(@Vector(2, i32), [runtime value])1363// @as(@Vector(2, i32), [runtime value])
1364// @as(@Vector(2, i32), [runtime value])1364// @as(@Vector(2, i32), [runtime value])
1365// @as(@Vector(2, i32), undefined)1365// @as(@Vector(2, i32), undefined)
1366// @as(@Vector(2, i32), [runtime value])1366// @as(@Vector(2, i32), [runtime value])
1367// @as(@Vector(2, i32), [runtime value])1367// @as(@Vector(2, i32), [runtime value])
1368// @as(@Vector(2, i32), [runtime value])1368// @as(@Vector(2, i32), [runtime value])
1369// @as(@Vector(2, i32), undefined)1369// @as(@Vector(2, i32), undefined)
1370// @as(@Vector(2, i32), [runtime value])1370// @as(@Vector(2, i32), [runtime value])
1371// @as(@Vector(2, i32), [runtime value])1371// @as(@Vector(2, i32), [runtime value])
1372// @as(@Vector(2, i32), [runtime value])1372// @as(@Vector(2, i32), [runtime value])
1373// @as(@Vector(2, i32), undefined)1373// @as(@Vector(2, i32), undefined)
1374// @as(@Vector(2, i32), undefined)1374// @as(@Vector(2, i32), undefined)
1375// @as(@Vector(2, i32), undefined)1375// @as(@Vector(2, i32), undefined)
1376// @as(@Vector(2, i32), undefined)1376// @as(@Vector(2, i32), undefined)
1377// @as(@Vector(2, i32), undefined)1377// @as(@Vector(2, i32), undefined)
1378// @as(i32, undefined)1378// @as(i32, undefined)
1379// @as(i32, undefined)1379// @as(i32, undefined)
1380// @as(@Vector(2, i32), [runtime value])1380// @as(@Vector(2, i32), [runtime value])
1381// @as(@Vector(2, i32), [runtime value])1381// @as(@Vector(2, i32), [runtime value])
1382// @as(@Vector(2, i32), undefined)1382// @as(@Vector(2, i32), undefined)
1383// @as(@Vector(2, i32), [runtime value])1383// @as(@Vector(2, i32), [runtime value])
1384// @as(@Vector(2, i32), [runtime value])1384// @as(@Vector(2, i32), [runtime value])
1385// @as(@Vector(2, i32), [runtime value])1385// @as(@Vector(2, i32), [runtime value])
1386// @as(@Vector(2, i32), undefined)1386// @as(@Vector(2, i32), undefined)
1387// @as(@Vector(2, i32), [runtime value])1387// @as(@Vector(2, i32), [runtime value])
1388// @as(@Vector(2, i32), [runtime value])1388// @as(@Vector(2, i32), [runtime value])
1389// @as(@Vector(2, i32), [runtime value])1389// @as(@Vector(2, i32), [runtime value])
1390// @as(@Vector(2, i32), undefined)1390// @as(@Vector(2, i32), undefined)
1391// @as(@Vector(2, i32), undefined)1391// @as(@Vector(2, i32), undefined)
1392// @as(@Vector(2, i32), undefined)1392// @as(@Vector(2, i32), undefined)
1393// @as(@Vector(2, i32), undefined)1393// @as(@Vector(2, i32), undefined)
1394// @as(@Vector(2, i32), undefined)1394// @as(@Vector(2, i32), undefined)
1395// @as(i32, undefined)1395// @as(i32, undefined)
1396// @as(i32, undefined)1396// @as(i32, undefined)
1397// @as(@Vector(2, i32), [runtime value])1397// @as(@Vector(2, i32), [runtime value])
1398// @as(@Vector(2, i32), [runtime value])1398// @as(@Vector(2, i32), [runtime value])
1399// @as(@Vector(2, i32), undefined)1399// @as(@Vector(2, i32), undefined)
1400// @as(@Vector(2, i32), [runtime value])1400// @as(@Vector(2, i32), [runtime value])
1401// @as(@Vector(2, i32), [runtime value])1401// @as(@Vector(2, i32), [runtime value])
1402// @as(@Vector(2, i32), [runtime value])1402// @as(@Vector(2, i32), [runtime value])
1403// @as(@Vector(2, i32), undefined)1403// @as(@Vector(2, i32), undefined)
1404// @as(@Vector(2, i32), [runtime value])1404// @as(@Vector(2, i32), [runtime value])
1405// @as(@Vector(2, i32), [runtime value])1405// @as(@Vector(2, i32), [runtime value])
1406// @as(@Vector(2, i32), [runtime value])1406// @as(@Vector(2, i32), [runtime value])
1407// @as(@Vector(2, i32), undefined)1407// @as(@Vector(2, i32), undefined)
1408// @as(@Vector(2, i32), undefined)1408// @as(@Vector(2, i32), undefined)
1409// @as(@Vector(2, i32), undefined)1409// @as(@Vector(2, i32), undefined)
1410// @as(@Vector(2, i32), undefined)1410// @as(@Vector(2, i32), undefined)
1411// @as(@Vector(2, i32), undefined)1411// @as(@Vector(2, i32), undefined)
1412// @as(i32, undefined)1412// @as(i32, undefined)
1413// @as(i32, undefined)1413// @as(i32, undefined)
1414// @as(@Vector(2, i32), [runtime value])1414// @as(@Vector(2, i32), [runtime value])
1415// @as(@Vector(2, i32), [runtime value])1415// @as(@Vector(2, i32), [runtime value])
1416// @as(@Vector(2, i32), undefined)1416// @as(@Vector(2, i32), undefined)
1417// @as(@Vector(2, i32), [runtime value])1417// @as(@Vector(2, i32), [runtime value])
1418// @as(@Vector(2, i32), [runtime value])1418// @as(@Vector(2, i32), [runtime value])
1419// @as(@Vector(2, i32), [runtime value])1419// @as(@Vector(2, i32), [runtime value])
1420// @as(@Vector(2, i32), undefined)1420// @as(@Vector(2, i32), undefined)
1421// @as(@Vector(2, i32), [runtime value])1421// @as(@Vector(2, i32), [runtime value])
1422// @as(@Vector(2, i32), [runtime value])1422// @as(@Vector(2, i32), [runtime value])
1423// @as(@Vector(2, i32), [runtime value])1423// @as(@Vector(2, i32), [runtime value])
1424// @as(@Vector(2, i32), undefined)1424// @as(@Vector(2, i32), undefined)
1425// @as(@Vector(2, i32), undefined)1425// @as(@Vector(2, i32), undefined)
1426// @as(@Vector(2, i32), undefined)1426// @as(@Vector(2, i32), undefined)
1427// @as(@Vector(2, i32), undefined)1427// @as(@Vector(2, i32), undefined)
1428// @as(@Vector(2, i32), undefined)1428// @as(@Vector(2, i32), undefined)
1429// @as(i32, undefined)1429// @as(i32, undefined)
1430// @as(i32, undefined)1430// @as(i32, undefined)
1431// @as(@Vector(2, i32), [runtime value])1431// @as(@Vector(2, i32), [runtime value])
1432// @as(@Vector(2, i32), [runtime value])1432// @as(@Vector(2, i32), [runtime value])
1433// @as(@Vector(2, i32), undefined)1433// @as(@Vector(2, i32), undefined)
1434// @as(@Vector(2, i32), [runtime value])1434// @as(@Vector(2, i32), [runtime value])
1435// @as(@Vector(2, i32), [runtime value])1435// @as(@Vector(2, i32), [runtime value])
1436// @as(@Vector(2, i32), [runtime value])1436// @as(@Vector(2, i32), [runtime value])
1437// @as(@Vector(2, i32), undefined)1437// @as(@Vector(2, i32), undefined)
1438// @as(@Vector(2, i32), [runtime value])1438// @as(@Vector(2, i32), [runtime value])
1439// @as(@Vector(2, i32), [runtime value])1439// @as(@Vector(2, i32), [runtime value])
1440// @as(@Vector(2, i32), [runtime value])1440// @as(@Vector(2, i32), [runtime value])
1441// @as(@Vector(2, i32), undefined)1441// @as(@Vector(2, i32), undefined)
1442// @as(@Vector(2, i32), undefined)1442// @as(@Vector(2, i32), undefined)
1443// @as(@Vector(2, i32), undefined)1443// @as(@Vector(2, i32), undefined)
1444// @as(@Vector(2, i32), undefined)1444// @as(@Vector(2, i32), undefined)
1445// @as(@Vector(2, i32), undefined)1445// @as(@Vector(2, i32), undefined)
1446// @as(i32, undefined)1446// @as(i32, undefined)
1447// @as(i32, undefined)1447// @as(i32, undefined)
1448// @as(@Vector(2, i32), [runtime value])1448// @as(@Vector(2, i32), [runtime value])
1449// @as(@Vector(2, i32), [runtime value])1449// @as(@Vector(2, i32), [runtime value])
1450// @as(@Vector(2, i32), undefined)1450// @as(@Vector(2, i32), undefined)
1451// @as(@Vector(2, i32), [runtime value])1451// @as(@Vector(2, i32), [runtime value])
1452// @as(@Vector(2, i32), [runtime value])1452// @as(@Vector(2, i32), [runtime value])
1453// @as(@Vector(2, i32), [runtime value])1453// @as(@Vector(2, i32), [runtime value])
1454// @as(@Vector(2, i32), undefined)1454// @as(@Vector(2, i32), undefined)
1455// @as(@Vector(2, i32), [runtime value])1455// @as(@Vector(2, i32), [runtime value])
1456// @as(@Vector(2, i32), [runtime value])1456// @as(@Vector(2, i32), [runtime value])
1457// @as(@Vector(2, i32), [runtime value])1457// @as(@Vector(2, i32), [runtime value])
1458// @as(@Vector(2, i32), undefined)1458// @as(@Vector(2, i32), undefined)
1459// @as(@Vector(2, i32), undefined)1459// @as(@Vector(2, i32), undefined)
1460// @as(@Vector(2, i32), undefined)1460// @as(@Vector(2, i32), undefined)
1461// @as(@Vector(2, i32), undefined)1461// @as(@Vector(2, i32), undefined)
1462// @as(@Vector(2, i32), undefined)1462// @as(@Vector(2, i32), undefined)
1463// @as(i32, [runtime value])1463// @as(i32, [runtime value])
1464// @as(i32, [runtime value])1464// @as(i32, [runtime value])
1465// @as(@Vector(2, i32), [runtime value])1465// @as(@Vector(2, i32), [runtime value])
1466// @as(@Vector(2, i32), [runtime value])1466// @as(@Vector(2, i32), [runtime value])
1467// @as(@Vector(2, i32), [runtime value])1467// @as(@Vector(2, i32), [runtime value])
1468// @as(@Vector(2, i32), [runtime value])1468// @as(@Vector(2, i32), [runtime value])
1469// @as(@Vector(2, i32), [runtime value])1469// @as(@Vector(2, i32), [runtime value])
1470// @as(@Vector(2, i32), [runtime value])1470// @as(@Vector(2, i32), [runtime value])
1471// @as(@Vector(2, i32), [runtime value])1471// @as(@Vector(2, i32), [runtime value])
1472// @as(@Vector(2, i32), [runtime value])1472// @as(@Vector(2, i32), [runtime value])
1473// @as(@Vector(2, i32), [runtime value])1473// @as(@Vector(2, i32), [runtime value])
1474// @as(@Vector(2, i32), [runtime value])1474// @as(@Vector(2, i32), [runtime value])
1475// @as(@Vector(2, i32), [runtime value])1475// @as(@Vector(2, i32), [runtime value])
1476// @as(@Vector(2, i32), [runtime value])1476// @as(@Vector(2, i32), [runtime value])
1477// @as(@Vector(2, i32), [runtime value])1477// @as(@Vector(2, i32), [runtime value])
1478// @as(@Vector(2, i32), [runtime value])1478// @as(@Vector(2, i32), [runtime value])
1479// @as(@Vector(2, i32), undefined)1479// @as(@Vector(2, i32), undefined)
1480// @as(i32, undefined)1480// @as(i32, undefined)
1481// @as(@Vector(2, i32), undefined)1481// @as(@Vector(2, i32), undefined)
1482// @as(i32, undefined)1482// @as(i32, undefined)
1483// @as(i32, undefined)1483// @as(i32, undefined)
1484// @as(@Vector(2, i32), undefined)1484// @as(@Vector(2, i32), undefined)
1485// @as(@Vector(2, i32), undefined)1485// @as(@Vector(2, i32), undefined)
1486// @as(i32, undefined)1486// @as(i32, undefined)
1487// @as(@Vector(2, i32), undefined)1487// @as(@Vector(2, i32), undefined)
1488// @as(u500, undefined)1488// @as(u32, undefined)
1489// @as(u500, undefined)1489// @as(u32, undefined)
1490// @as(@Vector(2, u500), .{ 6, undefined })1490// @as(@Vector(2, u32), .{ 6, undefined })
1491// @as(@Vector(2, u500), .{ undefined, 6 })1491// @as(@Vector(2, u32), .{ undefined, 6 })
1492// @as(@Vector(2, u500), undefined)1492// @as(@Vector(2, u32), undefined)
1493// @as(@Vector(2, u500), .{ 6, undefined })1493// @as(@Vector(2, u32), .{ 6, undefined })
1494// @as(@Vector(2, u500), .{ 6, undefined })1494// @as(@Vector(2, u32), .{ 6, undefined })
1495// @as(@Vector(2, u500), undefined)1495// @as(@Vector(2, u32), undefined)
1496// @as(@Vector(2, u500), undefined)1496// @as(@Vector(2, u32), undefined)
1497// @as(@Vector(2, u500), .{ undefined, 6 })1497// @as(@Vector(2, u32), .{ undefined, 6 })
1498// @as(@Vector(2, u500), undefined)1498// @as(@Vector(2, u32), undefined)
1499// @as(@Vector(2, u500), .{ undefined, 6 })1499// @as(@Vector(2, u32), .{ undefined, 6 })
1500// @as(@Vector(2, u500), undefined)1500// @as(@Vector(2, u32), undefined)
1501// @as(@Vector(2, u500), undefined)1501// @as(@Vector(2, u32), undefined)
1502// @as(@Vector(2, u500), undefined)1502// @as(@Vector(2, u32), undefined)
1503// @as(@Vector(2, u500), undefined)1503// @as(@Vector(2, u32), undefined)
1504// @as(@Vector(2, u500), undefined)1504// @as(@Vector(2, u32), undefined)
1505// @as(u500, undefined)1505// @as(u32, undefined)
1506// @as(u500, undefined)1506// @as(u32, undefined)
1507// @as(@Vector(2, u500), .{ 6, undefined })1507// @as(@Vector(2, u32), .{ 6, undefined })
1508// @as(@Vector(2, u500), .{ undefined, 6 })1508// @as(@Vector(2, u32), .{ undefined, 6 })
1509// @as(@Vector(2, u500), undefined)1509// @as(@Vector(2, u32), undefined)
1510// @as(@Vector(2, u500), .{ 6, undefined })1510// @as(@Vector(2, u32), .{ 6, undefined })
1511// @as(@Vector(2, u500), .{ 6, undefined })1511// @as(@Vector(2, u32), .{ 6, undefined })
1512// @as(@Vector(2, u500), undefined)1512// @as(@Vector(2, u32), undefined)
1513// @as(@Vector(2, u500), undefined)1513// @as(@Vector(2, u32), undefined)
1514// @as(@Vector(2, u500), .{ undefined, 6 })1514// @as(@Vector(2, u32), .{ undefined, 6 })
1515// @as(@Vector(2, u500), undefined)1515// @as(@Vector(2, u32), undefined)
1516// @as(@Vector(2, u500), .{ undefined, 6 })1516// @as(@Vector(2, u32), .{ undefined, 6 })
1517// @as(@Vector(2, u500), undefined)1517// @as(@Vector(2, u32), undefined)
1518// @as(@Vector(2, u500), undefined)1518// @as(@Vector(2, u32), undefined)
1519// @as(@Vector(2, u500), undefined)1519// @as(@Vector(2, u32), undefined)
1520// @as(@Vector(2, u500), undefined)1520// @as(@Vector(2, u32), undefined)
1521// @as(@Vector(2, u500), undefined)1521// @as(@Vector(2, u32), undefined)
1522// @as(u500, undefined)1522// @as(u32, undefined)
1523// @as(u500, undefined)1523// @as(u32, undefined)
1524// @as(@Vector(2, u500), .{ 0, undefined })1524// @as(@Vector(2, u32), .{ 0, undefined })
1525// @as(@Vector(2, u500), .{ undefined, 0 })1525// @as(@Vector(2, u32), .{ undefined, 0 })
1526// @as(@Vector(2, u500), undefined)1526// @as(@Vector(2, u32), undefined)
1527// @as(@Vector(2, u500), .{ 0, undefined })1527// @as(@Vector(2, u32), .{ 0, undefined })
1528// @as(@Vector(2, u500), .{ 0, undefined })1528// @as(@Vector(2, u32), .{ 0, undefined })
1529// @as(@Vector(2, u500), undefined)1529// @as(@Vector(2, u32), undefined)
1530// @as(@Vector(2, u500), undefined)1530// @as(@Vector(2, u32), undefined)
1531// @as(@Vector(2, u500), .{ undefined, 0 })1531// @as(@Vector(2, u32), .{ undefined, 0 })
1532// @as(@Vector(2, u500), undefined)1532// @as(@Vector(2, u32), undefined)
1533// @as(@Vector(2, u500), .{ undefined, 0 })1533// @as(@Vector(2, u32), .{ undefined, 0 })
1534// @as(@Vector(2, u500), undefined)1534// @as(@Vector(2, u32), undefined)
1535// @as(@Vector(2, u500), undefined)1535// @as(@Vector(2, u32), undefined)
1536// @as(@Vector(2, u500), undefined)1536// @as(@Vector(2, u32), undefined)
1537// @as(@Vector(2, u500), undefined)1537// @as(@Vector(2, u32), undefined)
1538// @as(@Vector(2, u500), undefined)1538// @as(@Vector(2, u32), undefined)
1539// @as(u500, undefined)1539// @as(u32, undefined)
1540// @as(u500, undefined)1540// @as(u32, undefined)
1541// @as(@Vector(2, u500), .{ 0, undefined })1541// @as(@Vector(2, u32), .{ 0, undefined })
1542// @as(@Vector(2, u500), .{ undefined, 0 })1542// @as(@Vector(2, u32), .{ undefined, 0 })
1543// @as(@Vector(2, u500), undefined)1543// @as(@Vector(2, u32), undefined)
1544// @as(@Vector(2, u500), .{ 0, undefined })1544// @as(@Vector(2, u32), .{ 0, undefined })
1545// @as(@Vector(2, u500), .{ 0, undefined })1545// @as(@Vector(2, u32), .{ 0, undefined })
1546// @as(@Vector(2, u500), undefined)1546// @as(@Vector(2, u32), undefined)
1547// @as(@Vector(2, u500), undefined)1547// @as(@Vector(2, u32), undefined)
1548// @as(@Vector(2, u500), .{ undefined, 0 })1548// @as(@Vector(2, u32), .{ undefined, 0 })
1549// @as(@Vector(2, u500), undefined)1549// @as(@Vector(2, u32), undefined)
1550// @as(@Vector(2, u500), .{ undefined, 0 })1550// @as(@Vector(2, u32), .{ undefined, 0 })
1551// @as(@Vector(2, u500), undefined)1551// @as(@Vector(2, u32), undefined)
1552// @as(@Vector(2, u500), undefined)1552// @as(@Vector(2, u32), undefined)
1553// @as(@Vector(2, u500), undefined)1553// @as(@Vector(2, u32), undefined)
1554// @as(@Vector(2, u500), undefined)1554// @as(@Vector(2, u32), undefined)
1555// @as(@Vector(2, u500), undefined)1555// @as(@Vector(2, u32), undefined)
1556// @as(u500, undefined)1556// @as(u32, undefined)
1557// @as(u500, undefined)1557// @as(u32, undefined)
1558// @as(@Vector(2, u500), .{ 9, undefined })1558// @as(@Vector(2, u32), .{ 9, undefined })
1559// @as(@Vector(2, u500), .{ undefined, 9 })1559// @as(@Vector(2, u32), .{ undefined, 9 })
1560// @as(@Vector(2, u500), undefined)1560// @as(@Vector(2, u32), undefined)
1561// @as(@Vector(2, u500), .{ 9, undefined })1561// @as(@Vector(2, u32), .{ 9, undefined })
1562// @as(@Vector(2, u500), .{ 9, undefined })1562// @as(@Vector(2, u32), .{ 9, undefined })
1563// @as(@Vector(2, u500), undefined)1563// @as(@Vector(2, u32), undefined)
1564// @as(@Vector(2, u500), undefined)1564// @as(@Vector(2, u32), undefined)
1565// @as(@Vector(2, u500), .{ undefined, 9 })1565// @as(@Vector(2, u32), .{ undefined, 9 })
1566// @as(@Vector(2, u500), undefined)1566// @as(@Vector(2, u32), undefined)
1567// @as(@Vector(2, u500), .{ undefined, 9 })1567// @as(@Vector(2, u32), .{ undefined, 9 })
1568// @as(@Vector(2, u500), undefined)1568// @as(@Vector(2, u32), undefined)
1569// @as(@Vector(2, u500), undefined)1569// @as(@Vector(2, u32), undefined)
1570// @as(@Vector(2, u500), undefined)1570// @as(@Vector(2, u32), undefined)
1571// @as(@Vector(2, u500), undefined)1571// @as(@Vector(2, u32), undefined)
1572// @as(@Vector(2, u500), undefined)1572// @as(@Vector(2, u32), undefined)
1573// @as(u500, undefined)1573// @as(u32, undefined)
1574// @as(u500, undefined)1574// @as(u32, undefined)
1575// @as(@Vector(2, u500), .{ 9, undefined })1575// @as(@Vector(2, u32), .{ 9, undefined })
1576// @as(@Vector(2, u500), .{ undefined, 9 })1576// @as(@Vector(2, u32), .{ undefined, 9 })
1577// @as(@Vector(2, u500), undefined)1577// @as(@Vector(2, u32), undefined)
1578// @as(@Vector(2, u500), .{ 9, undefined })1578// @as(@Vector(2, u32), .{ 9, undefined })
1579// @as(@Vector(2, u500), .{ 9, undefined })1579// @as(@Vector(2, u32), .{ 9, undefined })
1580// @as(@Vector(2, u500), undefined)1580// @as(@Vector(2, u32), undefined)
1581// @as(@Vector(2, u500), undefined)1581// @as(@Vector(2, u32), undefined)
1582// @as(@Vector(2, u500), .{ undefined, 9 })1582// @as(@Vector(2, u32), .{ undefined, 9 })
1583// @as(@Vector(2, u500), undefined)1583// @as(@Vector(2, u32), undefined)
1584// @as(@Vector(2, u500), .{ undefined, 9 })1584// @as(@Vector(2, u32), .{ undefined, 9 })
1585// @as(@Vector(2, u500), undefined)1585// @as(@Vector(2, u32), undefined)
1586// @as(@Vector(2, u500), undefined)1586// @as(@Vector(2, u32), undefined)
1587// @as(@Vector(2, u500), undefined)1587// @as(@Vector(2, u32), undefined)
1588// @as(@Vector(2, u500), undefined)1588// @as(@Vector(2, u32), undefined)
1589// @as(@Vector(2, u500), undefined)1589// @as(@Vector(2, u32), undefined)
1590// @as(u500, undefined)1590// @as(u32, undefined)
1591// @as(u500, undefined)1591// @as(u32, undefined)
1592// @as(@Vector(2, u500), .{ 24, undefined })1592// @as(@Vector(2, u32), .{ 24, undefined })
1593// @as(@Vector(2, u500), .{ undefined, 24 })1593// @as(@Vector(2, u32), .{ undefined, 24 })
1594// @as(@Vector(2, u500), undefined)1594// @as(@Vector(2, u32), undefined)
1595// @as(@Vector(2, u500), .{ 24, undefined })1595// @as(@Vector(2, u32), .{ 24, undefined })
1596// @as(@Vector(2, u500), .{ 24, undefined })1596// @as(@Vector(2, u32), .{ 24, undefined })
1597// @as(@Vector(2, u500), undefined)1597// @as(@Vector(2, u32), undefined)
1598// @as(@Vector(2, u500), undefined)1598// @as(@Vector(2, u32), undefined)
1599// @as(@Vector(2, u500), .{ undefined, 24 })1599// @as(@Vector(2, u32), .{ undefined, 24 })
1600// @as(@Vector(2, u500), undefined)1600// @as(@Vector(2, u32), undefined)
1601// @as(@Vector(2, u500), .{ undefined, 24 })1601// @as(@Vector(2, u32), .{ undefined, 24 })
1602// @as(@Vector(2, u500), undefined)1602// @as(@Vector(2, u32), undefined)
1603// @as(@Vector(2, u500), undefined)1603// @as(@Vector(2, u32), undefined)
1604// @as(@Vector(2, u500), undefined)1604// @as(@Vector(2, u32), undefined)
1605// @as(@Vector(2, u500), undefined)1605// @as(@Vector(2, u32), undefined)
1606// @as(@Vector(2, u500), undefined)1606// @as(@Vector(2, u32), undefined)
1607// @as(u500, undefined)1607// @as(u32, undefined)
1608// @as(u500, undefined)1608// @as(u32, undefined)
1609// @as(@Vector(2, u500), .{ 0, undefined })1609// @as(@Vector(2, u32), .{ 0, undefined })
1610// @as(@Vector(2, u500), .{ undefined, 0 })1610// @as(@Vector(2, u32), .{ undefined, 0 })
1611// @as(@Vector(2, u500), undefined)1611// @as(@Vector(2, u32), undefined)
1612// @as(@Vector(2, u500), .{ 0, undefined })1612// @as(@Vector(2, u32), .{ 0, undefined })
1613// @as(@Vector(2, u500), .{ 0, undefined })1613// @as(@Vector(2, u32), .{ 0, undefined })
1614// @as(@Vector(2, u500), undefined)1614// @as(@Vector(2, u32), undefined)
1615// @as(@Vector(2, u500), undefined)1615// @as(@Vector(2, u32), undefined)
1616// @as(@Vector(2, u500), .{ undefined, 0 })1616// @as(@Vector(2, u32), .{ undefined, 0 })
1617// @as(@Vector(2, u500), undefined)1617// @as(@Vector(2, u32), undefined)
1618// @as(@Vector(2, u500), .{ undefined, 0 })1618// @as(@Vector(2, u32), .{ undefined, 0 })
1619// @as(@Vector(2, u500), undefined)1619// @as(@Vector(2, u32), undefined)
1620// @as(@Vector(2, u500), undefined)1620// @as(@Vector(2, u32), undefined)
1621// @as(@Vector(2, u500), undefined)1621// @as(@Vector(2, u32), undefined)
1622// @as(@Vector(2, u500), undefined)1622// @as(@Vector(2, u32), undefined)
1623// @as(@Vector(2, u500), undefined)1623// @as(@Vector(2, u32), undefined)
1624// @as(u500, undefined)1624// @as(u32, undefined)
1625// @as(@Vector(2, u500), undefined)1625// @as(@Vector(2, u32), undefined)
1626// @as(u500, undefined)1626// @as(u32, undefined)
1627// @as(u500, undefined)1627// @as(u32, undefined)
1628// @as(@Vector(2, u500), undefined)1628// @as(@Vector(2, u32), undefined)
1629// @as(@Vector(2, u500), undefined)1629// @as(@Vector(2, u32), undefined)
1630// @as(u1, undefined)1630// @as(u1, undefined)
1631// @as(@Vector(2, u1), .{ 1, undefined })1631// @as(@Vector(2, u1), .{ 1, undefined })
1632// @as(@Vector(2, u1), .{ undefined, 1 })1632// @as(@Vector(2, u1), .{ undefined, 1 })
1633// @as(@Vector(2, u1), undefined)1633// @as(@Vector(2, u1), undefined)
1634// @as(u500, undefined)1634// @as(u32, undefined)
1635// @as(@Vector(2, u500), undefined)1635// @as(@Vector(2, u32), undefined)
1636// @as(u500, undefined)1636// @as(u32, undefined)
1637// @as(u500, undefined)1637// @as(u32, undefined)
1638// @as(@Vector(2, u500), [runtime value])1638// @as(@Vector(2, u32), [runtime value])
1639// @as(@Vector(2, u500), [runtime value])1639// @as(@Vector(2, u32), [runtime value])
1640// @as(@Vector(2, u500), undefined)1640// @as(@Vector(2, u32), undefined)
1641// @as(@Vector(2, u500), [runtime value])1641// @as(@Vector(2, u32), [runtime value])
1642// @as(@Vector(2, u500), [runtime value])1642// @as(@Vector(2, u32), [runtime value])
1643// @as(@Vector(2, u500), [runtime value])1643// @as(@Vector(2, u32), [runtime value])
1644// @as(@Vector(2, u500), undefined)1644// @as(@Vector(2, u32), undefined)
1645// @as(@Vector(2, u500), [runtime value])1645// @as(@Vector(2, u32), [runtime value])
1646// @as(@Vector(2, u500), [runtime value])1646// @as(@Vector(2, u32), [runtime value])
1647// @as(@Vector(2, u500), [runtime value])1647// @as(@Vector(2, u32), [runtime value])
1648// @as(@Vector(2, u500), undefined)1648// @as(@Vector(2, u32), undefined)
1649// @as(@Vector(2, u500), undefined)1649// @as(@Vector(2, u32), undefined)
1650// @as(@Vector(2, u500), undefined)1650// @as(@Vector(2, u32), undefined)
1651// @as(@Vector(2, u500), undefined)1651// @as(@Vector(2, u32), undefined)
1652// @as(@Vector(2, u500), undefined)1652// @as(@Vector(2, u32), undefined)
1653// @as(u500, undefined)1653// @as(u32, undefined)
1654// @as(u500, undefined)1654// @as(u32, undefined)
1655// @as(@Vector(2, u500), [runtime value])1655// @as(@Vector(2, u32), [runtime value])
1656// @as(@Vector(2, u500), [runtime value])1656// @as(@Vector(2, u32), [runtime value])
1657// @as(@Vector(2, u500), undefined)1657// @as(@Vector(2, u32), undefined)
1658// @as(@Vector(2, u500), [runtime value])1658// @as(@Vector(2, u32), [runtime value])
1659// @as(@Vector(2, u500), [runtime value])1659// @as(@Vector(2, u32), [runtime value])
1660// @as(@Vector(2, u500), [runtime value])1660// @as(@Vector(2, u32), [runtime value])
1661// @as(@Vector(2, u500), undefined)1661// @as(@Vector(2, u32), undefined)
1662// @as(@Vector(2, u500), [runtime value])1662// @as(@Vector(2, u32), [runtime value])
1663// @as(@Vector(2, u500), [runtime value])1663// @as(@Vector(2, u32), [runtime value])
1664// @as(@Vector(2, u500), [runtime value])1664// @as(@Vector(2, u32), [runtime value])
1665// @as(@Vector(2, u500), undefined)1665// @as(@Vector(2, u32), undefined)
1666// @as(@Vector(2, u500), undefined)1666// @as(@Vector(2, u32), undefined)
1667// @as(@Vector(2, u500), undefined)1667// @as(@Vector(2, u32), undefined)
1668// @as(@Vector(2, u500), undefined)1668// @as(@Vector(2, u32), undefined)
1669// @as(@Vector(2, u500), undefined)1669// @as(@Vector(2, u32), undefined)
1670// @as(u500, undefined)1670// @as(u32, undefined)
1671// @as(u500, undefined)1671// @as(u32, undefined)
1672// @as(@Vector(2, u500), [runtime value])1672// @as(@Vector(2, u32), [runtime value])
1673// @as(@Vector(2, u500), [runtime value])1673// @as(@Vector(2, u32), [runtime value])
1674// @as(@Vector(2, u500), undefined)1674// @as(@Vector(2, u32), undefined)
1675// @as(@Vector(2, u500), [runtime value])1675// @as(@Vector(2, u32), [runtime value])
1676// @as(@Vector(2, u500), [runtime value])1676// @as(@Vector(2, u32), [runtime value])
1677// @as(@Vector(2, u500), [runtime value])1677// @as(@Vector(2, u32), [runtime value])
1678// @as(@Vector(2, u500), undefined)1678// @as(@Vector(2, u32), undefined)
1679// @as(@Vector(2, u500), [runtime value])1679// @as(@Vector(2, u32), [runtime value])
1680// @as(@Vector(2, u500), [runtime value])1680// @as(@Vector(2, u32), [runtime value])
1681// @as(@Vector(2, u500), [runtime value])1681// @as(@Vector(2, u32), [runtime value])
1682// @as(@Vector(2, u500), undefined)1682// @as(@Vector(2, u32), undefined)
1683// @as(@Vector(2, u500), undefined)1683// @as(@Vector(2, u32), undefined)
1684// @as(@Vector(2, u500), undefined)1684// @as(@Vector(2, u32), undefined)
1685// @as(@Vector(2, u500), undefined)1685// @as(@Vector(2, u32), undefined)
1686// @as(@Vector(2, u500), undefined)1686// @as(@Vector(2, u32), undefined)
1687// @as(u500, undefined)1687// @as(u32, undefined)
1688// @as(u500, undefined)1688// @as(u32, undefined)
1689// @as(@Vector(2, u500), [runtime value])1689// @as(@Vector(2, u32), [runtime value])
1690// @as(@Vector(2, u500), [runtime value])1690// @as(@Vector(2, u32), [runtime value])
1691// @as(@Vector(2, u500), undefined)1691// @as(@Vector(2, u32), undefined)
1692// @as(@Vector(2, u500), [runtime value])1692// @as(@Vector(2, u32), [runtime value])
1693// @as(@Vector(2, u500), [runtime value])1693// @as(@Vector(2, u32), [runtime value])
1694// @as(@Vector(2, u500), [runtime value])1694// @as(@Vector(2, u32), [runtime value])
1695// @as(@Vector(2, u500), undefined)1695// @as(@Vector(2, u32), undefined)
1696// @as(@Vector(2, u500), [runtime value])1696// @as(@Vector(2, u32), [runtime value])
1697// @as(@Vector(2, u500), [runtime value])1697// @as(@Vector(2, u32), [runtime value])
1698// @as(@Vector(2, u500), [runtime value])1698// @as(@Vector(2, u32), [runtime value])
1699// @as(@Vector(2, u500), undefined)1699// @as(@Vector(2, u32), undefined)
1700// @as(@Vector(2, u500), undefined)1700// @as(@Vector(2, u32), undefined)
1701// @as(@Vector(2, u500), undefined)1701// @as(@Vector(2, u32), undefined)
1702// @as(@Vector(2, u500), undefined)1702// @as(@Vector(2, u32), undefined)
1703// @as(@Vector(2, u500), undefined)1703// @as(@Vector(2, u32), undefined)
1704// @as(u500, undefined)1704// @as(u32, undefined)
1705// @as(u500, undefined)1705// @as(u32, undefined)
1706// @as(@Vector(2, u500), [runtime value])1706// @as(@Vector(2, u32), [runtime value])
1707// @as(@Vector(2, u500), [runtime value])1707// @as(@Vector(2, u32), [runtime value])
1708// @as(@Vector(2, u500), undefined)1708// @as(@Vector(2, u32), undefined)
1709// @as(@Vector(2, u500), [runtime value])1709// @as(@Vector(2, u32), [runtime value])
1710// @as(@Vector(2, u500), [runtime value])1710// @as(@Vector(2, u32), [runtime value])
1711// @as(@Vector(2, u500), [runtime value])1711// @as(@Vector(2, u32), [runtime value])
1712// @as(@Vector(2, u500), undefined)1712// @as(@Vector(2, u32), undefined)
1713// @as(@Vector(2, u500), [runtime value])1713// @as(@Vector(2, u32), [runtime value])
1714// @as(@Vector(2, u500), [runtime value])1714// @as(@Vector(2, u32), [runtime value])
1715// @as(@Vector(2, u500), [runtime value])1715// @as(@Vector(2, u32), [runtime value])
1716// @as(@Vector(2, u500), undefined)1716// @as(@Vector(2, u32), undefined)
1717// @as(@Vector(2, u500), undefined)1717// @as(@Vector(2, u32), undefined)
1718// @as(@Vector(2, u500), undefined)1718// @as(@Vector(2, u32), undefined)
1719// @as(@Vector(2, u500), undefined)1719// @as(@Vector(2, u32), undefined)
1720// @as(@Vector(2, u500), undefined)1720// @as(@Vector(2, u32), undefined)
1721// @as(u500, undefined)1721// @as(u32, undefined)
1722// @as(u500, undefined)1722// @as(u32, undefined)
1723// @as(@Vector(2, u500), [runtime value])1723// @as(@Vector(2, u32), [runtime value])
1724// @as(@Vector(2, u500), [runtime value])1724// @as(@Vector(2, u32), [runtime value])
1725// @as(@Vector(2, u500), undefined)1725// @as(@Vector(2, u32), undefined)
1726// @as(@Vector(2, u500), [runtime value])1726// @as(@Vector(2, u32), [runtime value])
1727// @as(@Vector(2, u500), [runtime value])1727// @as(@Vector(2, u32), [runtime value])
1728// @as(@Vector(2, u500), [runtime value])1728// @as(@Vector(2, u32), [runtime value])
1729// @as(@Vector(2, u500), undefined)1729// @as(@Vector(2, u32), undefined)
1730// @as(@Vector(2, u500), [runtime value])1730// @as(@Vector(2, u32), [runtime value])
1731// @as(@Vector(2, u500), [runtime value])1731// @as(@Vector(2, u32), [runtime value])
1732// @as(@Vector(2, u500), [runtime value])1732// @as(@Vector(2, u32), [runtime value])
1733// @as(@Vector(2, u500), undefined)1733// @as(@Vector(2, u32), undefined)
1734// @as(@Vector(2, u500), undefined)1734// @as(@Vector(2, u32), undefined)
1735// @as(@Vector(2, u500), undefined)1735// @as(@Vector(2, u32), undefined)
1736// @as(@Vector(2, u500), undefined)1736// @as(@Vector(2, u32), undefined)
1737// @as(@Vector(2, u500), undefined)1737// @as(@Vector(2, u32), undefined)
1738// @as(u500, undefined)1738// @as(u32, undefined)
1739// @as(u500, undefined)1739// @as(u32, undefined)
1740// @as(@Vector(2, u500), [runtime value])1740// @as(@Vector(2, u32), [runtime value])
1741// @as(@Vector(2, u500), [runtime value])1741// @as(@Vector(2, u32), [runtime value])
1742// @as(@Vector(2, u500), undefined)1742// @as(@Vector(2, u32), undefined)
1743// @as(@Vector(2, u500), [runtime value])1743// @as(@Vector(2, u32), [runtime value])
1744// @as(@Vector(2, u500), [runtime value])1744// @as(@Vector(2, u32), [runtime value])
1745// @as(@Vector(2, u500), [runtime value])1745// @as(@Vector(2, u32), [runtime value])
1746// @as(@Vector(2, u500), undefined)1746// @as(@Vector(2, u32), undefined)
1747// @as(@Vector(2, u500), [runtime value])1747// @as(@Vector(2, u32), [runtime value])
1748// @as(@Vector(2, u500), [runtime value])1748// @as(@Vector(2, u32), [runtime value])
1749// @as(@Vector(2, u500), [runtime value])1749// @as(@Vector(2, u32), [runtime value])
1750// @as(@Vector(2, u500), undefined)1750// @as(@Vector(2, u32), undefined)
1751// @as(@Vector(2, u500), undefined)1751// @as(@Vector(2, u32), undefined)
1752// @as(@Vector(2, u500), undefined)1752// @as(@Vector(2, u32), undefined)
1753// @as(@Vector(2, u500), undefined)1753// @as(@Vector(2, u32), undefined)
1754// @as(@Vector(2, u500), undefined)1754// @as(@Vector(2, u32), undefined)
1755// @as(u500, [runtime value])1755// @as(u32, [runtime value])
1756// @as(u500, [runtime value])1756// @as(u32, [runtime value])
1757// @as(@Vector(2, u500), [runtime value])1757// @as(@Vector(2, u32), [runtime value])
1758// @as(@Vector(2, u500), [runtime value])1758// @as(@Vector(2, u32), [runtime value])
1759// @as(@Vector(2, u500), [runtime value])1759// @as(@Vector(2, u32), [runtime value])
1760// @as(@Vector(2, u500), [runtime value])1760// @as(@Vector(2, u32), [runtime value])
1761// @as(@Vector(2, u500), [runtime value])1761// @as(@Vector(2, u32), [runtime value])
1762// @as(@Vector(2, u500), [runtime value])1762// @as(@Vector(2, u32), [runtime value])
1763// @as(@Vector(2, u500), [runtime value])1763// @as(@Vector(2, u32), [runtime value])
1764// @as(@Vector(2, u500), [runtime value])1764// @as(@Vector(2, u32), [runtime value])
1765// @as(@Vector(2, u500), [runtime value])1765// @as(@Vector(2, u32), [runtime value])
1766// @as(@Vector(2, u500), [runtime value])1766// @as(@Vector(2, u32), [runtime value])
1767// @as(@Vector(2, u500), [runtime value])1767// @as(@Vector(2, u32), [runtime value])
1768// @as(@Vector(2, u500), [runtime value])1768// @as(@Vector(2, u32), [runtime value])
1769// @as(@Vector(2, u500), [runtime value])1769// @as(@Vector(2, u32), [runtime value])
1770// @as(@Vector(2, u500), [runtime value])1770// @as(@Vector(2, u32), [runtime value])
1771// @as(@Vector(2, u500), undefined)1771// @as(@Vector(2, u32), undefined)
1772// @as(u500, undefined)1772// @as(u32, undefined)
1773// @as(@Vector(2, u500), undefined)1773// @as(@Vector(2, u32), undefined)
1774// @as(u500, undefined)1774// @as(u32, undefined)
1775// @as(u500, undefined)1775// @as(u32, undefined)
1776// @as(@Vector(2, u500), undefined)1776// @as(@Vector(2, u32), undefined)
1777// @as(@Vector(2, u500), undefined)1777// @as(@Vector(2, u32), undefined)
1778// @as(u1, undefined)1778// @as(u1, undefined)
1779// @as(@Vector(2, u1), [runtime value])1779// @as(@Vector(2, u1), [runtime value])
1780// @as(@Vector(2, u1), [runtime value])1780// @as(@Vector(2, u1), [runtime value])
1781// @as(@Vector(2, u1), undefined)1781// @as(@Vector(2, u1), undefined)
1782// @as(u500, undefined)1782// @as(u32, undefined)
1783// @as(@Vector(2, u500), undefined)1783// @as(@Vector(2, u32), undefined)
1784// @as(i500, undefined)1784// @as(i8, undefined)
1785// @as(i500, undefined)1785// @as(i8, undefined)
1786// @as(@Vector(2, i500), .{ 6, undefined })1786// @as(@Vector(2, i8), .{ 6, undefined })
1787// @as(@Vector(2, i500), .{ undefined, 6 })1787// @as(@Vector(2, i8), .{ undefined, 6 })
1788// @as(@Vector(2, i500), undefined)1788// @as(@Vector(2, i8), undefined)
1789// @as(@Vector(2, i500), .{ 6, undefined })1789// @as(@Vector(2, i8), .{ 6, undefined })
1790// @as(@Vector(2, i500), .{ 6, undefined })1790// @as(@Vector(2, i8), .{ 6, undefined })
1791// @as(@Vector(2, i500), undefined)1791// @as(@Vector(2, i8), undefined)
1792// @as(@Vector(2, i500), undefined)1792// @as(@Vector(2, i8), undefined)
1793// @as(@Vector(2, i500), .{ undefined, 6 })1793// @as(@Vector(2, i8), .{ undefined, 6 })
1794// @as(@Vector(2, i500), undefined)1794// @as(@Vector(2, i8), undefined)
1795// @as(@Vector(2, i500), .{ undefined, 6 })1795// @as(@Vector(2, i8), .{ undefined, 6 })
1796// @as(@Vector(2, i500), undefined)1796// @as(@Vector(2, i8), undefined)
1797// @as(@Vector(2, i500), undefined)1797// @as(@Vector(2, i8), undefined)
1798// @as(@Vector(2, i500), undefined)1798// @as(@Vector(2, i8), undefined)
1799// @as(@Vector(2, i500), undefined)1799// @as(@Vector(2, i8), undefined)
1800// @as(@Vector(2, i500), undefined)1800// @as(@Vector(2, i8), undefined)
1801// @as(i500, undefined)1801// @as(i8, undefined)
1802// @as(i500, undefined)1802// @as(i8, undefined)
1803// @as(@Vector(2, i500), .{ 6, undefined })1803// @as(@Vector(2, i8), .{ 6, undefined })
1804// @as(@Vector(2, i500), .{ undefined, 6 })1804// @as(@Vector(2, i8), .{ undefined, 6 })
1805// @as(@Vector(2, i500), undefined)1805// @as(@Vector(2, i8), undefined)
1806// @as(@Vector(2, i500), .{ 6, undefined })1806// @as(@Vector(2, i8), .{ 6, undefined })
1807// @as(@Vector(2, i500), .{ 6, undefined })1807// @as(@Vector(2, i8), .{ 6, undefined })
1808// @as(@Vector(2, i500), undefined)1808// @as(@Vector(2, i8), undefined)
1809// @as(@Vector(2, i500), undefined)1809// @as(@Vector(2, i8), undefined)
1810// @as(@Vector(2, i500), .{ undefined, 6 })1810// @as(@Vector(2, i8), .{ undefined, 6 })
1811// @as(@Vector(2, i500), undefined)1811// @as(@Vector(2, i8), undefined)
1812// @as(@Vector(2, i500), .{ undefined, 6 })1812// @as(@Vector(2, i8), .{ undefined, 6 })
1813// @as(@Vector(2, i500), undefined)1813// @as(@Vector(2, i8), undefined)
1814// @as(@Vector(2, i500), undefined)1814// @as(@Vector(2, i8), undefined)
1815// @as(@Vector(2, i500), undefined)1815// @as(@Vector(2, i8), undefined)
1816// @as(@Vector(2, i500), undefined)1816// @as(@Vector(2, i8), undefined)
1817// @as(@Vector(2, i500), undefined)1817// @as(@Vector(2, i8), undefined)
1818// @as(i500, undefined)1818// @as(i8, undefined)
1819// @as(i500, undefined)1819// @as(i8, undefined)
1820// @as(@Vector(2, i500), .{ 0, undefined })1820// @as(@Vector(2, i8), .{ 0, undefined })
1821// @as(@Vector(2, i500), .{ undefined, 0 })1821// @as(@Vector(2, i8), .{ undefined, 0 })
1822// @as(@Vector(2, i500), undefined)1822// @as(@Vector(2, i8), undefined)
1823// @as(@Vector(2, i500), .{ 0, undefined })1823// @as(@Vector(2, i8), .{ 0, undefined })
1824// @as(@Vector(2, i500), .{ 0, undefined })1824// @as(@Vector(2, i8), .{ 0, undefined })
1825// @as(@Vector(2, i500), undefined)1825// @as(@Vector(2, i8), undefined)
1826// @as(@Vector(2, i500), undefined)1826// @as(@Vector(2, i8), undefined)
1827// @as(@Vector(2, i500), .{ undefined, 0 })1827// @as(@Vector(2, i8), .{ undefined, 0 })
1828// @as(@Vector(2, i500), undefined)1828// @as(@Vector(2, i8), undefined)
1829// @as(@Vector(2, i500), .{ undefined, 0 })1829// @as(@Vector(2, i8), .{ undefined, 0 })
1830// @as(@Vector(2, i500), undefined)1830// @as(@Vector(2, i8), undefined)
1831// @as(@Vector(2, i500), undefined)1831// @as(@Vector(2, i8), undefined)
1832// @as(@Vector(2, i500), undefined)1832// @as(@Vector(2, i8), undefined)
1833// @as(@Vector(2, i500), undefined)1833// @as(@Vector(2, i8), undefined)
1834// @as(@Vector(2, i500), undefined)1834// @as(@Vector(2, i8), undefined)
1835// @as(i500, undefined)1835// @as(i8, undefined)
1836// @as(i500, undefined)1836// @as(i8, undefined)
1837// @as(@Vector(2, i500), .{ 0, undefined })1837// @as(@Vector(2, i8), .{ 0, undefined })
1838// @as(@Vector(2, i500), .{ undefined, 0 })1838// @as(@Vector(2, i8), .{ undefined, 0 })
1839// @as(@Vector(2, i500), undefined)1839// @as(@Vector(2, i8), undefined)
1840// @as(@Vector(2, i500), .{ 0, undefined })1840// @as(@Vector(2, i8), .{ 0, undefined })
1841// @as(@Vector(2, i500), .{ 0, undefined })1841// @as(@Vector(2, i8), .{ 0, undefined })
1842// @as(@Vector(2, i500), undefined)1842// @as(@Vector(2, i8), undefined)
1843// @as(@Vector(2, i500), undefined)1843// @as(@Vector(2, i8), undefined)
1844// @as(@Vector(2, i500), .{ undefined, 0 })1844// @as(@Vector(2, i8), .{ undefined, 0 })
1845// @as(@Vector(2, i500), undefined)1845// @as(@Vector(2, i8), undefined)
1846// @as(@Vector(2, i500), .{ undefined, 0 })1846// @as(@Vector(2, i8), .{ undefined, 0 })
1847// @as(@Vector(2, i500), undefined)1847// @as(@Vector(2, i8), undefined)
1848// @as(@Vector(2, i500), undefined)1848// @as(@Vector(2, i8), undefined)
1849// @as(@Vector(2, i500), undefined)1849// @as(@Vector(2, i8), undefined)
1850// @as(@Vector(2, i500), undefined)1850// @as(@Vector(2, i8), undefined)
1851// @as(@Vector(2, i500), undefined)1851// @as(@Vector(2, i8), undefined)
1852// @as(i500, undefined)1852// @as(i8, undefined)
1853// @as(i500, undefined)1853// @as(i8, undefined)
1854// @as(@Vector(2, i500), .{ 9, undefined })1854// @as(@Vector(2, i8), .{ 9, undefined })
1855// @as(@Vector(2, i500), .{ undefined, 9 })1855// @as(@Vector(2, i8), .{ undefined, 9 })
1856// @as(@Vector(2, i500), undefined)1856// @as(@Vector(2, i8), undefined)
1857// @as(@Vector(2, i500), .{ 9, undefined })1857// @as(@Vector(2, i8), .{ 9, undefined })
1858// @as(@Vector(2, i500), .{ 9, undefined })1858// @as(@Vector(2, i8), .{ 9, undefined })
1859// @as(@Vector(2, i500), undefined)1859// @as(@Vector(2, i8), undefined)
1860// @as(@Vector(2, i500), undefined)1860// @as(@Vector(2, i8), undefined)
1861// @as(@Vector(2, i500), .{ undefined, 9 })1861// @as(@Vector(2, i8), .{ undefined, 9 })
1862// @as(@Vector(2, i500), undefined)1862// @as(@Vector(2, i8), undefined)
1863// @as(@Vector(2, i500), .{ undefined, 9 })1863// @as(@Vector(2, i8), .{ undefined, 9 })
1864// @as(@Vector(2, i500), undefined)1864// @as(@Vector(2, i8), undefined)
1865// @as(@Vector(2, i500), undefined)1865// @as(@Vector(2, i8), undefined)
1866// @as(@Vector(2, i500), undefined)1866// @as(@Vector(2, i8), undefined)
1867// @as(@Vector(2, i500), undefined)1867// @as(@Vector(2, i8), undefined)
1868// @as(@Vector(2, i500), undefined)1868// @as(@Vector(2, i8), undefined)
1869// @as(i500, undefined)1869// @as(i8, undefined)
1870// @as(i500, undefined)1870// @as(i8, undefined)
1871// @as(@Vector(2, i500), .{ 9, undefined })1871// @as(@Vector(2, i8), .{ 9, undefined })
1872// @as(@Vector(2, i500), .{ undefined, 9 })1872// @as(@Vector(2, i8), .{ undefined, 9 })
1873// @as(@Vector(2, i500), undefined)1873// @as(@Vector(2, i8), undefined)
1874// @as(@Vector(2, i500), .{ 9, undefined })1874// @as(@Vector(2, i8), .{ 9, undefined })
1875// @as(@Vector(2, i500), .{ 9, undefined })1875// @as(@Vector(2, i8), .{ 9, undefined })
1876// @as(@Vector(2, i500), undefined)1876// @as(@Vector(2, i8), undefined)
1877// @as(@Vector(2, i500), undefined)1877// @as(@Vector(2, i8), undefined)
1878// @as(@Vector(2, i500), .{ undefined, 9 })1878// @as(@Vector(2, i8), .{ undefined, 9 })
1879// @as(@Vector(2, i500), undefined)1879// @as(@Vector(2, i8), undefined)
1880// @as(@Vector(2, i500), .{ undefined, 9 })1880// @as(@Vector(2, i8), .{ undefined, 9 })
1881// @as(@Vector(2, i500), undefined)1881// @as(@Vector(2, i8), undefined)
1882// @as(@Vector(2, i500), undefined)1882// @as(@Vector(2, i8), undefined)
1883// @as(@Vector(2, i500), undefined)1883// @as(@Vector(2, i8), undefined)
1884// @as(@Vector(2, i500), undefined)1884// @as(@Vector(2, i8), undefined)
1885// @as(@Vector(2, i500), undefined)1885// @as(@Vector(2, i8), undefined)
1886// @as(i500, undefined)1886// @as(i8, undefined)
1887// @as(i500, undefined)1887// @as(i8, undefined)
1888// @as(@Vector(2, i500), .{ 0, undefined })1888// @as(@Vector(2, i8), .{ 0, undefined })
1889// @as(@Vector(2, i500), .{ undefined, 0 })1889// @as(@Vector(2, i8), .{ undefined, 0 })
1890// @as(@Vector(2, i500), undefined)1890// @as(@Vector(2, i8), undefined)
1891// @as(@Vector(2, i500), .{ 0, undefined })1891// @as(@Vector(2, i8), .{ 0, undefined })
1892// @as(@Vector(2, i500), .{ 0, undefined })1892// @as(@Vector(2, i8), .{ 0, undefined })
1893// @as(@Vector(2, i500), undefined)1893// @as(@Vector(2, i8), undefined)
1894// @as(@Vector(2, i500), undefined)1894// @as(@Vector(2, i8), undefined)
1895// @as(@Vector(2, i500), .{ undefined, 0 })1895// @as(@Vector(2, i8), .{ undefined, 0 })
1896// @as(@Vector(2, i500), undefined)1896// @as(@Vector(2, i8), undefined)
1897// @as(@Vector(2, i500), .{ undefined, 0 })1897// @as(@Vector(2, i8), .{ undefined, 0 })
1898// @as(@Vector(2, i500), undefined)1898// @as(@Vector(2, i8), undefined)
1899// @as(@Vector(2, i500), undefined)1899// @as(@Vector(2, i8), undefined)
1900// @as(@Vector(2, i500), undefined)1900// @as(@Vector(2, i8), undefined)
1901// @as(@Vector(2, i500), undefined)1901// @as(@Vector(2, i8), undefined)
1902// @as(@Vector(2, i500), undefined)1902// @as(@Vector(2, i8), undefined)
1903// @as(i500, undefined)1903// @as(i8, undefined)
1904// @as(@Vector(2, i500), undefined)1904// @as(@Vector(2, i8), undefined)
1905// @as(i500, undefined)1905// @as(i8, undefined)
1906// @as(i500, undefined)1906// @as(i8, undefined)
1907// @as(@Vector(2, i500), undefined)1907// @as(@Vector(2, i8), undefined)
1908// @as(@Vector(2, i500), undefined)1908// @as(@Vector(2, i8), undefined)
1909// @as(i500, undefined)1909// @as(i8, undefined)
1910// @as(@Vector(2, i500), undefined)1910// @as(@Vector(2, i8), undefined)
1911// @as(i500, undefined)1911// @as(i8, undefined)
1912// @as(i500, undefined)1912// @as(i8, undefined)
1913// @as(@Vector(2, i500), [runtime value])1913// @as(@Vector(2, i8), [runtime value])
1914// @as(@Vector(2, i500), [runtime value])1914// @as(@Vector(2, i8), [runtime value])
1915// @as(@Vector(2, i500), undefined)1915// @as(@Vector(2, i8), undefined)
1916// @as(@Vector(2, i500), [runtime value])1916// @as(@Vector(2, i8), [runtime value])
1917// @as(@Vector(2, i500), [runtime value])1917// @as(@Vector(2, i8), [runtime value])
1918// @as(@Vector(2, i500), [runtime value])1918// @as(@Vector(2, i8), [runtime value])
1919// @as(@Vector(2, i500), undefined)1919// @as(@Vector(2, i8), undefined)
1920// @as(@Vector(2, i500), [runtime value])1920// @as(@Vector(2, i8), [runtime value])
1921// @as(@Vector(2, i500), [runtime value])1921// @as(@Vector(2, i8), [runtime value])
1922// @as(@Vector(2, i500), [runtime value])1922// @as(@Vector(2, i8), [runtime value])
1923// @as(@Vector(2, i500), undefined)1923// @as(@Vector(2, i8), undefined)
1924// @as(@Vector(2, i500), undefined)1924// @as(@Vector(2, i8), undefined)
1925// @as(@Vector(2, i500), undefined)1925// @as(@Vector(2, i8), undefined)
1926// @as(@Vector(2, i500), undefined)1926// @as(@Vector(2, i8), undefined)
1927// @as(@Vector(2, i500), undefined)1927// @as(@Vector(2, i8), undefined)
1928// @as(i500, undefined)1928// @as(i8, undefined)
1929// @as(i500, undefined)1929// @as(i8, undefined)
1930// @as(@Vector(2, i500), [runtime value])1930// @as(@Vector(2, i8), [runtime value])
1931// @as(@Vector(2, i500), [runtime value])1931// @as(@Vector(2, i8), [runtime value])
1932// @as(@Vector(2, i500), undefined)1932// @as(@Vector(2, i8), undefined)
1933// @as(@Vector(2, i500), [runtime value])1933// @as(@Vector(2, i8), [runtime value])
1934// @as(@Vector(2, i500), [runtime value])1934// @as(@Vector(2, i8), [runtime value])
1935// @as(@Vector(2, i500), [runtime value])1935// @as(@Vector(2, i8), [runtime value])
1936// @as(@Vector(2, i500), undefined)1936// @as(@Vector(2, i8), undefined)
1937// @as(@Vector(2, i500), [runtime value])1937// @as(@Vector(2, i8), [runtime value])
1938// @as(@Vector(2, i500), [runtime value])1938// @as(@Vector(2, i8), [runtime value])
1939// @as(@Vector(2, i500), [runtime value])1939// @as(@Vector(2, i8), [runtime value])
1940// @as(@Vector(2, i500), undefined)1940// @as(@Vector(2, i8), undefined)
1941// @as(@Vector(2, i500), undefined)1941// @as(@Vector(2, i8), undefined)
1942// @as(@Vector(2, i500), undefined)1942// @as(@Vector(2, i8), undefined)
1943// @as(@Vector(2, i500), undefined)1943// @as(@Vector(2, i8), undefined)
1944// @as(@Vector(2, i500), undefined)1944// @as(@Vector(2, i8), undefined)
1945// @as(i500, undefined)1945// @as(i8, undefined)
1946// @as(i500, undefined)1946// @as(i8, undefined)
1947// @as(@Vector(2, i500), [runtime value])1947// @as(@Vector(2, i8), [runtime value])
1948// @as(@Vector(2, i500), [runtime value])1948// @as(@Vector(2, i8), [runtime value])
1949// @as(@Vector(2, i500), undefined)1949// @as(@Vector(2, i8), undefined)
1950// @as(@Vector(2, i500), [runtime value])1950// @as(@Vector(2, i8), [runtime value])
1951// @as(@Vector(2, i500), [runtime value])1951// @as(@Vector(2, i8), [runtime value])
1952// @as(@Vector(2, i500), [runtime value])1952// @as(@Vector(2, i8), [runtime value])
1953// @as(@Vector(2, i500), undefined)1953// @as(@Vector(2, i8), undefined)
1954// @as(@Vector(2, i500), [runtime value])1954// @as(@Vector(2, i8), [runtime value])
1955// @as(@Vector(2, i500), [runtime value])1955// @as(@Vector(2, i8), [runtime value])
1956// @as(@Vector(2, i500), [runtime value])1956// @as(@Vector(2, i8), [runtime value])
1957// @as(@Vector(2, i500), undefined)1957// @as(@Vector(2, i8), undefined)
1958// @as(@Vector(2, i500), undefined)1958// @as(@Vector(2, i8), undefined)
1959// @as(@Vector(2, i500), undefined)1959// @as(@Vector(2, i8), undefined)
1960// @as(@Vector(2, i500), undefined)1960// @as(@Vector(2, i8), undefined)
1961// @as(@Vector(2, i500), undefined)1961// @as(@Vector(2, i8), undefined)
1962// @as(i500, undefined)1962// @as(i8, undefined)
1963// @as(i500, undefined)1963// @as(i8, undefined)
1964// @as(@Vector(2, i500), [runtime value])1964// @as(@Vector(2, i8), [runtime value])
1965// @as(@Vector(2, i500), [runtime value])1965// @as(@Vector(2, i8), [runtime value])
1966// @as(@Vector(2, i500), undefined)1966// @as(@Vector(2, i8), undefined)
1967// @as(@Vector(2, i500), [runtime value])1967// @as(@Vector(2, i8), [runtime value])
1968// @as(@Vector(2, i500), [runtime value])1968// @as(@Vector(2, i8), [runtime value])
1969// @as(@Vector(2, i500), [runtime value])1969// @as(@Vector(2, i8), [runtime value])
1970// @as(@Vector(2, i500), undefined)1970// @as(@Vector(2, i8), undefined)
1971// @as(@Vector(2, i500), [runtime value])1971// @as(@Vector(2, i8), [runtime value])
1972// @as(@Vector(2, i500), [runtime value])1972// @as(@Vector(2, i8), [runtime value])
1973// @as(@Vector(2, i500), [runtime value])1973// @as(@Vector(2, i8), [runtime value])
1974// @as(@Vector(2, i500), undefined)1974// @as(@Vector(2, i8), undefined)
1975// @as(@Vector(2, i500), undefined)1975// @as(@Vector(2, i8), undefined)
1976// @as(@Vector(2, i500), undefined)1976// @as(@Vector(2, i8), undefined)
1977// @as(@Vector(2, i500), undefined)1977// @as(@Vector(2, i8), undefined)
1978// @as(@Vector(2, i500), undefined)1978// @as(@Vector(2, i8), undefined)
1979// @as(i500, undefined)1979// @as(i8, undefined)
1980// @as(i500, undefined)1980// @as(i8, undefined)
1981// @as(@Vector(2, i500), [runtime value])1981// @as(@Vector(2, i8), [runtime value])
1982// @as(@Vector(2, i500), [runtime value])1982// @as(@Vector(2, i8), [runtime value])
1983// @as(@Vector(2, i500), undefined)1983// @as(@Vector(2, i8), undefined)
1984// @as(@Vector(2, i500), [runtime value])1984// @as(@Vector(2, i8), [runtime value])
1985// @as(@Vector(2, i500), [runtime value])1985// @as(@Vector(2, i8), [runtime value])
1986// @as(@Vector(2, i500), [runtime value])1986// @as(@Vector(2, i8), [runtime value])
1987// @as(@Vector(2, i500), undefined)1987// @as(@Vector(2, i8), undefined)
1988// @as(@Vector(2, i500), [runtime value])1988// @as(@Vector(2, i8), [runtime value])
1989// @as(@Vector(2, i500), [runtime value])1989// @as(@Vector(2, i8), [runtime value])
1990// @as(@Vector(2, i500), [runtime value])1990// @as(@Vector(2, i8), [runtime value])
1991// @as(@Vector(2, i500), undefined)1991// @as(@Vector(2, i8), undefined)
1992// @as(@Vector(2, i500), undefined)1992// @as(@Vector(2, i8), undefined)
1993// @as(@Vector(2, i500), undefined)1993// @as(@Vector(2, i8), undefined)
1994// @as(@Vector(2, i500), undefined)1994// @as(@Vector(2, i8), undefined)
1995// @as(@Vector(2, i500), undefined)1995// @as(@Vector(2, i8), undefined)
1996// @as(i500, undefined)1996// @as(i8, undefined)
1997// @as(i500, undefined)1997// @as(i8, undefined)
1998// @as(@Vector(2, i500), [runtime value])1998// @as(@Vector(2, i8), [runtime value])
1999// @as(@Vector(2, i500), [runtime value])1999// @as(@Vector(2, i8), [runtime value])
2000// @as(@Vector(2, i500), undefined)2000// @as(@Vector(2, i8), undefined)
2001// @as(@Vector(2, i500), [runtime value])2001// @as(@Vector(2, i8), [runtime value])
2002// @as(@Vector(2, i500), [runtime value])2002// @as(@Vector(2, i8), [runtime value])
2003// @as(@Vector(2, i500), [runtime value])2003// @as(@Vector(2, i8), [runtime value])
2004// @as(@Vector(2, i500), undefined)2004// @as(@Vector(2, i8), undefined)
2005// @as(@Vector(2, i500), [runtime value])2005// @as(@Vector(2, i8), [runtime value])
2006// @as(@Vector(2, i500), [runtime value])2006// @as(@Vector(2, i8), [runtime value])
2007// @as(@Vector(2, i500), [runtime value])2007// @as(@Vector(2, i8), [runtime value])
2008// @as(@Vector(2, i500), undefined)2008// @as(@Vector(2, i8), undefined)
2009// @as(@Vector(2, i500), undefined)2009// @as(@Vector(2, i8), undefined)
2010// @as(@Vector(2, i500), undefined)2010// @as(@Vector(2, i8), undefined)
2011// @as(@Vector(2, i500), undefined)2011// @as(@Vector(2, i8), undefined)
2012// @as(@Vector(2, i500), undefined)2012// @as(@Vector(2, i8), undefined)
2013// @as(i500, [runtime value])2013// @as(i8, [runtime value])
2014// @as(i500, [runtime value])2014// @as(i8, [runtime value])
2015// @as(@Vector(2, i500), [runtime value])2015// @as(@Vector(2, i8), [runtime value])
2016// @as(@Vector(2, i500), [runtime value])2016// @as(@Vector(2, i8), [runtime value])
2017// @as(@Vector(2, i500), [runtime value])2017// @as(@Vector(2, i8), [runtime value])
2018// @as(@Vector(2, i500), [runtime value])2018// @as(@Vector(2, i8), [runtime value])
2019// @as(@Vector(2, i500), [runtime value])2019// @as(@Vector(2, i8), [runtime value])
2020// @as(@Vector(2, i500), [runtime value])2020// @as(@Vector(2, i8), [runtime value])
2021// @as(@Vector(2, i500), [runtime value])2021// @as(@Vector(2, i8), [runtime value])
2022// @as(@Vector(2, i500), [runtime value])2022// @as(@Vector(2, i8), [runtime value])
2023// @as(@Vector(2, i500), [runtime value])2023// @as(@Vector(2, i8), [runtime value])
2024// @as(@Vector(2, i500), [runtime value])2024// @as(@Vector(2, i8), [runtime value])
2025// @as(@Vector(2, i500), [runtime value])2025// @as(@Vector(2, i8), [runtime value])
2026// @as(@Vector(2, i500), [runtime value])2026// @as(@Vector(2, i8), [runtime value])
2027// @as(@Vector(2, i500), [runtime value])2027// @as(@Vector(2, i8), [runtime value])
2028// @as(@Vector(2, i500), [runtime value])2028// @as(@Vector(2, i8), [runtime value])
2029// @as(@Vector(2, i500), undefined)2029// @as(@Vector(2, i8), undefined)
2030// @as(i500, undefined)2030// @as(i8, undefined)
2031// @as(@Vector(2, i500), undefined)2031// @as(@Vector(2, i8), undefined)
2032// @as(i500, undefined)2032// @as(i8, undefined)
2033// @as(i500, undefined)2033// @as(i8, undefined)
2034// @as(@Vector(2, i500), undefined)2034// @as(@Vector(2, i8), undefined)
2035// @as(@Vector(2, i500), undefined)2035// @as(@Vector(2, i8), undefined)
2036// @as(i500, undefined)2036// @as(i8, undefined)
2037// @as(@Vector(2, i500), undefined)2037// @as(@Vector(2, i8), 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)
2478// @as(f128, undefined)2038// @as(f128, undefined)
2479// @as(f128, undefined)2039// @as(f128, undefined)
2480// @as(@Vector(2, f128), .{ 6, undefined })2040// @as(@Vector(2, f128), .{ 6, undefined })
...@@ -2585,3 +2145,443 @@ inline fn testFloatWithValue(comptime Float: type, x: Float) void {...@@ -2585,3 +2145,443 @@ inline fn testFloatWithValue(comptime Float: type, x: Float) void {
2585// @as(@Vector(2, f128), [runtime value])2145// @as(@Vector(2, f128), [runtime value])
2586// @as(@Vector(2, f128), [runtime value])2146// @as(@Vector(2, f128), [runtime value])
2587// @as(@Vector(2, f128), undefined)2147// @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");...@@ -125,27 +125,19 @@ const std = @import("std");
125// :53:17: error: use of undefined value here causes illegal behavior125// :53:17: error: use of undefined value here causes illegal behavior
126// :53:17: error: use of undefined value here causes illegal behavior126// :53:17: error: use of undefined value here causes illegal behavior
127// :53:17: error: use of undefined value here causes illegal behavior127// :53:17: error: use of undefined value here causes illegal behavior
128// :53:17: note: when computing vector element at index '0'
129// :53:17: error: use of undefined value here causes illegal behavior128// :53:17: error: use of undefined value here causes illegal behavior
130// :53:17: note: when computing vector element at index '0'
131// :53:17: error: use of undefined value here causes illegal behavior129// :53:17: error: use of undefined value here causes illegal behavior
132// :53:17: note: when computing vector element at index '0'
133// :53:17: error: use of undefined value here causes illegal behavior130// :53:17: error: use of undefined value here causes illegal behavior
134// :53:17: note: when computing vector element at index '0'
135// :53:17: error: use of undefined value here causes illegal behavior131// :53:17: error: use of undefined value here causes illegal behavior
136// :53:17: note: when computing vector element at index '1'
137// :53:17: error: use of undefined value here causes illegal behavior132// :53:17: error: use of undefined value here causes illegal behavior
138// :53:17: note: when computing vector element at index '1'
139// :53:17: error: use of undefined value here causes illegal behavior133// :53:17: error: use of undefined value here causes illegal behavior
140// :53:17: note: when computing vector element at index '0'
141// :53:17: error: use of undefined value here causes illegal behavior134// :53:17: error: use of undefined value here causes illegal behavior
142// :53:17: note: when computing vector element at index '0'
143// :53:17: error: use of undefined value here causes illegal behavior135// :53:17: error: use of undefined value here causes illegal behavior
144// :53:17: note: when computing vector element at index '0'
145// :53:17: error: use of undefined value here causes illegal behavior136// :53:17: error: use of undefined value here causes illegal behavior
146// :53:17: note: when computing vector element at index '0'
147// :53:17: error: use of undefined value here causes illegal behavior137// :53:17: error: use of undefined value here causes illegal behavior
138// :53:17: note: when computing vector element at index '0'
148// :53:17: error: use of undefined value here causes illegal behavior139// :53:17: error: use of undefined value here causes illegal behavior
140// :53:17: note: when computing vector element at index '0'
149// :53:17: error: use of undefined value here causes illegal behavior141// :53:17: error: use of undefined value here causes illegal behavior
150// :53:17: note: when computing vector element at index '0'142// :53:17: note: when computing vector element at index '0'
151// :53:17: error: use of undefined value here causes illegal behavior143// :53:17: error: use of undefined value here causes illegal behavior
...@@ -155,9 +147,9 @@ const std = @import("std");...@@ -155,9 +147,9 @@ const std = @import("std");
155// :53:17: error: use of undefined value here causes illegal behavior147// :53:17: error: use of undefined value here causes illegal behavior
156// :53:17: note: when computing vector element at index '0'148// :53:17: note: when computing vector element at index '0'
157// :53:17: error: use of undefined value here causes illegal behavior149// :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'
159// :53:17: error: use of undefined value here causes illegal behavior151// :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'
161// :53:17: error: use of undefined value here causes illegal behavior153// :53:17: error: use of undefined value here causes illegal behavior
162// :53:17: note: when computing vector element at index '0'154// :53:17: note: when computing vector element at index '0'
163// :53:17: error: use of undefined value here causes illegal behavior155// :53:17: error: use of undefined value here causes illegal behavior
...@@ -167,7 +159,9 @@ const std = @import("std");...@@ -167,7 +159,9 @@ const std = @import("std");
167// :53:17: error: use of undefined value here causes illegal behavior159// :53:17: error: use of undefined value here causes illegal behavior
168// :53:17: note: when computing vector element at index '0'160// :53:17: note: when computing vector element at index '0'
169// :53:17: error: use of undefined value here causes illegal behavior161// :53:17: error: use of undefined value here causes illegal behavior
162// :53:17: note: when computing vector element at index '0'
170// :53:17: error: use of undefined value here causes illegal behavior163// :53:17: error: use of undefined value here causes illegal behavior
164// :53:17: note: when computing vector element at index '0'
171// :53:17: error: use of undefined value here causes illegal behavior165// :53:17: error: use of undefined value here causes illegal behavior
172// :53:17: note: when computing vector element at index '0'166// :53:17: note: when computing vector element at index '0'
173// :53:17: error: use of undefined value here causes illegal behavior167// :53:17: error: use of undefined value here causes illegal behavior
...@@ -177,9 +171,9 @@ const std = @import("std");...@@ -177,9 +171,9 @@ const std = @import("std");
177// :53:17: error: use of undefined value here causes illegal behavior171// :53:17: error: use of undefined value here causes illegal behavior
178// :53:17: note: when computing vector element at index '0'172// :53:17: note: when computing vector element at index '0'
179// :53:17: error: use of undefined value here causes illegal behavior173// :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'
181// :53:17: error: use of undefined value here causes illegal behavior175// :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'
183// :53:17: error: use of undefined value here causes illegal behavior177// :53:17: error: use of undefined value here causes illegal behavior
184// :53:17: note: when computing vector element at index '0'178// :53:17: note: when computing vector element at index '0'
185// :53:17: error: use of undefined value here causes illegal behavior179// :53:17: error: use of undefined value here causes illegal behavior
...@@ -189,7 +183,9 @@ const std = @import("std");...@@ -189,7 +183,9 @@ const std = @import("std");
189// :53:17: error: use of undefined value here causes illegal behavior183// :53:17: error: use of undefined value here causes illegal behavior
190// :53:17: note: when computing vector element at index '0'184// :53:17: note: when computing vector element at index '0'
191// :53:17: error: use of undefined value here causes illegal behavior185// :53:17: error: use of undefined value here causes illegal behavior
186// :53:17: note: when computing vector element at index '0'
192// :53:17: error: use of undefined value here causes illegal behavior187// :53:17: error: use of undefined value here causes illegal behavior
188// :53:17: note: when computing vector element at index '0'
193// :53:17: error: use of undefined value here causes illegal behavior189// :53:17: error: use of undefined value here causes illegal behavior
194// :53:17: note: when computing vector element at index '0'190// :53:17: note: when computing vector element at index '0'
195// :53:17: error: use of undefined value here causes illegal behavior191// :53:17: error: use of undefined value here causes illegal behavior
...@@ -199,9 +195,9 @@ const std = @import("std");...@@ -199,9 +195,9 @@ const std = @import("std");
199// :53:17: error: use of undefined value here causes illegal behavior195// :53:17: error: use of undefined value here causes illegal behavior
200// :53:17: note: when computing vector element at index '0'196// :53:17: note: when computing vector element at index '0'
201// :53:17: error: use of undefined value here causes illegal behavior197// :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'
203// :53:17: error: use of undefined value here causes illegal behavior199// :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'
205// :53:17: error: use of undefined value here causes illegal behavior201// :53:17: error: use of undefined value here causes illegal behavior
206// :53:17: note: when computing vector element at index '0'202// :53:17: note: when computing vector element at index '0'
207// :53:17: error: use of undefined value here causes illegal behavior203// :53:17: error: use of undefined value here causes illegal behavior
...@@ -211,7 +207,9 @@ const std = @import("std");...@@ -211,7 +207,9 @@ const std = @import("std");
211// :53:17: error: use of undefined value here causes illegal behavior207// :53:17: error: use of undefined value here causes illegal behavior
212// :53:17: note: when computing vector element at index '0'208// :53:17: note: when computing vector element at index '0'
213// :53:17: error: use of undefined value here causes illegal behavior209// :53:17: error: use of undefined value here causes illegal behavior
210// :53:17: note: when computing vector element at index '0'
214// :53:17: error: use of undefined value here causes illegal behavior211// :53:17: error: use of undefined value here causes illegal behavior
212// :53:17: note: when computing vector element at index '0'
215// :53:17: error: use of undefined value here causes illegal behavior213// :53:17: error: use of undefined value here causes illegal behavior
216// :53:17: note: when computing vector element at index '0'214// :53:17: note: when computing vector element at index '0'
217// :53:17: error: use of undefined value here causes illegal behavior215// :53:17: error: use of undefined value here causes illegal behavior
...@@ -221,9 +219,9 @@ const std = @import("std");...@@ -221,9 +219,9 @@ const std = @import("std");
221// :53:17: error: use of undefined value here causes illegal behavior219// :53:17: error: use of undefined value here causes illegal behavior
222// :53:17: note: when computing vector element at index '0'220// :53:17: note: when computing vector element at index '0'
223// :53:17: error: use of undefined value here causes illegal behavior221// :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'
225// :53:17: error: use of undefined value here causes illegal behavior223// :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'
227// :53:17: error: use of undefined value here causes illegal behavior225// :53:17: error: use of undefined value here causes illegal behavior
228// :53:17: note: when computing vector element at index '0'226// :53:17: note: when computing vector element at index '0'
229// :53:17: error: use of undefined value here causes illegal behavior227// :53:17: error: use of undefined value here causes illegal behavior
...@@ -233,27 +231,29 @@ const std = @import("std");...@@ -233,27 +231,29 @@ const std = @import("std");
233// :53:17: error: use of undefined value here causes illegal behavior231// :53:17: error: use of undefined value here causes illegal behavior
234// :53:17: note: when computing vector element at index '0'232// :53:17: note: when computing vector element at index '0'
235// :53:17: error: use of undefined value here causes illegal behavior233// :53:17: error: use of undefined value here causes illegal behavior
234// :53:17: note: when computing vector element at index '1'
236// :53:17: error: use of undefined value here causes illegal behavior235// :53:17: error: use of undefined value here causes illegal behavior
236// :53:17: note: when computing vector element at index '1'
237// :53:17: error: use of undefined value here causes illegal behavior237// :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'
239// :53:17: error: use of undefined value here causes illegal behavior239// :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'
241// :53:17: error: use of undefined value here causes illegal behavior241// :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'
243// :53:17: error: use of undefined value here causes illegal behavior243// :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'
245// :53:17: error: use of undefined value here causes illegal behavior245// :53:17: error: use of undefined value here causes illegal behavior
246// :53:17: note: when computing vector element at index '1'246// :53:17: note: when computing vector element at index '1'
247// :53:17: error: use of undefined value here causes illegal behavior247// :53:17: error: use of undefined value here causes illegal behavior
248// :53:17: note: when computing vector element at index '1'248// :53:17: note: when computing vector element at index '1'
249// :53:17: error: use of undefined value here causes illegal behavior249// :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'
251// :53:17: error: use of undefined value here causes illegal behavior251// :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'
253// :53:17: error: use of undefined value here causes illegal behavior253// :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'
255// :53:17: error: use of undefined value here causes illegal behavior255// :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'
257// :53:22: error: use of undefined value here causes illegal behavior257// :53:22: error: use of undefined value here causes illegal behavior
258// :53:22: note: when computing vector element at index '0'258// :53:22: note: when computing vector element at index '0'
259// :53:22: error: use of undefined value here causes illegal behavior259// :53:22: error: use of undefined value here causes illegal behavior
...@@ -281,27 +281,19 @@ const std = @import("std");...@@ -281,27 +281,19 @@ const std = @import("std");
281// :56:27: error: use of undefined value here causes illegal behavior281// :56:27: error: use of undefined value here causes illegal behavior
282// :56:27: error: use of undefined value here causes illegal behavior282// :56:27: error: use of undefined value here causes illegal behavior
283// :56:27: error: use of undefined value here causes illegal behavior283// :56:27: error: use of undefined value here causes illegal behavior
284// :56:27: note: when computing vector element at index '0'
285// :56:27: error: use of undefined value here causes illegal behavior284// :56:27: error: use of undefined value here causes illegal behavior
286// :56:27: note: when computing vector element at index '0'
287// :56:27: error: use of undefined value here causes illegal behavior285// :56:27: error: use of undefined value here causes illegal behavior
288// :56:27: note: when computing vector element at index '0'
289// :56:27: error: use of undefined value here causes illegal behavior286// :56:27: error: use of undefined value here causes illegal behavior
290// :56:27: note: when computing vector element at index '0'
291// :56:27: error: use of undefined value here causes illegal behavior287// :56:27: error: use of undefined value here causes illegal behavior
292// :56:27: note: when computing vector element at index '1'
293// :56:27: error: use of undefined value here causes illegal behavior288// :56:27: error: use of undefined value here causes illegal behavior
294// :56:27: note: when computing vector element at index '1'
295// :56:27: error: use of undefined value here causes illegal behavior289// :56:27: error: use of undefined value here causes illegal behavior
296// :56:27: note: when computing vector element at index '0'
297// :56:27: error: use of undefined value here causes illegal behavior290// :56:27: error: use of undefined value here causes illegal behavior
298// :56:27: note: when computing vector element at index '0'
299// :56:27: error: use of undefined value here causes illegal behavior291// :56:27: error: use of undefined value here causes illegal behavior
300// :56:27: note: when computing vector element at index '0'
301// :56:27: error: use of undefined value here causes illegal behavior292// :56:27: error: use of undefined value here causes illegal behavior
302// :56:27: note: when computing vector element at index '0'
303// :56:27: error: use of undefined value here causes illegal behavior293// :56:27: error: use of undefined value here causes illegal behavior
294// :56:27: note: when computing vector element at index '0'
304// :56:27: error: use of undefined value here causes illegal behavior295// :56:27: error: use of undefined value here causes illegal behavior
296// :56:27: note: when computing vector element at index '0'
305// :56:27: error: use of undefined value here causes illegal behavior297// :56:27: error: use of undefined value here causes illegal behavior
306// :56:27: note: when computing vector element at index '0'298// :56:27: note: when computing vector element at index '0'
307// :56:27: error: use of undefined value here causes illegal behavior299// :56:27: error: use of undefined value here causes illegal behavior
...@@ -311,9 +303,9 @@ const std = @import("std");...@@ -311,9 +303,9 @@ const std = @import("std");
311// :56:27: error: use of undefined value here causes illegal behavior303// :56:27: error: use of undefined value here causes illegal behavior
312// :56:27: note: when computing vector element at index '0'304// :56:27: note: when computing vector element at index '0'
313// :56:27: error: use of undefined value here causes illegal behavior305// :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'
315// :56:27: error: use of undefined value here causes illegal behavior307// :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'
317// :56:27: error: use of undefined value here causes illegal behavior309// :56:27: error: use of undefined value here causes illegal behavior
318// :56:27: note: when computing vector element at index '0'310// :56:27: note: when computing vector element at index '0'
319// :56:27: error: use of undefined value here causes illegal behavior311// :56:27: error: use of undefined value here causes illegal behavior
...@@ -323,7 +315,9 @@ const std = @import("std");...@@ -323,7 +315,9 @@ const std = @import("std");
323// :56:27: error: use of undefined value here causes illegal behavior315// :56:27: error: use of undefined value here causes illegal behavior
324// :56:27: note: when computing vector element at index '0'316// :56:27: note: when computing vector element at index '0'
325// :56:27: error: use of undefined value here causes illegal behavior317// :56:27: error: use of undefined value here causes illegal behavior
318// :56:27: note: when computing vector element at index '0'
326// :56:27: error: use of undefined value here causes illegal behavior319// :56:27: error: use of undefined value here causes illegal behavior
320// :56:27: note: when computing vector element at index '0'
327// :56:27: error: use of undefined value here causes illegal behavior321// :56:27: error: use of undefined value here causes illegal behavior
328// :56:27: note: when computing vector element at index '0'322// :56:27: note: when computing vector element at index '0'
329// :56:27: error: use of undefined value here causes illegal behavior323// :56:27: error: use of undefined value here causes illegal behavior
...@@ -333,9 +327,9 @@ const std = @import("std");...@@ -333,9 +327,9 @@ const std = @import("std");
333// :56:27: error: use of undefined value here causes illegal behavior327// :56:27: error: use of undefined value here causes illegal behavior
334// :56:27: note: when computing vector element at index '0'328// :56:27: note: when computing vector element at index '0'
335// :56:27: error: use of undefined value here causes illegal behavior329// :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'
337// :56:27: error: use of undefined value here causes illegal behavior331// :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'
339// :56:27: error: use of undefined value here causes illegal behavior333// :56:27: error: use of undefined value here causes illegal behavior
340// :56:27: note: when computing vector element at index '0'334// :56:27: note: when computing vector element at index '0'
341// :56:27: error: use of undefined value here causes illegal behavior335// :56:27: error: use of undefined value here causes illegal behavior
...@@ -345,7 +339,9 @@ const std = @import("std");...@@ -345,7 +339,9 @@ const std = @import("std");
345// :56:27: error: use of undefined value here causes illegal behavior339// :56:27: error: use of undefined value here causes illegal behavior
346// :56:27: note: when computing vector element at index '0'340// :56:27: note: when computing vector element at index '0'
347// :56:27: error: use of undefined value here causes illegal behavior341// :56:27: error: use of undefined value here causes illegal behavior
342// :56:27: note: when computing vector element at index '0'
348// :56:27: error: use of undefined value here causes illegal behavior343// :56:27: error: use of undefined value here causes illegal behavior
344// :56:27: note: when computing vector element at index '0'
349// :56:27: error: use of undefined value here causes illegal behavior345// :56:27: error: use of undefined value here causes illegal behavior
350// :56:27: note: when computing vector element at index '0'346// :56:27: note: when computing vector element at index '0'
351// :56:27: error: use of undefined value here causes illegal behavior347// :56:27: error: use of undefined value here causes illegal behavior
...@@ -355,9 +351,9 @@ const std = @import("std");...@@ -355,9 +351,9 @@ const std = @import("std");
355// :56:27: error: use of undefined value here causes illegal behavior351// :56:27: error: use of undefined value here causes illegal behavior
356// :56:27: note: when computing vector element at index '0'352// :56:27: note: when computing vector element at index '0'
357// :56:27: error: use of undefined value here causes illegal behavior353// :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'
359// :56:27: error: use of undefined value here causes illegal behavior355// :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'
361// :56:27: error: use of undefined value here causes illegal behavior357// :56:27: error: use of undefined value here causes illegal behavior
362// :56:27: note: when computing vector element at index '0'358// :56:27: note: when computing vector element at index '0'
363// :56:27: error: use of undefined value here causes illegal behavior359// :56:27: error: use of undefined value here causes illegal behavior
...@@ -367,7 +363,9 @@ const std = @import("std");...@@ -367,7 +363,9 @@ const std = @import("std");
367// :56:27: error: use of undefined value here causes illegal behavior363// :56:27: error: use of undefined value here causes illegal behavior
368// :56:27: note: when computing vector element at index '0'364// :56:27: note: when computing vector element at index '0'
369// :56:27: error: use of undefined value here causes illegal behavior365// :56:27: error: use of undefined value here causes illegal behavior
366// :56:27: note: when computing vector element at index '0'
370// :56:27: error: use of undefined value here causes illegal behavior367// :56:27: error: use of undefined value here causes illegal behavior
368// :56:27: note: when computing vector element at index '0'
371// :56:27: error: use of undefined value here causes illegal behavior369// :56:27: error: use of undefined value here causes illegal behavior
372// :56:27: note: when computing vector element at index '0'370// :56:27: note: when computing vector element at index '0'
373// :56:27: error: use of undefined value here causes illegal behavior371// :56:27: error: use of undefined value here causes illegal behavior
...@@ -377,9 +375,9 @@ const std = @import("std");...@@ -377,9 +375,9 @@ const std = @import("std");
377// :56:27: error: use of undefined value here causes illegal behavior375// :56:27: error: use of undefined value here causes illegal behavior
378// :56:27: note: when computing vector element at index '0'376// :56:27: note: when computing vector element at index '0'
379// :56:27: error: use of undefined value here causes illegal behavior377// :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'
381// :56:27: error: use of undefined value here causes illegal behavior379// :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'
383// :56:27: error: use of undefined value here causes illegal behavior381// :56:27: error: use of undefined value here causes illegal behavior
384// :56:27: note: when computing vector element at index '0'382// :56:27: note: when computing vector element at index '0'
385// :56:27: error: use of undefined value here causes illegal behavior383// :56:27: error: use of undefined value here causes illegal behavior
...@@ -389,27 +387,29 @@ const std = @import("std");...@@ -389,27 +387,29 @@ const std = @import("std");
389// :56:27: error: use of undefined value here causes illegal behavior387// :56:27: error: use of undefined value here causes illegal behavior
390// :56:27: note: when computing vector element at index '0'388// :56:27: note: when computing vector element at index '0'
391// :56:27: error: use of undefined value here causes illegal behavior389// :56:27: error: use of undefined value here causes illegal behavior
390// :56:27: note: when computing vector element at index '1'
392// :56:27: error: use of undefined value here causes illegal behavior391// :56:27: error: use of undefined value here causes illegal behavior
392// :56:27: note: when computing vector element at index '1'
393// :56:27: error: use of undefined value here causes illegal behavior393// :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'
395// :56:27: error: use of undefined value here causes illegal behavior395// :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'
397// :56:27: error: use of undefined value here causes illegal behavior397// :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'
399// :56:27: error: use of undefined value here causes illegal behavior399// :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'
401// :56:27: error: use of undefined value here causes illegal behavior401// :56:27: error: use of undefined value here causes illegal behavior
402// :56:27: note: when computing vector element at index '1'402// :56:27: note: when computing vector element at index '1'
403// :56:27: error: use of undefined value here causes illegal behavior403// :56:27: error: use of undefined value here causes illegal behavior
404// :56:27: note: when computing vector element at index '1'404// :56:27: note: when computing vector element at index '1'
405// :56:27: error: use of undefined value here causes illegal behavior405// :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'
407// :56:27: error: use of undefined value here causes illegal behavior407// :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'
409// :56:27: error: use of undefined value here causes illegal behavior409// :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'
411// :56:27: error: use of undefined value here causes illegal behavior411// :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'
413// :56:30: error: use of undefined value here causes illegal behavior413// :56:30: error: use of undefined value here causes illegal behavior
414// :56:30: note: when computing vector element at index '0'414// :56:30: note: when computing vector element at index '0'
415// :56:30: error: use of undefined value here causes illegal behavior415// :56:30: error: use of undefined value here causes illegal behavior
...@@ -437,27 +437,19 @@ const std = @import("std");...@@ -437,27 +437,19 @@ const std = @import("std");
437// :59:34: error: use of undefined value here causes illegal behavior437// :59:34: error: use of undefined value here causes illegal behavior
438// :59:34: error: use of undefined value here causes illegal behavior438// :59:34: error: use of undefined value here causes illegal behavior
439// :59:34: error: use of undefined value here causes illegal behavior439// :59:34: error: use of undefined value here causes illegal behavior
440// :59:34: note: when computing vector element at index '0'
441// :59:34: error: use of undefined value here causes illegal behavior440// :59:34: error: use of undefined value here causes illegal behavior
442// :59:34: note: when computing vector element at index '0'
443// :59:34: error: use of undefined value here causes illegal behavior441// :59:34: error: use of undefined value here causes illegal behavior
444// :59:34: note: when computing vector element at index '0'
445// :59:34: error: use of undefined value here causes illegal behavior442// :59:34: error: use of undefined value here causes illegal behavior
446// :59:34: note: when computing vector element at index '0'
447// :59:34: error: use of undefined value here causes illegal behavior443// :59:34: error: use of undefined value here causes illegal behavior
448// :59:34: note: when computing vector element at index '1'
449// :59:34: error: use of undefined value here causes illegal behavior444// :59:34: error: use of undefined value here causes illegal behavior
450// :59:34: note: when computing vector element at index '1'
451// :59:34: error: use of undefined value here causes illegal behavior445// :59:34: error: use of undefined value here causes illegal behavior
452// :59:34: note: when computing vector element at index '0'
453// :59:34: error: use of undefined value here causes illegal behavior446// :59:34: error: use of undefined value here causes illegal behavior
454// :59:34: note: when computing vector element at index '0'
455// :59:34: error: use of undefined value here causes illegal behavior447// :59:34: error: use of undefined value here causes illegal behavior
456// :59:34: note: when computing vector element at index '0'
457// :59:34: error: use of undefined value here causes illegal behavior448// :59:34: error: use of undefined value here causes illegal behavior
458// :59:34: note: when computing vector element at index '0'
459// :59:34: error: use of undefined value here causes illegal behavior449// :59:34: error: use of undefined value here causes illegal behavior
450// :59:34: note: when computing vector element at index '0'
460// :59:34: error: use of undefined value here causes illegal behavior451// :59:34: error: use of undefined value here causes illegal behavior
452// :59:34: note: when computing vector element at index '0'
461// :59:34: error: use of undefined value here causes illegal behavior453// :59:34: error: use of undefined value here causes illegal behavior
462// :59:34: note: when computing vector element at index '0'454// :59:34: note: when computing vector element at index '0'
463// :59:34: error: use of undefined value here causes illegal behavior455// :59:34: error: use of undefined value here causes illegal behavior
...@@ -467,9 +459,9 @@ const std = @import("std");...@@ -467,9 +459,9 @@ const std = @import("std");
467// :59:34: error: use of undefined value here causes illegal behavior459// :59:34: error: use of undefined value here causes illegal behavior
468// :59:34: note: when computing vector element at index '0'460// :59:34: note: when computing vector element at index '0'
469// :59:34: error: use of undefined value here causes illegal behavior461// :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'
471// :59:34: error: use of undefined value here causes illegal behavior463// :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'
473// :59:34: error: use of undefined value here causes illegal behavior465// :59:34: error: use of undefined value here causes illegal behavior
474// :59:34: note: when computing vector element at index '0'466// :59:34: note: when computing vector element at index '0'
475// :59:34: error: use of undefined value here causes illegal behavior467// :59:34: error: use of undefined value here causes illegal behavior
...@@ -479,7 +471,9 @@ const std = @import("std");...@@ -479,7 +471,9 @@ const std = @import("std");
479// :59:34: error: use of undefined value here causes illegal behavior471// :59:34: error: use of undefined value here causes illegal behavior
480// :59:34: note: when computing vector element at index '0'472// :59:34: note: when computing vector element at index '0'
481// :59:34: error: use of undefined value here causes illegal behavior473// :59:34: error: use of undefined value here causes illegal behavior
474// :59:34: note: when computing vector element at index '0'
482// :59:34: error: use of undefined value here causes illegal behavior475// :59:34: error: use of undefined value here causes illegal behavior
476// :59:34: note: when computing vector element at index '0'
483// :59:34: error: use of undefined value here causes illegal behavior477// :59:34: error: use of undefined value here causes illegal behavior
484// :59:34: note: when computing vector element at index '0'478// :59:34: note: when computing vector element at index '0'
485// :59:34: error: use of undefined value here causes illegal behavior479// :59:34: error: use of undefined value here causes illegal behavior
...@@ -489,9 +483,9 @@ const std = @import("std");...@@ -489,9 +483,9 @@ const std = @import("std");
489// :59:34: error: use of undefined value here causes illegal behavior483// :59:34: error: use of undefined value here causes illegal behavior
490// :59:34: note: when computing vector element at index '0'484// :59:34: note: when computing vector element at index '0'
491// :59:34: error: use of undefined value here causes illegal behavior485// :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'
493// :59:34: error: use of undefined value here causes illegal behavior487// :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'
495// :59:34: error: use of undefined value here causes illegal behavior489// :59:34: error: use of undefined value here causes illegal behavior
496// :59:34: note: when computing vector element at index '0'490// :59:34: note: when computing vector element at index '0'
497// :59:34: error: use of undefined value here causes illegal behavior491// :59:34: error: use of undefined value here causes illegal behavior
...@@ -501,7 +495,9 @@ const std = @import("std");...@@ -501,7 +495,9 @@ const std = @import("std");
501// :59:34: error: use of undefined value here causes illegal behavior495// :59:34: error: use of undefined value here causes illegal behavior
502// :59:34: note: when computing vector element at index '0'496// :59:34: note: when computing vector element at index '0'
503// :59:34: error: use of undefined value here causes illegal behavior497// :59:34: error: use of undefined value here causes illegal behavior
498// :59:34: note: when computing vector element at index '0'
504// :59:34: error: use of undefined value here causes illegal behavior499// :59:34: error: use of undefined value here causes illegal behavior
500// :59:34: note: when computing vector element at index '0'
505// :59:34: error: use of undefined value here causes illegal behavior501// :59:34: error: use of undefined value here causes illegal behavior
506// :59:34: note: when computing vector element at index '0'502// :59:34: note: when computing vector element at index '0'
507// :59:34: error: use of undefined value here causes illegal behavior503// :59:34: error: use of undefined value here causes illegal behavior
...@@ -511,9 +507,9 @@ const std = @import("std");...@@ -511,9 +507,9 @@ const std = @import("std");
511// :59:34: error: use of undefined value here causes illegal behavior507// :59:34: error: use of undefined value here causes illegal behavior
512// :59:34: note: when computing vector element at index '0'508// :59:34: note: when computing vector element at index '0'
513// :59:34: error: use of undefined value here causes illegal behavior509// :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'
515// :59:34: error: use of undefined value here causes illegal behavior511// :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'
517// :59:34: error: use of undefined value here causes illegal behavior513// :59:34: error: use of undefined value here causes illegal behavior
518// :59:34: note: when computing vector element at index '0'514// :59:34: note: when computing vector element at index '0'
519// :59:34: error: use of undefined value here causes illegal behavior515// :59:34: error: use of undefined value here causes illegal behavior
...@@ -523,7 +519,9 @@ const std = @import("std");...@@ -523,7 +519,9 @@ const std = @import("std");
523// :59:34: error: use of undefined value here causes illegal behavior519// :59:34: error: use of undefined value here causes illegal behavior
524// :59:34: note: when computing vector element at index '0'520// :59:34: note: when computing vector element at index '0'
525// :59:34: error: use of undefined value here causes illegal behavior521// :59:34: error: use of undefined value here causes illegal behavior
522// :59:34: note: when computing vector element at index '0'
526// :59:34: error: use of undefined value here causes illegal behavior523// :59:34: error: use of undefined value here causes illegal behavior
524// :59:34: note: when computing vector element at index '0'
527// :59:34: error: use of undefined value here causes illegal behavior525// :59:34: error: use of undefined value here causes illegal behavior
528// :59:34: note: when computing vector element at index '0'526// :59:34: note: when computing vector element at index '0'
529// :59:34: error: use of undefined value here causes illegal behavior527// :59:34: error: use of undefined value here causes illegal behavior
...@@ -533,9 +531,9 @@ const std = @import("std");...@@ -533,9 +531,9 @@ const std = @import("std");
533// :59:34: error: use of undefined value here causes illegal behavior531// :59:34: error: use of undefined value here causes illegal behavior
534// :59:34: note: when computing vector element at index '0'532// :59:34: note: when computing vector element at index '0'
535// :59:34: error: use of undefined value here causes illegal behavior533// :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'
537// :59:34: error: use of undefined value here causes illegal behavior535// :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'
539// :59:34: error: use of undefined value here causes illegal behavior537// :59:34: error: use of undefined value here causes illegal behavior
540// :59:34: note: when computing vector element at index '0'538// :59:34: note: when computing vector element at index '0'
541// :59:34: error: use of undefined value here causes illegal behavior539// :59:34: error: use of undefined value here causes illegal behavior
...@@ -545,27 +543,29 @@ const std = @import("std");...@@ -545,27 +543,29 @@ const std = @import("std");
545// :59:34: error: use of undefined value here causes illegal behavior543// :59:34: error: use of undefined value here causes illegal behavior
546// :59:34: note: when computing vector element at index '0'544// :59:34: note: when computing vector element at index '0'
547// :59:34: error: use of undefined value here causes illegal behavior545// :59:34: error: use of undefined value here causes illegal behavior
546// :59:34: note: when computing vector element at index '1'
548// :59:34: error: use of undefined value here causes illegal behavior547// :59:34: error: use of undefined value here causes illegal behavior
548// :59:34: note: when computing vector element at index '1'
549// :59:34: error: use of undefined value here causes illegal behavior549// :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'
551// :59:34: error: use of undefined value here causes illegal behavior551// :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'
553// :59:34: error: use of undefined value here causes illegal behavior553// :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'
555// :59:34: error: use of undefined value here causes illegal behavior555// :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'
557// :59:34: error: use of undefined value here causes illegal behavior557// :59:34: error: use of undefined value here causes illegal behavior
558// :59:34: note: when computing vector element at index '1'558// :59:34: note: when computing vector element at index '1'
559// :59:34: error: use of undefined value here causes illegal behavior559// :59:34: error: use of undefined value here causes illegal behavior
560// :59:34: note: when computing vector element at index '1'560// :59:34: note: when computing vector element at index '1'
561// :59:34: error: use of undefined value here causes illegal behavior561// :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'
563// :59:34: error: use of undefined value here causes illegal behavior563// :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'
565// :59:34: error: use of undefined value here causes illegal behavior565// :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'
567// :59:34: error: use of undefined value here causes illegal behavior567// :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'
569// :59:37: error: use of undefined value here causes illegal behavior569// :59:37: error: use of undefined value here causes illegal behavior
570// :59:37: note: when computing vector element at index '0'570// :59:37: note: when computing vector element at index '0'
571// :59:37: error: use of undefined value here causes illegal behavior571// :59:37: error: use of undefined value here causes illegal behavior
...@@ -593,27 +593,19 @@ const std = @import("std");...@@ -593,27 +593,19 @@ const std = @import("std");
593// :62:17: error: use of undefined value here causes illegal behavior593// :62:17: error: use of undefined value here causes illegal behavior
594// :62:17: error: use of undefined value here causes illegal behavior594// :62:17: error: use of undefined value here causes illegal behavior
595// :62:17: error: use of undefined value here causes illegal behavior595// :62:17: error: use of undefined value here causes illegal behavior
596// :62:17: note: when computing vector element at index '0'
597// :62:17: error: use of undefined value here causes illegal behavior596// :62:17: error: use of undefined value here causes illegal behavior
598// :62:17: note: when computing vector element at index '0'
599// :62:17: error: use of undefined value here causes illegal behavior597// :62:17: error: use of undefined value here causes illegal behavior
600// :62:17: note: when computing vector element at index '0'
601// :62:17: error: use of undefined value here causes illegal behavior598// :62:17: error: use of undefined value here causes illegal behavior
602// :62:17: note: when computing vector element at index '0'
603// :62:17: error: use of undefined value here causes illegal behavior599// :62:17: error: use of undefined value here causes illegal behavior
604// :62:17: note: when computing vector element at index '1'
605// :62:17: error: use of undefined value here causes illegal behavior600// :62:17: error: use of undefined value here causes illegal behavior
606// :62:17: note: when computing vector element at index '1'
607// :62:17: error: use of undefined value here causes illegal behavior601// :62:17: error: use of undefined value here causes illegal behavior
608// :62:17: note: when computing vector element at index '0'
609// :62:17: error: use of undefined value here causes illegal behavior602// :62:17: error: use of undefined value here causes illegal behavior
610// :62:17: note: when computing vector element at index '0'
611// :62:17: error: use of undefined value here causes illegal behavior603// :62:17: error: use of undefined value here causes illegal behavior
612// :62:17: note: when computing vector element at index '0'
613// :62:17: error: use of undefined value here causes illegal behavior604// :62:17: error: use of undefined value here causes illegal behavior
614// :62:17: note: when computing vector element at index '0'
615// :62:17: error: use of undefined value here causes illegal behavior605// :62:17: error: use of undefined value here causes illegal behavior
606// :62:17: note: when computing vector element at index '0'
616// :62:17: error: use of undefined value here causes illegal behavior607// :62:17: error: use of undefined value here causes illegal behavior
608// :62:17: note: when computing vector element at index '0'
617// :62:17: error: use of undefined value here causes illegal behavior609// :62:17: error: use of undefined value here causes illegal behavior
618// :62:17: note: when computing vector element at index '0'610// :62:17: note: when computing vector element at index '0'
619// :62:17: error: use of undefined value here causes illegal behavior611// :62:17: error: use of undefined value here causes illegal behavior
...@@ -623,9 +615,9 @@ const std = @import("std");...@@ -623,9 +615,9 @@ const std = @import("std");
623// :62:17: error: use of undefined value here causes illegal behavior615// :62:17: error: use of undefined value here causes illegal behavior
624// :62:17: note: when computing vector element at index '0'616// :62:17: note: when computing vector element at index '0'
625// :62:17: error: use of undefined value here causes illegal behavior617// :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'
627// :62:17: error: use of undefined value here causes illegal behavior619// :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'
629// :62:17: error: use of undefined value here causes illegal behavior621// :62:17: error: use of undefined value here causes illegal behavior
630// :62:17: note: when computing vector element at index '0'622// :62:17: note: when computing vector element at index '0'
631// :62:17: error: use of undefined value here causes illegal behavior623// :62:17: error: use of undefined value here causes illegal behavior
...@@ -635,7 +627,9 @@ const std = @import("std");...@@ -635,7 +627,9 @@ const std = @import("std");
635// :62:17: error: use of undefined value here causes illegal behavior627// :62:17: error: use of undefined value here causes illegal behavior
636// :62:17: note: when computing vector element at index '0'628// :62:17: note: when computing vector element at index '0'
637// :62:17: error: use of undefined value here causes illegal behavior629// :62:17: error: use of undefined value here causes illegal behavior
630// :62:17: note: when computing vector element at index '0'
638// :62:17: error: use of undefined value here causes illegal behavior631// :62:17: error: use of undefined value here causes illegal behavior
632// :62:17: note: when computing vector element at index '0'
639// :62:17: error: use of undefined value here causes illegal behavior633// :62:17: error: use of undefined value here causes illegal behavior
640// :62:17: note: when computing vector element at index '0'634// :62:17: note: when computing vector element at index '0'
641// :62:17: error: use of undefined value here causes illegal behavior635// :62:17: error: use of undefined value here causes illegal behavior
...@@ -645,9 +639,9 @@ const std = @import("std");...@@ -645,9 +639,9 @@ const std = @import("std");
645// :62:17: error: use of undefined value here causes illegal behavior639// :62:17: error: use of undefined value here causes illegal behavior
646// :62:17: note: when computing vector element at index '0'640// :62:17: note: when computing vector element at index '0'
647// :62:17: error: use of undefined value here causes illegal behavior641// :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'
649// :62:17: error: use of undefined value here causes illegal behavior643// :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'
651// :62:17: error: use of undefined value here causes illegal behavior645// :62:17: error: use of undefined value here causes illegal behavior
652// :62:17: note: when computing vector element at index '0'646// :62:17: note: when computing vector element at index '0'
653// :62:17: error: use of undefined value here causes illegal behavior647// :62:17: error: use of undefined value here causes illegal behavior
...@@ -657,7 +651,9 @@ const std = @import("std");...@@ -657,7 +651,9 @@ const std = @import("std");
657// :62:17: error: use of undefined value here causes illegal behavior651// :62:17: error: use of undefined value here causes illegal behavior
658// :62:17: note: when computing vector element at index '0'652// :62:17: note: when computing vector element at index '0'
659// :62:17: error: use of undefined value here causes illegal behavior653// :62:17: error: use of undefined value here causes illegal behavior
654// :62:17: note: when computing vector element at index '0'
660// :62:17: error: use of undefined value here causes illegal behavior655// :62:17: error: use of undefined value here causes illegal behavior
656// :62:17: note: when computing vector element at index '0'
661// :62:17: error: use of undefined value here causes illegal behavior657// :62:17: error: use of undefined value here causes illegal behavior
662// :62:17: note: when computing vector element at index '0'658// :62:17: note: when computing vector element at index '0'
663// :62:17: error: use of undefined value here causes illegal behavior659// :62:17: error: use of undefined value here causes illegal behavior
...@@ -667,9 +663,9 @@ const std = @import("std");...@@ -667,9 +663,9 @@ const std = @import("std");
667// :62:17: error: use of undefined value here causes illegal behavior663// :62:17: error: use of undefined value here causes illegal behavior
668// :62:17: note: when computing vector element at index '0'664// :62:17: note: when computing vector element at index '0'
669// :62:17: error: use of undefined value here causes illegal behavior665// :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'
671// :62:17: error: use of undefined value here causes illegal behavior667// :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'
673// :62:17: error: use of undefined value here causes illegal behavior669// :62:17: error: use of undefined value here causes illegal behavior
674// :62:17: note: when computing vector element at index '0'670// :62:17: note: when computing vector element at index '0'
675// :62:17: error: use of undefined value here causes illegal behavior671// :62:17: error: use of undefined value here causes illegal behavior
...@@ -679,7 +675,9 @@ const std = @import("std");...@@ -679,7 +675,9 @@ const std = @import("std");
679// :62:17: error: use of undefined value here causes illegal behavior675// :62:17: error: use of undefined value here causes illegal behavior
680// :62:17: note: when computing vector element at index '0'676// :62:17: note: when computing vector element at index '0'
681// :62:17: error: use of undefined value here causes illegal behavior677// :62:17: error: use of undefined value here causes illegal behavior
678// :62:17: note: when computing vector element at index '0'
682// :62:17: error: use of undefined value here causes illegal behavior679// :62:17: error: use of undefined value here causes illegal behavior
680// :62:17: note: when computing vector element at index '0'
683// :62:17: error: use of undefined value here causes illegal behavior681// :62:17: error: use of undefined value here causes illegal behavior
684// :62:17: note: when computing vector element at index '0'682// :62:17: note: when computing vector element at index '0'
685// :62:17: error: use of undefined value here causes illegal behavior683// :62:17: error: use of undefined value here causes illegal behavior
...@@ -689,9 +687,9 @@ const std = @import("std");...@@ -689,9 +687,9 @@ const std = @import("std");
689// :62:17: error: use of undefined value here causes illegal behavior687// :62:17: error: use of undefined value here causes illegal behavior
690// :62:17: note: when computing vector element at index '0'688// :62:17: note: when computing vector element at index '0'
691// :62:17: error: use of undefined value here causes illegal behavior689// :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'
693// :62:17: error: use of undefined value here causes illegal behavior691// :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'
695// :62:17: error: use of undefined value here causes illegal behavior693// :62:17: error: use of undefined value here causes illegal behavior
696// :62:17: note: when computing vector element at index '0'694// :62:17: note: when computing vector element at index '0'
697// :62:17: error: use of undefined value here causes illegal behavior695// :62:17: error: use of undefined value here causes illegal behavior
...@@ -701,27 +699,29 @@ const std = @import("std");...@@ -701,27 +699,29 @@ const std = @import("std");
701// :62:17: error: use of undefined value here causes illegal behavior699// :62:17: error: use of undefined value here causes illegal behavior
702// :62:17: note: when computing vector element at index '0'700// :62:17: note: when computing vector element at index '0'
703// :62:17: error: use of undefined value here causes illegal behavior701// :62:17: error: use of undefined value here causes illegal behavior
702// :62:17: note: when computing vector element at index '1'
704// :62:17: error: use of undefined value here causes illegal behavior703// :62:17: error: use of undefined value here causes illegal behavior
704// :62:17: note: when computing vector element at index '1'
705// :62:17: error: use of undefined value here causes illegal behavior705// :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'
707// :62:17: error: use of undefined value here causes illegal behavior707// :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'
709// :62:17: error: use of undefined value here causes illegal behavior709// :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'
711// :62:17: error: use of undefined value here causes illegal behavior711// :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'
713// :62:17: error: use of undefined value here causes illegal behavior713// :62:17: error: use of undefined value here causes illegal behavior
714// :62:17: note: when computing vector element at index '1'714// :62:17: note: when computing vector element at index '1'
715// :62:17: error: use of undefined value here causes illegal behavior715// :62:17: error: use of undefined value here causes illegal behavior
716// :62:17: note: when computing vector element at index '1'716// :62:17: note: when computing vector element at index '1'
717// :62:17: error: use of undefined value here causes illegal behavior717// :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'
719// :62:17: error: use of undefined value here causes illegal behavior719// :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'
721// :62:17: error: use of undefined value here causes illegal behavior721// :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'
723// :62:17: error: use of undefined value here causes illegal behavior723// :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'
725// :62:22: error: use of undefined value here causes illegal behavior725// :62:22: error: use of undefined value here causes illegal behavior
726// :62:22: note: when computing vector element at index '0'726// :62:22: note: when computing vector element at index '0'
727// :62:22: error: use of undefined value here causes illegal behavior727// :62:22: error: use of undefined value here causes illegal behavior
...@@ -749,27 +749,19 @@ const std = @import("std");...@@ -749,27 +749,19 @@ const std = @import("std");
749// :65:27: error: use of undefined value here causes illegal behavior749// :65:27: error: use of undefined value here causes illegal behavior
750// :65:27: error: use of undefined value here causes illegal behavior750// :65:27: error: use of undefined value here causes illegal behavior
751// :65:27: error: use of undefined value here causes illegal behavior751// :65:27: error: use of undefined value here causes illegal behavior
752// :65:27: note: when computing vector element at index '0'
753// :65:27: error: use of undefined value here causes illegal behavior752// :65:27: error: use of undefined value here causes illegal behavior
754// :65:27: note: when computing vector element at index '0'
755// :65:27: error: use of undefined value here causes illegal behavior753// :65:27: error: use of undefined value here causes illegal behavior
756// :65:27: note: when computing vector element at index '0'
757// :65:27: error: use of undefined value here causes illegal behavior754// :65:27: error: use of undefined value here causes illegal behavior
758// :65:27: note: when computing vector element at index '0'
759// :65:27: error: use of undefined value here causes illegal behavior755// :65:27: error: use of undefined value here causes illegal behavior
760// :65:27: note: when computing vector element at index '1'
761// :65:27: error: use of undefined value here causes illegal behavior756// :65:27: error: use of undefined value here causes illegal behavior
762// :65:27: note: when computing vector element at index '1'
763// :65:27: error: use of undefined value here causes illegal behavior757// :65:27: error: use of undefined value here causes illegal behavior
764// :65:27: note: when computing vector element at index '0'
765// :65:27: error: use of undefined value here causes illegal behavior758// :65:27: error: use of undefined value here causes illegal behavior
766// :65:27: note: when computing vector element at index '0'
767// :65:27: error: use of undefined value here causes illegal behavior759// :65:27: error: use of undefined value here causes illegal behavior
768// :65:27: note: when computing vector element at index '0'
769// :65:27: error: use of undefined value here causes illegal behavior760// :65:27: error: use of undefined value here causes illegal behavior
770// :65:27: note: when computing vector element at index '0'
771// :65:27: error: use of undefined value here causes illegal behavior761// :65:27: error: use of undefined value here causes illegal behavior
762// :65:27: note: when computing vector element at index '0'
772// :65:27: error: use of undefined value here causes illegal behavior763// :65:27: error: use of undefined value here causes illegal behavior
764// :65:27: note: when computing vector element at index '0'
773// :65:27: error: use of undefined value here causes illegal behavior765// :65:27: error: use of undefined value here causes illegal behavior
774// :65:27: note: when computing vector element at index '0'766// :65:27: note: when computing vector element at index '0'
775// :65:27: error: use of undefined value here causes illegal behavior767// :65:27: error: use of undefined value here causes illegal behavior
...@@ -779,9 +771,9 @@ const std = @import("std");...@@ -779,9 +771,9 @@ const std = @import("std");
779// :65:27: error: use of undefined value here causes illegal behavior771// :65:27: error: use of undefined value here causes illegal behavior
780// :65:27: note: when computing vector element at index '0'772// :65:27: note: when computing vector element at index '0'
781// :65:27: error: use of undefined value here causes illegal behavior773// :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'
783// :65:27: error: use of undefined value here causes illegal behavior775// :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'
785// :65:27: error: use of undefined value here causes illegal behavior777// :65:27: error: use of undefined value here causes illegal behavior
786// :65:27: note: when computing vector element at index '0'778// :65:27: note: when computing vector element at index '0'
787// :65:27: error: use of undefined value here causes illegal behavior779// :65:27: error: use of undefined value here causes illegal behavior
...@@ -791,7 +783,9 @@ const std = @import("std");...@@ -791,7 +783,9 @@ const std = @import("std");
791// :65:27: error: use of undefined value here causes illegal behavior783// :65:27: error: use of undefined value here causes illegal behavior
792// :65:27: note: when computing vector element at index '0'784// :65:27: note: when computing vector element at index '0'
793// :65:27: error: use of undefined value here causes illegal behavior785// :65:27: error: use of undefined value here causes illegal behavior
786// :65:27: note: when computing vector element at index '0'
794// :65:27: error: use of undefined value here causes illegal behavior787// :65:27: error: use of undefined value here causes illegal behavior
788// :65:27: note: when computing vector element at index '0'
795// :65:27: error: use of undefined value here causes illegal behavior789// :65:27: error: use of undefined value here causes illegal behavior
796// :65:27: note: when computing vector element at index '0'790// :65:27: note: when computing vector element at index '0'
797// :65:27: error: use of undefined value here causes illegal behavior791// :65:27: error: use of undefined value here causes illegal behavior
...@@ -801,9 +795,9 @@ const std = @import("std");...@@ -801,9 +795,9 @@ const std = @import("std");
801// :65:27: error: use of undefined value here causes illegal behavior795// :65:27: error: use of undefined value here causes illegal behavior
802// :65:27: note: when computing vector element at index '0'796// :65:27: note: when computing vector element at index '0'
803// :65:27: error: use of undefined value here causes illegal behavior797// :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'
805// :65:27: error: use of undefined value here causes illegal behavior799// :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'
807// :65:27: error: use of undefined value here causes illegal behavior801// :65:27: error: use of undefined value here causes illegal behavior
808// :65:27: note: when computing vector element at index '0'802// :65:27: note: when computing vector element at index '0'
809// :65:27: error: use of undefined value here causes illegal behavior803// :65:27: error: use of undefined value here causes illegal behavior
...@@ -813,7 +807,9 @@ const std = @import("std");...@@ -813,7 +807,9 @@ const std = @import("std");
813// :65:27: error: use of undefined value here causes illegal behavior807// :65:27: error: use of undefined value here causes illegal behavior
814// :65:27: note: when computing vector element at index '0'808// :65:27: note: when computing vector element at index '0'
815// :65:27: error: use of undefined value here causes illegal behavior809// :65:27: error: use of undefined value here causes illegal behavior
810// :65:27: note: when computing vector element at index '0'
816// :65:27: error: use of undefined value here causes illegal behavior811// :65:27: error: use of undefined value here causes illegal behavior
812// :65:27: note: when computing vector element at index '0'
817// :65:27: error: use of undefined value here causes illegal behavior813// :65:27: error: use of undefined value here causes illegal behavior
818// :65:27: note: when computing vector element at index '0'814// :65:27: note: when computing vector element at index '0'
819// :65:27: error: use of undefined value here causes illegal behavior815// :65:27: error: use of undefined value here causes illegal behavior
...@@ -823,9 +819,9 @@ const std = @import("std");...@@ -823,9 +819,9 @@ const std = @import("std");
823// :65:27: error: use of undefined value here causes illegal behavior819// :65:27: error: use of undefined value here causes illegal behavior
824// :65:27: note: when computing vector element at index '0'820// :65:27: note: when computing vector element at index '0'
825// :65:27: error: use of undefined value here causes illegal behavior821// :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'
827// :65:27: error: use of undefined value here causes illegal behavior823// :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'
829// :65:27: error: use of undefined value here causes illegal behavior825// :65:27: error: use of undefined value here causes illegal behavior
830// :65:27: note: when computing vector element at index '0'826// :65:27: note: when computing vector element at index '0'
831// :65:27: error: use of undefined value here causes illegal behavior827// :65:27: error: use of undefined value here causes illegal behavior
...@@ -835,7 +831,9 @@ const std = @import("std");...@@ -835,7 +831,9 @@ const std = @import("std");
835// :65:27: error: use of undefined value here causes illegal behavior831// :65:27: error: use of undefined value here causes illegal behavior
836// :65:27: note: when computing vector element at index '0'832// :65:27: note: when computing vector element at index '0'
837// :65:27: error: use of undefined value here causes illegal behavior833// :65:27: error: use of undefined value here causes illegal behavior
834// :65:27: note: when computing vector element at index '0'
838// :65:27: error: use of undefined value here causes illegal behavior835// :65:27: error: use of undefined value here causes illegal behavior
836// :65:27: note: when computing vector element at index '0'
839// :65:27: error: use of undefined value here causes illegal behavior837// :65:27: error: use of undefined value here causes illegal behavior
840// :65:27: note: when computing vector element at index '0'838// :65:27: note: when computing vector element at index '0'
841// :65:27: error: use of undefined value here causes illegal behavior839// :65:27: error: use of undefined value here causes illegal behavior
...@@ -845,9 +843,9 @@ const std = @import("std");...@@ -845,9 +843,9 @@ const std = @import("std");
845// :65:27: error: use of undefined value here causes illegal behavior843// :65:27: error: use of undefined value here causes illegal behavior
846// :65:27: note: when computing vector element at index '0'844// :65:27: note: when computing vector element at index '0'
847// :65:27: error: use of undefined value here causes illegal behavior845// :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'
849// :65:27: error: use of undefined value here causes illegal behavior847// :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'
851// :65:27: error: use of undefined value here causes illegal behavior849// :65:27: error: use of undefined value here causes illegal behavior
852// :65:27: note: when computing vector element at index '0'850// :65:27: note: when computing vector element at index '0'
853// :65:27: error: use of undefined value here causes illegal behavior851// :65:27: error: use of undefined value here causes illegal behavior
...@@ -857,27 +855,29 @@ const std = @import("std");...@@ -857,27 +855,29 @@ const std = @import("std");
857// :65:27: error: use of undefined value here causes illegal behavior855// :65:27: error: use of undefined value here causes illegal behavior
858// :65:27: note: when computing vector element at index '0'856// :65:27: note: when computing vector element at index '0'
859// :65:27: error: use of undefined value here causes illegal behavior857// :65:27: error: use of undefined value here causes illegal behavior
858// :65:27: note: when computing vector element at index '1'
860// :65:27: error: use of undefined value here causes illegal behavior859// :65:27: error: use of undefined value here causes illegal behavior
860// :65:27: note: when computing vector element at index '1'
861// :65:27: error: use of undefined value here causes illegal behavior861// :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'
863// :65:27: error: use of undefined value here causes illegal behavior863// :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'
865// :65:27: error: use of undefined value here causes illegal behavior865// :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'
867// :65:27: error: use of undefined value here causes illegal behavior867// :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'
869// :65:27: error: use of undefined value here causes illegal behavior869// :65:27: error: use of undefined value here causes illegal behavior
870// :65:27: note: when computing vector element at index '1'870// :65:27: note: when computing vector element at index '1'
871// :65:27: error: use of undefined value here causes illegal behavior871// :65:27: error: use of undefined value here causes illegal behavior
872// :65:27: note: when computing vector element at index '1'872// :65:27: note: when computing vector element at index '1'
873// :65:27: error: use of undefined value here causes illegal behavior873// :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'
875// :65:27: error: use of undefined value here causes illegal behavior875// :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'
877// :65:27: error: use of undefined value here causes illegal behavior877// :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'
879// :65:27: error: use of undefined value here causes illegal behavior879// :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'
881// :65:30: error: use of undefined value here causes illegal behavior881// :65:30: error: use of undefined value here causes illegal behavior
882// :65:30: note: when computing vector element at index '0'882// :65:30: note: when computing vector element at index '0'
883// :65:30: error: use of undefined value here causes illegal behavior883// :65:30: error: use of undefined value here causes illegal behavior
...@@ -909,21 +909,13 @@ const std = @import("std");...@@ -909,21 +909,13 @@ const std = @import("std");
909// :70:17: error: use of undefined value here causes illegal behavior909// :70:17: error: use of undefined value here causes illegal behavior
910// :70:17: error: use of undefined value here causes illegal behavior910// :70:17: error: use of undefined value here causes illegal behavior
911// :70:17: error: use of undefined value here causes illegal behavior911// :70:17: error: use of undefined value here causes illegal behavior
912// :70:17: note: when computing vector element at index '1'
913// :70:17: error: use of undefined value here causes illegal behavior912// :70:17: error: use of undefined value here causes illegal behavior
914// :70:17: note: when computing vector element at index '1'
915// :70:17: error: use of undefined value here causes illegal behavior913// :70:17: error: use of undefined value here causes illegal behavior
916// :70:17: note: when computing vector element at index '1'
917// :70:17: error: use of undefined value here causes illegal behavior914// :70:17: error: use of undefined value here causes illegal behavior
918// :70:17: note: when computing vector element at index '1'
919// :70:17: error: use of undefined value here causes illegal behavior915// :70:17: error: use of undefined value here causes illegal behavior
920// :70:17: note: when computing vector element at index '0'
921// :70:17: error: use of undefined value here causes illegal behavior916// :70:17: error: use of undefined value here causes illegal behavior
922// :70:17: note: when computing vector element at index '0'
923// :70:17: error: use of undefined value here causes illegal behavior917// :70:17: error: use of undefined value here causes illegal behavior
924// :70:17: note: when computing vector element at index '0'
925// :70:17: error: use of undefined value here causes illegal behavior918// :70:17: error: use of undefined value here causes illegal behavior
926// :70:17: note: when computing vector element at index '0'
927// :70:17: error: use of undefined value here causes illegal behavior919// :70:17: error: use of undefined value here causes illegal behavior
928// :70:17: error: use of undefined value here causes illegal behavior920// :70:17: error: use of undefined value here causes illegal behavior
929// :70:17: error: use of undefined value here causes illegal behavior921// :70:17: error: use of undefined value here causes illegal behavior
...@@ -931,21 +923,13 @@ const std = @import("std");...@@ -931,21 +923,13 @@ const std = @import("std");
931// :70:17: error: use of undefined value here causes illegal behavior923// :70:17: error: use of undefined value here causes illegal behavior
932// :70:17: error: use of undefined value here causes illegal behavior924// :70:17: error: use of undefined value here causes illegal behavior
933// :70:17: error: use of undefined value here causes illegal behavior925// :70:17: error: use of undefined value here causes illegal behavior
934// :70:17: note: when computing vector element at index '1'
935// :70:17: error: use of undefined value here causes illegal behavior926// :70:17: error: use of undefined value here causes illegal behavior
936// :70:17: note: when computing vector element at index '1'
937// :70:17: error: use of undefined value here causes illegal behavior927// :70:17: error: use of undefined value here causes illegal behavior
938// :70:17: note: when computing vector element at index '1'
939// :70:17: error: use of undefined value here causes illegal behavior928// :70:17: error: use of undefined value here causes illegal behavior
940// :70:17: note: when computing vector element at index '1'
941// :70:17: error: use of undefined value here causes illegal behavior929// :70:17: error: use of undefined value here causes illegal behavior
942// :70:17: note: when computing vector element at index '0'
943// :70:17: error: use of undefined value here causes illegal behavior930// :70:17: error: use of undefined value here causes illegal behavior
944// :70:17: note: when computing vector element at index '0'
945// :70:17: error: use of undefined value here causes illegal behavior931// :70:17: error: use of undefined value here causes illegal behavior
946// :70:17: note: when computing vector element at index '0'
947// :70:17: error: use of undefined value here causes illegal behavior932// :70:17: error: use of undefined value here causes illegal behavior
948// :70:17: note: when computing vector element at index '0'
949// :70:17: error: use of undefined value here causes illegal behavior933// :70:17: error: use of undefined value here causes illegal behavior
950// :70:17: error: use of undefined value here causes illegal behavior934// :70:17: error: use of undefined value here causes illegal behavior
951// :70:17: error: use of undefined value here causes illegal behavior935// :70:17: error: use of undefined value here causes illegal behavior
...@@ -953,13 +937,11 @@ const std = @import("std");...@@ -953,13 +937,11 @@ const std = @import("std");
953// :70:17: error: use of undefined value here causes illegal behavior937// :70:17: error: use of undefined value here causes illegal behavior
954// :70:17: error: use of undefined value here causes illegal behavior938// :70:17: error: use of undefined value here causes illegal behavior
955// :70:17: error: use of undefined value here causes illegal behavior939// :70:17: error: use of undefined value here causes illegal behavior
956// :70:17: note: when computing vector element at index '1'
957// :70:17: error: use of undefined value here causes illegal behavior940// :70:17: error: use of undefined value here causes illegal behavior
958// :70:17: note: when computing vector element at index '1'
959// :70:17: error: use of undefined value here causes illegal behavior941// :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'
961// :70:17: error: use of undefined value here causes illegal behavior943// :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'
963// :70:17: error: use of undefined value here causes illegal behavior945// :70:17: error: use of undefined value here causes illegal behavior
964// :70:17: note: when computing vector element at index '0'946// :70:17: note: when computing vector element at index '0'
965// :70:17: error: use of undefined value here causes illegal behavior947// :70:17: error: use of undefined value here causes illegal behavior
...@@ -969,19 +951,25 @@ const std = @import("std");...@@ -969,19 +951,25 @@ const std = @import("std");
969// :70:17: error: use of undefined value here causes illegal behavior951// :70:17: error: use of undefined value here causes illegal behavior
970// :70:17: note: when computing vector element at index '0'952// :70:17: note: when computing vector element at index '0'
971// :70:17: error: use of undefined value here causes illegal behavior953// :70:17: error: use of undefined value here causes illegal behavior
954// :70:17: note: when computing vector element at index '0'
972// :70:17: error: use of undefined value here causes illegal behavior955// :70:17: error: use of undefined value here causes illegal behavior
956// :70:17: note: when computing vector element at index '0'
973// :70:17: error: use of undefined value here causes illegal behavior957// :70:17: error: use of undefined value here causes illegal behavior
958// :70:17: note: when computing vector element at index '0'
974// :70:17: error: use of undefined value here causes illegal behavior959// :70:17: error: use of undefined value here causes illegal behavior
960// :70:17: note: when computing vector element at index '0'
975// :70:17: error: use of undefined value here causes illegal behavior961// :70:17: error: use of undefined value here causes illegal behavior
962// :70:17: note: when computing vector element at index '0'
976// :70:17: error: use of undefined value here causes illegal behavior963// :70:17: error: use of undefined value here causes illegal behavior
964// :70:17: note: when computing vector element at index '0'
977// :70:17: error: use of undefined value here causes illegal behavior965// :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'
979// :70:17: error: use of undefined value here causes illegal behavior967// :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'
981// :70:17: error: use of undefined value here causes illegal behavior969// :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'
983// :70:17: error: use of undefined value here causes illegal behavior971// :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'
985// :70:17: error: use of undefined value here causes illegal behavior973// :70:17: error: use of undefined value here causes illegal behavior
986// :70:17: note: when computing vector element at index '0'974// :70:17: note: when computing vector element at index '0'
987// :70:17: error: use of undefined value here causes illegal behavior975// :70:17: error: use of undefined value here causes illegal behavior
...@@ -991,11 +979,17 @@ const std = @import("std");...@@ -991,11 +979,17 @@ const std = @import("std");
991// :70:17: error: use of undefined value here causes illegal behavior979// :70:17: error: use of undefined value here causes illegal behavior
992// :70:17: note: when computing vector element at index '0'980// :70:17: note: when computing vector element at index '0'
993// :70:17: error: use of undefined value here causes illegal behavior981// :70:17: error: use of undefined value here causes illegal behavior
982// :70:17: note: when computing vector element at index '0'
994// :70:17: error: use of undefined value here causes illegal behavior983// :70:17: error: use of undefined value here causes illegal behavior
984// :70:17: note: when computing vector element at index '0'
995// :70:17: error: use of undefined value here causes illegal behavior985// :70:17: error: use of undefined value here causes illegal behavior
986// :70:17: note: when computing vector element at index '0'
996// :70:17: error: use of undefined value here causes illegal behavior987// :70:17: error: use of undefined value here causes illegal behavior
988// :70:17: note: when computing vector element at index '0'
997// :70:17: error: use of undefined value here causes illegal behavior989// :70:17: error: use of undefined value here causes illegal behavior
990// :70:17: note: when computing vector element at index '1'
998// :70:17: error: use of undefined value here causes illegal behavior991// :70:17: error: use of undefined value here causes illegal behavior
992// :70:17: note: when computing vector element at index '1'
999// :70:17: error: use of undefined value here causes illegal behavior993// :70:17: error: use of undefined value here causes illegal behavior
1000// :70:17: note: when computing vector element at index '1'994// :70:17: note: when computing vector element at index '1'
1001// :70:17: error: use of undefined value here causes illegal behavior995// :70:17: error: use of undefined value here causes illegal behavior
...@@ -1005,19 +999,25 @@ const std = @import("std");...@@ -1005,19 +999,25 @@ const std = @import("std");
1005// :70:17: error: use of undefined value here causes illegal behavior999// :70:17: error: use of undefined value here causes illegal behavior
1006// :70:17: note: when computing vector element at index '1'1000// :70:17: note: when computing vector element at index '1'
1007// :70:17: error: use of undefined value here causes illegal behavior1001// :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'
1009// :70:17: error: use of undefined value here causes illegal behavior1003// :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'
1011// :70:17: error: use of undefined value here causes illegal behavior1005// :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'
1013// :70:17: error: use of undefined value here causes illegal behavior1007// :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'
1015// :70:17: error: use of undefined value here causes illegal behavior1009// :70:17: error: use of undefined value here causes illegal behavior
1010// :70:17: note: when computing vector element at index '1'
1016// :70:17: error: use of undefined value here causes illegal behavior1011// :70:17: error: use of undefined value here causes illegal behavior
1012// :70:17: note: when computing vector element at index '1'
1017// :70:17: error: use of undefined value here causes illegal behavior1013// :70:17: error: use of undefined value here causes illegal behavior
1014// :70:17: note: when computing vector element at index '1'
1018// :70:17: error: use of undefined value here causes illegal behavior1015// :70:17: error: use of undefined value here causes illegal behavior
1016// :70:17: note: when computing vector element at index '1'
1019// :70:17: error: use of undefined value here causes illegal behavior1017// :70:17: error: use of undefined value here causes illegal behavior
1018// :70:17: note: when computing vector element at index '1'
1020// :70:17: error: use of undefined value here causes illegal behavior1019// :70:17: error: use of undefined value here causes illegal behavior
1020// :70:17: note: when computing vector element at index '1'
1021// :70:17: error: use of undefined value here causes illegal behavior1021// :70:17: error: use of undefined value here causes illegal behavior
1022// :70:17: note: when computing vector element at index '1'1022// :70:17: note: when computing vector element at index '1'
1023// :70:17: error: use of undefined value here causes illegal behavior1023// :70:17: error: use of undefined value here causes illegal behavior
...@@ -1027,13 +1027,13 @@ const std = @import("std");...@@ -1027,13 +1027,13 @@ const std = @import("std");
1027// :70:17: error: use of undefined value here causes illegal behavior1027// :70:17: error: use of undefined value here causes illegal behavior
1028// :70:17: note: when computing vector element at index '1'1028// :70:17: note: when computing vector element at index '1'
1029// :70:17: error: use of undefined value here causes illegal behavior1029// :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'
1031// :70:17: error: use of undefined value here causes illegal behavior1031// :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'
1033// :70:17: error: use of undefined value here causes illegal behavior1033// :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'
1035// :70:17: error: use of undefined value here causes illegal behavior1035// :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'
1037// :73:27: error: use of undefined value here causes illegal behavior1037// :73:27: error: use of undefined value here causes illegal behavior
1038// :73:27: error: use of undefined value here causes illegal behavior1038// :73:27: error: use of undefined value here causes illegal behavior
1039// :73:27: error: use of undefined value here causes illegal behavior1039// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1041,21 +1041,13 @@ const std = @import("std");...@@ -1041,21 +1041,13 @@ const std = @import("std");
1041// :73:27: error: use of undefined value here causes illegal behavior1041// :73:27: error: use of undefined value here causes illegal behavior
1042// :73:27: error: use of undefined value here causes illegal behavior1042// :73:27: error: use of undefined value here causes illegal behavior
1043// :73:27: error: use of undefined value here causes illegal behavior1043// :73:27: error: use of undefined value here causes illegal behavior
1044// :73:27: note: when computing vector element at index '1'
1045// :73:27: error: use of undefined value here causes illegal behavior1044// :73:27: error: use of undefined value here causes illegal behavior
1046// :73:27: note: when computing vector element at index '1'
1047// :73:27: error: use of undefined value here causes illegal behavior1045// :73:27: error: use of undefined value here causes illegal behavior
1048// :73:27: note: when computing vector element at index '1'
1049// :73:27: error: use of undefined value here causes illegal behavior1046// :73:27: error: use of undefined value here causes illegal behavior
1050// :73:27: note: when computing vector element at index '1'
1051// :73:27: error: use of undefined value here causes illegal behavior1047// :73:27: error: use of undefined value here causes illegal behavior
1052// :73:27: note: when computing vector element at index '0'
1053// :73:27: error: use of undefined value here causes illegal behavior1048// :73:27: error: use of undefined value here causes illegal behavior
1054// :73:27: note: when computing vector element at index '0'
1055// :73:27: error: use of undefined value here causes illegal behavior1049// :73:27: error: use of undefined value here causes illegal behavior
1056// :73:27: note: when computing vector element at index '0'
1057// :73:27: error: use of undefined value here causes illegal behavior1050// :73:27: error: use of undefined value here causes illegal behavior
1058// :73:27: note: when computing vector element at index '0'
1059// :73:27: error: use of undefined value here causes illegal behavior1051// :73:27: error: use of undefined value here causes illegal behavior
1060// :73:27: error: use of undefined value here causes illegal behavior1052// :73:27: error: use of undefined value here causes illegal behavior
1061// :73:27: error: use of undefined value here causes illegal behavior1053// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1063,21 +1055,13 @@ const std = @import("std");...@@ -1063,21 +1055,13 @@ const std = @import("std");
1063// :73:27: error: use of undefined value here causes illegal behavior1055// :73:27: error: use of undefined value here causes illegal behavior
1064// :73:27: error: use of undefined value here causes illegal behavior1056// :73:27: error: use of undefined value here causes illegal behavior
1065// :73:27: error: use of undefined value here causes illegal behavior1057// :73:27: error: use of undefined value here causes illegal behavior
1066// :73:27: note: when computing vector element at index '1'
1067// :73:27: error: use of undefined value here causes illegal behavior1058// :73:27: error: use of undefined value here causes illegal behavior
1068// :73:27: note: when computing vector element at index '1'
1069// :73:27: error: use of undefined value here causes illegal behavior1059// :73:27: error: use of undefined value here causes illegal behavior
1070// :73:27: note: when computing vector element at index '1'
1071// :73:27: error: use of undefined value here causes illegal behavior1060// :73:27: error: use of undefined value here causes illegal behavior
1072// :73:27: note: when computing vector element at index '1'
1073// :73:27: error: use of undefined value here causes illegal behavior1061// :73:27: error: use of undefined value here causes illegal behavior
1074// :73:27: note: when computing vector element at index '0'
1075// :73:27: error: use of undefined value here causes illegal behavior1062// :73:27: error: use of undefined value here causes illegal behavior
1076// :73:27: note: when computing vector element at index '0'
1077// :73:27: error: use of undefined value here causes illegal behavior1063// :73:27: error: use of undefined value here causes illegal behavior
1078// :73:27: note: when computing vector element at index '0'
1079// :73:27: error: use of undefined value here causes illegal behavior1064// :73:27: error: use of undefined value here causes illegal behavior
1080// :73:27: note: when computing vector element at index '0'
1081// :73:27: error: use of undefined value here causes illegal behavior1065// :73:27: error: use of undefined value here causes illegal behavior
1082// :73:27: error: use of undefined value here causes illegal behavior1066// :73:27: error: use of undefined value here causes illegal behavior
1083// :73:27: error: use of undefined value here causes illegal behavior1067// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1085,13 +1069,11 @@ const std = @import("std");...@@ -1085,13 +1069,11 @@ const std = @import("std");
1085// :73:27: error: use of undefined value here causes illegal behavior1069// :73:27: error: use of undefined value here causes illegal behavior
1086// :73:27: error: use of undefined value here causes illegal behavior1070// :73:27: error: use of undefined value here causes illegal behavior
1087// :73:27: error: use of undefined value here causes illegal behavior1071// :73:27: error: use of undefined value here causes illegal behavior
1088// :73:27: note: when computing vector element at index '1'
1089// :73:27: error: use of undefined value here causes illegal behavior1072// :73:27: error: use of undefined value here causes illegal behavior
1090// :73:27: note: when computing vector element at index '1'
1091// :73:27: error: use of undefined value here causes illegal behavior1073// :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'
1093// :73:27: error: use of undefined value here causes illegal behavior1075// :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'
1095// :73:27: error: use of undefined value here causes illegal behavior1077// :73:27: error: use of undefined value here causes illegal behavior
1096// :73:27: note: when computing vector element at index '0'1078// :73:27: note: when computing vector element at index '0'
1097// :73:27: error: use of undefined value here causes illegal behavior1079// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1101,19 +1083,25 @@ const std = @import("std");...@@ -1101,19 +1083,25 @@ const std = @import("std");
1101// :73:27: error: use of undefined value here causes illegal behavior1083// :73:27: error: use of undefined value here causes illegal behavior
1102// :73:27: note: when computing vector element at index '0'1084// :73:27: note: when computing vector element at index '0'
1103// :73:27: error: use of undefined value here causes illegal behavior1085// :73:27: error: use of undefined value here causes illegal behavior
1086// :73:27: note: when computing vector element at index '0'
1104// :73:27: error: use of undefined value here causes illegal behavior1087// :73:27: error: use of undefined value here causes illegal behavior
1088// :73:27: note: when computing vector element at index '0'
1105// :73:27: error: use of undefined value here causes illegal behavior1089// :73:27: error: use of undefined value here causes illegal behavior
1090// :73:27: note: when computing vector element at index '0'
1106// :73:27: error: use of undefined value here causes illegal behavior1091// :73:27: error: use of undefined value here causes illegal behavior
1092// :73:27: note: when computing vector element at index '0'
1107// :73:27: error: use of undefined value here causes illegal behavior1093// :73:27: error: use of undefined value here causes illegal behavior
1094// :73:27: note: when computing vector element at index '0'
1108// :73:27: error: use of undefined value here causes illegal behavior1095// :73:27: error: use of undefined value here causes illegal behavior
1096// :73:27: note: when computing vector element at index '0'
1109// :73:27: error: use of undefined value here causes illegal behavior1097// :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'
1111// :73:27: error: use of undefined value here causes illegal behavior1099// :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'
1113// :73:27: error: use of undefined value here causes illegal behavior1101// :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'
1115// :73:27: error: use of undefined value here causes illegal behavior1103// :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'
1117// :73:27: error: use of undefined value here causes illegal behavior1105// :73:27: error: use of undefined value here causes illegal behavior
1118// :73:27: note: when computing vector element at index '0'1106// :73:27: note: when computing vector element at index '0'
1119// :73:27: error: use of undefined value here causes illegal behavior1107// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1123,11 +1111,17 @@ const std = @import("std");...@@ -1123,11 +1111,17 @@ const std = @import("std");
1123// :73:27: error: use of undefined value here causes illegal behavior1111// :73:27: error: use of undefined value here causes illegal behavior
1124// :73:27: note: when computing vector element at index '0'1112// :73:27: note: when computing vector element at index '0'
1125// :73:27: error: use of undefined value here causes illegal behavior1113// :73:27: error: use of undefined value here causes illegal behavior
1114// :73:27: note: when computing vector element at index '0'
1126// :73:27: error: use of undefined value here causes illegal behavior1115// :73:27: error: use of undefined value here causes illegal behavior
1116// :73:27: note: when computing vector element at index '0'
1127// :73:27: error: use of undefined value here causes illegal behavior1117// :73:27: error: use of undefined value here causes illegal behavior
1118// :73:27: note: when computing vector element at index '0'
1128// :73:27: error: use of undefined value here causes illegal behavior1119// :73:27: error: use of undefined value here causes illegal behavior
1120// :73:27: note: when computing vector element at index '0'
1129// :73:27: error: use of undefined value here causes illegal behavior1121// :73:27: error: use of undefined value here causes illegal behavior
1122// :73:27: note: when computing vector element at index '1'
1130// :73:27: error: use of undefined value here causes illegal behavior1123// :73:27: error: use of undefined value here causes illegal behavior
1124// :73:27: note: when computing vector element at index '1'
1131// :73:27: error: use of undefined value here causes illegal behavior1125// :73:27: error: use of undefined value here causes illegal behavior
1132// :73:27: note: when computing vector element at index '1'1126// :73:27: note: when computing vector element at index '1'
1133// :73:27: error: use of undefined value here causes illegal behavior1127// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1137,19 +1131,25 @@ const std = @import("std");...@@ -1137,19 +1131,25 @@ const std = @import("std");
1137// :73:27: error: use of undefined value here causes illegal behavior1131// :73:27: error: use of undefined value here causes illegal behavior
1138// :73:27: note: when computing vector element at index '1'1132// :73:27: note: when computing vector element at index '1'
1139// :73:27: error: use of undefined value here causes illegal behavior1133// :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'
1141// :73:27: error: use of undefined value here causes illegal behavior1135// :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'
1143// :73:27: error: use of undefined value here causes illegal behavior1137// :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'
1145// :73:27: error: use of undefined value here causes illegal behavior1139// :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'
1147// :73:27: error: use of undefined value here causes illegal behavior1141// :73:27: error: use of undefined value here causes illegal behavior
1142// :73:27: note: when computing vector element at index '1'
1148// :73:27: error: use of undefined value here causes illegal behavior1143// :73:27: error: use of undefined value here causes illegal behavior
1144// :73:27: note: when computing vector element at index '1'
1149// :73:27: error: use of undefined value here causes illegal behavior1145// :73:27: error: use of undefined value here causes illegal behavior
1146// :73:27: note: when computing vector element at index '1'
1150// :73:27: error: use of undefined value here causes illegal behavior1147// :73:27: error: use of undefined value here causes illegal behavior
1148// :73:27: note: when computing vector element at index '1'
1151// :73:27: error: use of undefined value here causes illegal behavior1149// :73:27: error: use of undefined value here causes illegal behavior
1150// :73:27: note: when computing vector element at index '1'
1152// :73:27: error: use of undefined value here causes illegal behavior1151// :73:27: error: use of undefined value here causes illegal behavior
1152// :73:27: note: when computing vector element at index '1'
1153// :73:27: error: use of undefined value here causes illegal behavior1153// :73:27: error: use of undefined value here causes illegal behavior
1154// :73:27: note: when computing vector element at index '1'1154// :73:27: note: when computing vector element at index '1'
1155// :73:27: error: use of undefined value here causes illegal behavior1155// :73:27: error: use of undefined value here causes illegal behavior
...@@ -1159,13 +1159,13 @@ const std = @import("std");...@@ -1159,13 +1159,13 @@ const std = @import("std");
1159// :73:27: error: use of undefined value here causes illegal behavior1159// :73:27: error: use of undefined value here causes illegal behavior
1160// :73:27: note: when computing vector element at index '1'1160// :73:27: note: when computing vector element at index '1'
1161// :73:27: error: use of undefined value here causes illegal behavior1161// :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'
1163// :73:27: error: use of undefined value here causes illegal behavior1163// :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'
1165// :73:27: error: use of undefined value here causes illegal behavior1165// :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'
1167// :73:27: error: use of undefined value here causes illegal behavior1167// :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'
1169// :76:34: error: use of undefined value here causes illegal behavior1169// :76:34: error: use of undefined value here causes illegal behavior
1170// :76:34: error: use of undefined value here causes illegal behavior1170// :76:34: error: use of undefined value here causes illegal behavior
1171// :76:34: error: use of undefined value here causes illegal behavior1171// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1173,21 +1173,13 @@ const std = @import("std");...@@ -1173,21 +1173,13 @@ const std = @import("std");
1173// :76:34: error: use of undefined value here causes illegal behavior1173// :76:34: error: use of undefined value here causes illegal behavior
1174// :76:34: error: use of undefined value here causes illegal behavior1174// :76:34: error: use of undefined value here causes illegal behavior
1175// :76:34: error: use of undefined value here causes illegal behavior1175// :76:34: error: use of undefined value here causes illegal behavior
1176// :76:34: note: when computing vector element at index '1'
1177// :76:34: error: use of undefined value here causes illegal behavior1176// :76:34: error: use of undefined value here causes illegal behavior
1178// :76:34: note: when computing vector element at index '1'
1179// :76:34: error: use of undefined value here causes illegal behavior1177// :76:34: error: use of undefined value here causes illegal behavior
1180// :76:34: note: when computing vector element at index '1'
1181// :76:34: error: use of undefined value here causes illegal behavior1178// :76:34: error: use of undefined value here causes illegal behavior
1182// :76:34: note: when computing vector element at index '1'
1183// :76:34: error: use of undefined value here causes illegal behavior1179// :76:34: error: use of undefined value here causes illegal behavior
1184// :76:34: note: when computing vector element at index '0'
1185// :76:34: error: use of undefined value here causes illegal behavior1180// :76:34: error: use of undefined value here causes illegal behavior
1186// :76:34: note: when computing vector element at index '0'
1187// :76:34: error: use of undefined value here causes illegal behavior1181// :76:34: error: use of undefined value here causes illegal behavior
1188// :76:34: note: when computing vector element at index '0'
1189// :76:34: error: use of undefined value here causes illegal behavior1182// :76:34: error: use of undefined value here causes illegal behavior
1190// :76:34: note: when computing vector element at index '0'
1191// :76:34: error: use of undefined value here causes illegal behavior1183// :76:34: error: use of undefined value here causes illegal behavior
1192// :76:34: error: use of undefined value here causes illegal behavior1184// :76:34: error: use of undefined value here causes illegal behavior
1193// :76:34: error: use of undefined value here causes illegal behavior1185// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1195,21 +1187,13 @@ const std = @import("std");...@@ -1195,21 +1187,13 @@ const std = @import("std");
1195// :76:34: error: use of undefined value here causes illegal behavior1187// :76:34: error: use of undefined value here causes illegal behavior
1196// :76:34: error: use of undefined value here causes illegal behavior1188// :76:34: error: use of undefined value here causes illegal behavior
1197// :76:34: error: use of undefined value here causes illegal behavior1189// :76:34: error: use of undefined value here causes illegal behavior
1198// :76:34: note: when computing vector element at index '1'
1199// :76:34: error: use of undefined value here causes illegal behavior1190// :76:34: error: use of undefined value here causes illegal behavior
1200// :76:34: note: when computing vector element at index '1'
1201// :76:34: error: use of undefined value here causes illegal behavior1191// :76:34: error: use of undefined value here causes illegal behavior
1202// :76:34: note: when computing vector element at index '1'
1203// :76:34: error: use of undefined value here causes illegal behavior1192// :76:34: error: use of undefined value here causes illegal behavior
1204// :76:34: note: when computing vector element at index '1'
1205// :76:34: error: use of undefined value here causes illegal behavior1193// :76:34: error: use of undefined value here causes illegal behavior
1206// :76:34: note: when computing vector element at index '0'
1207// :76:34: error: use of undefined value here causes illegal behavior1194// :76:34: error: use of undefined value here causes illegal behavior
1208// :76:34: note: when computing vector element at index '0'
1209// :76:34: error: use of undefined value here causes illegal behavior1195// :76:34: error: use of undefined value here causes illegal behavior
1210// :76:34: note: when computing vector element at index '0'
1211// :76:34: error: use of undefined value here causes illegal behavior1196// :76:34: error: use of undefined value here causes illegal behavior
1212// :76:34: note: when computing vector element at index '0'
1213// :76:34: error: use of undefined value here causes illegal behavior1197// :76:34: error: use of undefined value here causes illegal behavior
1214// :76:34: error: use of undefined value here causes illegal behavior1198// :76:34: error: use of undefined value here causes illegal behavior
1215// :76:34: error: use of undefined value here causes illegal behavior1199// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1217,13 +1201,11 @@ const std = @import("std");...@@ -1217,13 +1201,11 @@ const std = @import("std");
1217// :76:34: error: use of undefined value here causes illegal behavior1201// :76:34: error: use of undefined value here causes illegal behavior
1218// :76:34: error: use of undefined value here causes illegal behavior1202// :76:34: error: use of undefined value here causes illegal behavior
1219// :76:34: error: use of undefined value here causes illegal behavior1203// :76:34: error: use of undefined value here causes illegal behavior
1220// :76:34: note: when computing vector element at index '1'
1221// :76:34: error: use of undefined value here causes illegal behavior1204// :76:34: error: use of undefined value here causes illegal behavior
1222// :76:34: note: when computing vector element at index '1'
1223// :76:34: error: use of undefined value here causes illegal behavior1205// :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'
1225// :76:34: error: use of undefined value here causes illegal behavior1207// :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'
1227// :76:34: error: use of undefined value here causes illegal behavior1209// :76:34: error: use of undefined value here causes illegal behavior
1228// :76:34: note: when computing vector element at index '0'1210// :76:34: note: when computing vector element at index '0'
1229// :76:34: error: use of undefined value here causes illegal behavior1211// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1233,19 +1215,25 @@ const std = @import("std");...@@ -1233,19 +1215,25 @@ const std = @import("std");
1233// :76:34: error: use of undefined value here causes illegal behavior1215// :76:34: error: use of undefined value here causes illegal behavior
1234// :76:34: note: when computing vector element at index '0'1216// :76:34: note: when computing vector element at index '0'
1235// :76:34: error: use of undefined value here causes illegal behavior1217// :76:34: error: use of undefined value here causes illegal behavior
1218// :76:34: note: when computing vector element at index '0'
1236// :76:34: error: use of undefined value here causes illegal behavior1219// :76:34: error: use of undefined value here causes illegal behavior
1220// :76:34: note: when computing vector element at index '0'
1237// :76:34: error: use of undefined value here causes illegal behavior1221// :76:34: error: use of undefined value here causes illegal behavior
1222// :76:34: note: when computing vector element at index '0'
1238// :76:34: error: use of undefined value here causes illegal behavior1223// :76:34: error: use of undefined value here causes illegal behavior
1224// :76:34: note: when computing vector element at index '0'
1239// :76:34: error: use of undefined value here causes illegal behavior1225// :76:34: error: use of undefined value here causes illegal behavior
1226// :76:34: note: when computing vector element at index '0'
1240// :76:34: error: use of undefined value here causes illegal behavior1227// :76:34: error: use of undefined value here causes illegal behavior
1228// :76:34: note: when computing vector element at index '0'
1241// :76:34: error: use of undefined value here causes illegal behavior1229// :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'
1243// :76:34: error: use of undefined value here causes illegal behavior1231// :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'
1245// :76:34: error: use of undefined value here causes illegal behavior1233// :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'
1247// :76:34: error: use of undefined value here causes illegal behavior1235// :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'
1249// :76:34: error: use of undefined value here causes illegal behavior1237// :76:34: error: use of undefined value here causes illegal behavior
1250// :76:34: note: when computing vector element at index '0'1238// :76:34: note: when computing vector element at index '0'
1251// :76:34: error: use of undefined value here causes illegal behavior1239// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1255,11 +1243,17 @@ const std = @import("std");...@@ -1255,11 +1243,17 @@ const std = @import("std");
1255// :76:34: error: use of undefined value here causes illegal behavior1243// :76:34: error: use of undefined value here causes illegal behavior
1256// :76:34: note: when computing vector element at index '0'1244// :76:34: note: when computing vector element at index '0'
1257// :76:34: error: use of undefined value here causes illegal behavior1245// :76:34: error: use of undefined value here causes illegal behavior
1246// :76:34: note: when computing vector element at index '0'
1258// :76:34: error: use of undefined value here causes illegal behavior1247// :76:34: error: use of undefined value here causes illegal behavior
1248// :76:34: note: when computing vector element at index '0'
1259// :76:34: error: use of undefined value here causes illegal behavior1249// :76:34: error: use of undefined value here causes illegal behavior
1250// :76:34: note: when computing vector element at index '0'
1260// :76:34: error: use of undefined value here causes illegal behavior1251// :76:34: error: use of undefined value here causes illegal behavior
1252// :76:34: note: when computing vector element at index '0'
1261// :76:34: error: use of undefined value here causes illegal behavior1253// :76:34: error: use of undefined value here causes illegal behavior
1254// :76:34: note: when computing vector element at index '1'
1262// :76:34: error: use of undefined value here causes illegal behavior1255// :76:34: error: use of undefined value here causes illegal behavior
1256// :76:34: note: when computing vector element at index '1'
1263// :76:34: error: use of undefined value here causes illegal behavior1257// :76:34: error: use of undefined value here causes illegal behavior
1264// :76:34: note: when computing vector element at index '1'1258// :76:34: note: when computing vector element at index '1'
1265// :76:34: error: use of undefined value here causes illegal behavior1259// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1269,19 +1263,25 @@ const std = @import("std");...@@ -1269,19 +1263,25 @@ const std = @import("std");
1269// :76:34: error: use of undefined value here causes illegal behavior1263// :76:34: error: use of undefined value here causes illegal behavior
1270// :76:34: note: when computing vector element at index '1'1264// :76:34: note: when computing vector element at index '1'
1271// :76:34: error: use of undefined value here causes illegal behavior1265// :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'
1273// :76:34: error: use of undefined value here causes illegal behavior1267// :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'
1275// :76:34: error: use of undefined value here causes illegal behavior1269// :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'
1277// :76:34: error: use of undefined value here causes illegal behavior1271// :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'
1279// :76:34: error: use of undefined value here causes illegal behavior1273// :76:34: error: use of undefined value here causes illegal behavior
1274// :76:34: note: when computing vector element at index '1'
1280// :76:34: error: use of undefined value here causes illegal behavior1275// :76:34: error: use of undefined value here causes illegal behavior
1276// :76:34: note: when computing vector element at index '1'
1281// :76:34: error: use of undefined value here causes illegal behavior1277// :76:34: error: use of undefined value here causes illegal behavior
1278// :76:34: note: when computing vector element at index '1'
1282// :76:34: error: use of undefined value here causes illegal behavior1279// :76:34: error: use of undefined value here causes illegal behavior
1280// :76:34: note: when computing vector element at index '1'
1283// :76:34: error: use of undefined value here causes illegal behavior1281// :76:34: error: use of undefined value here causes illegal behavior
1282// :76:34: note: when computing vector element at index '1'
1284// :76:34: error: use of undefined value here causes illegal behavior1283// :76:34: error: use of undefined value here causes illegal behavior
1284// :76:34: note: when computing vector element at index '1'
1285// :76:34: error: use of undefined value here causes illegal behavior1285// :76:34: error: use of undefined value here causes illegal behavior
1286// :76:34: note: when computing vector element at index '1'1286// :76:34: note: when computing vector element at index '1'
1287// :76:34: error: use of undefined value here causes illegal behavior1287// :76:34: error: use of undefined value here causes illegal behavior
...@@ -1291,13 +1291,13 @@ const std = @import("std");...@@ -1291,13 +1291,13 @@ const std = @import("std");
1291// :76:34: error: use of undefined value here causes illegal behavior1291// :76:34: error: use of undefined value here causes illegal behavior
1292// :76:34: note: when computing vector element at index '1'1292// :76:34: note: when computing vector element at index '1'
1293// :76:34: error: use of undefined value here causes illegal behavior1293// :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'
1295// :76:34: error: use of undefined value here causes illegal behavior1295// :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'
1297// :76:34: error: use of undefined value here causes illegal behavior1297// :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'
1299// :76:34: error: use of undefined value here causes illegal behavior1299// :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'
1301// :79:17: error: use of undefined value here causes illegal behavior1301// :79:17: error: use of undefined value here causes illegal behavior
1302// :79:17: error: use of undefined value here causes illegal behavior1302// :79:17: error: use of undefined value here causes illegal behavior
1303// :79:17: error: use of undefined value here causes illegal behavior1303// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1305,21 +1305,13 @@ const std = @import("std");...@@ -1305,21 +1305,13 @@ const std = @import("std");
1305// :79:17: error: use of undefined value here causes illegal behavior1305// :79:17: error: use of undefined value here causes illegal behavior
1306// :79:17: error: use of undefined value here causes illegal behavior1306// :79:17: error: use of undefined value here causes illegal behavior
1307// :79:17: error: use of undefined value here causes illegal behavior1307// :79:17: error: use of undefined value here causes illegal behavior
1308// :79:17: note: when computing vector element at index '1'
1309// :79:17: error: use of undefined value here causes illegal behavior1308// :79:17: error: use of undefined value here causes illegal behavior
1310// :79:17: note: when computing vector element at index '1'
1311// :79:17: error: use of undefined value here causes illegal behavior1309// :79:17: error: use of undefined value here causes illegal behavior
1312// :79:17: note: when computing vector element at index '1'
1313// :79:17: error: use of undefined value here causes illegal behavior1310// :79:17: error: use of undefined value here causes illegal behavior
1314// :79:17: note: when computing vector element at index '1'
1315// :79:17: error: use of undefined value here causes illegal behavior1311// :79:17: error: use of undefined value here causes illegal behavior
1316// :79:17: note: when computing vector element at index '0'
1317// :79:17: error: use of undefined value here causes illegal behavior1312// :79:17: error: use of undefined value here causes illegal behavior
1318// :79:17: note: when computing vector element at index '0'
1319// :79:17: error: use of undefined value here causes illegal behavior1313// :79:17: error: use of undefined value here causes illegal behavior
1320// :79:17: note: when computing vector element at index '0'
1321// :79:17: error: use of undefined value here causes illegal behavior1314// :79:17: error: use of undefined value here causes illegal behavior
1322// :79:17: note: when computing vector element at index '0'
1323// :79:17: error: use of undefined value here causes illegal behavior1315// :79:17: error: use of undefined value here causes illegal behavior
1324// :79:17: error: use of undefined value here causes illegal behavior1316// :79:17: error: use of undefined value here causes illegal behavior
1325// :79:17: error: use of undefined value here causes illegal behavior1317// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1327,21 +1319,13 @@ const std = @import("std");...@@ -1327,21 +1319,13 @@ const std = @import("std");
1327// :79:17: error: use of undefined value here causes illegal behavior1319// :79:17: error: use of undefined value here causes illegal behavior
1328// :79:17: error: use of undefined value here causes illegal behavior1320// :79:17: error: use of undefined value here causes illegal behavior
1329// :79:17: error: use of undefined value here causes illegal behavior1321// :79:17: error: use of undefined value here causes illegal behavior
1330// :79:17: note: when computing vector element at index '1'
1331// :79:17: error: use of undefined value here causes illegal behavior1322// :79:17: error: use of undefined value here causes illegal behavior
1332// :79:17: note: when computing vector element at index '1'
1333// :79:17: error: use of undefined value here causes illegal behavior1323// :79:17: error: use of undefined value here causes illegal behavior
1334// :79:17: note: when computing vector element at index '1'
1335// :79:17: error: use of undefined value here causes illegal behavior1324// :79:17: error: use of undefined value here causes illegal behavior
1336// :79:17: note: when computing vector element at index '1'
1337// :79:17: error: use of undefined value here causes illegal behavior1325// :79:17: error: use of undefined value here causes illegal behavior
1338// :79:17: note: when computing vector element at index '0'
1339// :79:17: error: use of undefined value here causes illegal behavior1326// :79:17: error: use of undefined value here causes illegal behavior
1340// :79:17: note: when computing vector element at index '0'
1341// :79:17: error: use of undefined value here causes illegal behavior1327// :79:17: error: use of undefined value here causes illegal behavior
1342// :79:17: note: when computing vector element at index '0'
1343// :79:17: error: use of undefined value here causes illegal behavior1328// :79:17: error: use of undefined value here causes illegal behavior
1344// :79:17: note: when computing vector element at index '0'
1345// :79:17: error: use of undefined value here causes illegal behavior1329// :79:17: error: use of undefined value here causes illegal behavior
1346// :79:17: error: use of undefined value here causes illegal behavior1330// :79:17: error: use of undefined value here causes illegal behavior
1347// :79:17: error: use of undefined value here causes illegal behavior1331// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1349,13 +1333,11 @@ const std = @import("std");...@@ -1349,13 +1333,11 @@ const std = @import("std");
1349// :79:17: error: use of undefined value here causes illegal behavior1333// :79:17: error: use of undefined value here causes illegal behavior
1350// :79:17: error: use of undefined value here causes illegal behavior1334// :79:17: error: use of undefined value here causes illegal behavior
1351// :79:17: error: use of undefined value here causes illegal behavior1335// :79:17: error: use of undefined value here causes illegal behavior
1352// :79:17: note: when computing vector element at index '1'
1353// :79:17: error: use of undefined value here causes illegal behavior1336// :79:17: error: use of undefined value here causes illegal behavior
1354// :79:17: note: when computing vector element at index '1'
1355// :79:17: error: use of undefined value here causes illegal behavior1337// :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'
1357// :79:17: error: use of undefined value here causes illegal behavior1339// :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'
1359// :79:17: error: use of undefined value here causes illegal behavior1341// :79:17: error: use of undefined value here causes illegal behavior
1360// :79:17: note: when computing vector element at index '0'1342// :79:17: note: when computing vector element at index '0'
1361// :79:17: error: use of undefined value here causes illegal behavior1343// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1365,19 +1347,25 @@ const std = @import("std");...@@ -1365,19 +1347,25 @@ const std = @import("std");
1365// :79:17: error: use of undefined value here causes illegal behavior1347// :79:17: error: use of undefined value here causes illegal behavior
1366// :79:17: note: when computing vector element at index '0'1348// :79:17: note: when computing vector element at index '0'
1367// :79:17: error: use of undefined value here causes illegal behavior1349// :79:17: error: use of undefined value here causes illegal behavior
1350// :79:17: note: when computing vector element at index '0'
1368// :79:17: error: use of undefined value here causes illegal behavior1351// :79:17: error: use of undefined value here causes illegal behavior
1352// :79:17: note: when computing vector element at index '0'
1369// :79:17: error: use of undefined value here causes illegal behavior1353// :79:17: error: use of undefined value here causes illegal behavior
1354// :79:17: note: when computing vector element at index '0'
1370// :79:17: error: use of undefined value here causes illegal behavior1355// :79:17: error: use of undefined value here causes illegal behavior
1356// :79:17: note: when computing vector element at index '0'
1371// :79:17: error: use of undefined value here causes illegal behavior1357// :79:17: error: use of undefined value here causes illegal behavior
1358// :79:17: note: when computing vector element at index '0'
1372// :79:17: error: use of undefined value here causes illegal behavior1359// :79:17: error: use of undefined value here causes illegal behavior
1360// :79:17: note: when computing vector element at index '0'
1373// :79:17: error: use of undefined value here causes illegal behavior1361// :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'
1375// :79:17: error: use of undefined value here causes illegal behavior1363// :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'
1377// :79:17: error: use of undefined value here causes illegal behavior1365// :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'
1379// :79:17: error: use of undefined value here causes illegal behavior1367// :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'
1381// :79:17: error: use of undefined value here causes illegal behavior1369// :79:17: error: use of undefined value here causes illegal behavior
1382// :79:17: note: when computing vector element at index '0'1370// :79:17: note: when computing vector element at index '0'
1383// :79:17: error: use of undefined value here causes illegal behavior1371// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1387,11 +1375,17 @@ const std = @import("std");...@@ -1387,11 +1375,17 @@ const std = @import("std");
1387// :79:17: error: use of undefined value here causes illegal behavior1375// :79:17: error: use of undefined value here causes illegal behavior
1388// :79:17: note: when computing vector element at index '0'1376// :79:17: note: when computing vector element at index '0'
1389// :79:17: error: use of undefined value here causes illegal behavior1377// :79:17: error: use of undefined value here causes illegal behavior
1378// :79:17: note: when computing vector element at index '0'
1390// :79:17: error: use of undefined value here causes illegal behavior1379// :79:17: error: use of undefined value here causes illegal behavior
1380// :79:17: note: when computing vector element at index '0'
1391// :79:17: error: use of undefined value here causes illegal behavior1381// :79:17: error: use of undefined value here causes illegal behavior
1382// :79:17: note: when computing vector element at index '0'
1392// :79:17: error: use of undefined value here causes illegal behavior1383// :79:17: error: use of undefined value here causes illegal behavior
1384// :79:17: note: when computing vector element at index '0'
1393// :79:17: error: use of undefined value here causes illegal behavior1385// :79:17: error: use of undefined value here causes illegal behavior
1386// :79:17: note: when computing vector element at index '1'
1394// :79:17: error: use of undefined value here causes illegal behavior1387// :79:17: error: use of undefined value here causes illegal behavior
1388// :79:17: note: when computing vector element at index '1'
1395// :79:17: error: use of undefined value here causes illegal behavior1389// :79:17: error: use of undefined value here causes illegal behavior
1396// :79:17: note: when computing vector element at index '1'1390// :79:17: note: when computing vector element at index '1'
1397// :79:17: error: use of undefined value here causes illegal behavior1391// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1401,19 +1395,25 @@ const std = @import("std");...@@ -1401,19 +1395,25 @@ const std = @import("std");
1401// :79:17: error: use of undefined value here causes illegal behavior1395// :79:17: error: use of undefined value here causes illegal behavior
1402// :79:17: note: when computing vector element at index '1'1396// :79:17: note: when computing vector element at index '1'
1403// :79:17: error: use of undefined value here causes illegal behavior1397// :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'
1405// :79:17: error: use of undefined value here causes illegal behavior1399// :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'
1407// :79:17: error: use of undefined value here causes illegal behavior1401// :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'
1409// :79:17: error: use of undefined value here causes illegal behavior1403// :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'
1411// :79:17: error: use of undefined value here causes illegal behavior1405// :79:17: error: use of undefined value here causes illegal behavior
1406// :79:17: note: when computing vector element at index '1'
1412// :79:17: error: use of undefined value here causes illegal behavior1407// :79:17: error: use of undefined value here causes illegal behavior
1408// :79:17: note: when computing vector element at index '1'
1413// :79:17: error: use of undefined value here causes illegal behavior1409// :79:17: error: use of undefined value here causes illegal behavior
1410// :79:17: note: when computing vector element at index '1'
1414// :79:17: error: use of undefined value here causes illegal behavior1411// :79:17: error: use of undefined value here causes illegal behavior
1412// :79:17: note: when computing vector element at index '1'
1415// :79:17: error: use of undefined value here causes illegal behavior1413// :79:17: error: use of undefined value here causes illegal behavior
1414// :79:17: note: when computing vector element at index '1'
1416// :79:17: error: use of undefined value here causes illegal behavior1415// :79:17: error: use of undefined value here causes illegal behavior
1416// :79:17: note: when computing vector element at index '1'
1417// :79:17: error: use of undefined value here causes illegal behavior1417// :79:17: error: use of undefined value here causes illegal behavior
1418// :79:17: note: when computing vector element at index '1'1418// :79:17: note: when computing vector element at index '1'
1419// :79:17: error: use of undefined value here causes illegal behavior1419// :79:17: error: use of undefined value here causes illegal behavior
...@@ -1423,13 +1423,13 @@ const std = @import("std");...@@ -1423,13 +1423,13 @@ const std = @import("std");
1423// :79:17: error: use of undefined value here causes illegal behavior1423// :79:17: error: use of undefined value here causes illegal behavior
1424// :79:17: note: when computing vector element at index '1'1424// :79:17: note: when computing vector element at index '1'
1425// :79:17: error: use of undefined value here causes illegal behavior1425// :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'
1427// :79:17: error: use of undefined value here causes illegal behavior1427// :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'
1429// :79:17: error: use of undefined value here causes illegal behavior1429// :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'
1431// :79:17: error: use of undefined value here causes illegal behavior1431// :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'
1433// :82:27: error: use of undefined value here causes illegal behavior1433// :82:27: error: use of undefined value here causes illegal behavior
1434// :82:27: error: use of undefined value here causes illegal behavior1434// :82:27: error: use of undefined value here causes illegal behavior
1435// :82:27: error: use of undefined value here causes illegal behavior1435// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1437,21 +1437,13 @@ const std = @import("std");...@@ -1437,21 +1437,13 @@ const std = @import("std");
1437// :82:27: error: use of undefined value here causes illegal behavior1437// :82:27: error: use of undefined value here causes illegal behavior
1438// :82:27: error: use of undefined value here causes illegal behavior1438// :82:27: error: use of undefined value here causes illegal behavior
1439// :82:27: error: use of undefined value here causes illegal behavior1439// :82:27: error: use of undefined value here causes illegal behavior
1440// :82:27: note: when computing vector element at index '1'
1441// :82:27: error: use of undefined value here causes illegal behavior1440// :82:27: error: use of undefined value here causes illegal behavior
1442// :82:27: note: when computing vector element at index '1'
1443// :82:27: error: use of undefined value here causes illegal behavior1441// :82:27: error: use of undefined value here causes illegal behavior
1444// :82:27: note: when computing vector element at index '1'
1445// :82:27: error: use of undefined value here causes illegal behavior1442// :82:27: error: use of undefined value here causes illegal behavior
1446// :82:27: note: when computing vector element at index '1'
1447// :82:27: error: use of undefined value here causes illegal behavior1443// :82:27: error: use of undefined value here causes illegal behavior
1448// :82:27: note: when computing vector element at index '0'
1449// :82:27: error: use of undefined value here causes illegal behavior1444// :82:27: error: use of undefined value here causes illegal behavior
1450// :82:27: note: when computing vector element at index '0'
1451// :82:27: error: use of undefined value here causes illegal behavior1445// :82:27: error: use of undefined value here causes illegal behavior
1452// :82:27: note: when computing vector element at index '0'
1453// :82:27: error: use of undefined value here causes illegal behavior1446// :82:27: error: use of undefined value here causes illegal behavior
1454// :82:27: note: when computing vector element at index '0'
1455// :82:27: error: use of undefined value here causes illegal behavior1447// :82:27: error: use of undefined value here causes illegal behavior
1456// :82:27: error: use of undefined value here causes illegal behavior1448// :82:27: error: use of undefined value here causes illegal behavior
1457// :82:27: error: use of undefined value here causes illegal behavior1449// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1459,21 +1451,13 @@ const std = @import("std");...@@ -1459,21 +1451,13 @@ const std = @import("std");
1459// :82:27: error: use of undefined value here causes illegal behavior1451// :82:27: error: use of undefined value here causes illegal behavior
1460// :82:27: error: use of undefined value here causes illegal behavior1452// :82:27: error: use of undefined value here causes illegal behavior
1461// :82:27: error: use of undefined value here causes illegal behavior1453// :82:27: error: use of undefined value here causes illegal behavior
1462// :82:27: note: when computing vector element at index '1'
1463// :82:27: error: use of undefined value here causes illegal behavior1454// :82:27: error: use of undefined value here causes illegal behavior
1464// :82:27: note: when computing vector element at index '1'
1465// :82:27: error: use of undefined value here causes illegal behavior1455// :82:27: error: use of undefined value here causes illegal behavior
1466// :82:27: note: when computing vector element at index '1'
1467// :82:27: error: use of undefined value here causes illegal behavior1456// :82:27: error: use of undefined value here causes illegal behavior
1468// :82:27: note: when computing vector element at index '1'
1469// :82:27: error: use of undefined value here causes illegal behavior1457// :82:27: error: use of undefined value here causes illegal behavior
1470// :82:27: note: when computing vector element at index '0'
1471// :82:27: error: use of undefined value here causes illegal behavior1458// :82:27: error: use of undefined value here causes illegal behavior
1472// :82:27: note: when computing vector element at index '0'
1473// :82:27: error: use of undefined value here causes illegal behavior1459// :82:27: error: use of undefined value here causes illegal behavior
1474// :82:27: note: when computing vector element at index '0'
1475// :82:27: error: use of undefined value here causes illegal behavior1460// :82:27: error: use of undefined value here causes illegal behavior
1476// :82:27: note: when computing vector element at index '0'
1477// :82:27: error: use of undefined value here causes illegal behavior1461// :82:27: error: use of undefined value here causes illegal behavior
1478// :82:27: error: use of undefined value here causes illegal behavior1462// :82:27: error: use of undefined value here causes illegal behavior
1479// :82:27: error: use of undefined value here causes illegal behavior1463// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1481,13 +1465,11 @@ const std = @import("std");...@@ -1481,13 +1465,11 @@ const std = @import("std");
1481// :82:27: error: use of undefined value here causes illegal behavior1465// :82:27: error: use of undefined value here causes illegal behavior
1482// :82:27: error: use of undefined value here causes illegal behavior1466// :82:27: error: use of undefined value here causes illegal behavior
1483// :82:27: error: use of undefined value here causes illegal behavior1467// :82:27: error: use of undefined value here causes illegal behavior
1484// :82:27: note: when computing vector element at index '1'
1485// :82:27: error: use of undefined value here causes illegal behavior1468// :82:27: error: use of undefined value here causes illegal behavior
1486// :82:27: note: when computing vector element at index '1'
1487// :82:27: error: use of undefined value here causes illegal behavior1469// :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'
1489// :82:27: error: use of undefined value here causes illegal behavior1471// :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'
1491// :82:27: error: use of undefined value here causes illegal behavior1473// :82:27: error: use of undefined value here causes illegal behavior
1492// :82:27: note: when computing vector element at index '0'1474// :82:27: note: when computing vector element at index '0'
1493// :82:27: error: use of undefined value here causes illegal behavior1475// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1497,19 +1479,25 @@ const std = @import("std");...@@ -1497,19 +1479,25 @@ const std = @import("std");
1497// :82:27: error: use of undefined value here causes illegal behavior1479// :82:27: error: use of undefined value here causes illegal behavior
1498// :82:27: note: when computing vector element at index '0'1480// :82:27: note: when computing vector element at index '0'
1499// :82:27: error: use of undefined value here causes illegal behavior1481// :82:27: error: use of undefined value here causes illegal behavior
1482// :82:27: note: when computing vector element at index '0'
1500// :82:27: error: use of undefined value here causes illegal behavior1483// :82:27: error: use of undefined value here causes illegal behavior
1484// :82:27: note: when computing vector element at index '0'
1501// :82:27: error: use of undefined value here causes illegal behavior1485// :82:27: error: use of undefined value here causes illegal behavior
1486// :82:27: note: when computing vector element at index '0'
1502// :82:27: error: use of undefined value here causes illegal behavior1487// :82:27: error: use of undefined value here causes illegal behavior
1488// :82:27: note: when computing vector element at index '0'
1503// :82:27: error: use of undefined value here causes illegal behavior1489// :82:27: error: use of undefined value here causes illegal behavior
1490// :82:27: note: when computing vector element at index '0'
1504// :82:27: error: use of undefined value here causes illegal behavior1491// :82:27: error: use of undefined value here causes illegal behavior
1492// :82:27: note: when computing vector element at index '0'
1505// :82:27: error: use of undefined value here causes illegal behavior1493// :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'
1507// :82:27: error: use of undefined value here causes illegal behavior1495// :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'
1509// :82:27: error: use of undefined value here causes illegal behavior1497// :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'
1511// :82:27: error: use of undefined value here causes illegal behavior1499// :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'
1513// :82:27: error: use of undefined value here causes illegal behavior1501// :82:27: error: use of undefined value here causes illegal behavior
1514// :82:27: note: when computing vector element at index '0'1502// :82:27: note: when computing vector element at index '0'
1515// :82:27: error: use of undefined value here causes illegal behavior1503// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1519,11 +1507,17 @@ const std = @import("std");...@@ -1519,11 +1507,17 @@ const std = @import("std");
1519// :82:27: error: use of undefined value here causes illegal behavior1507// :82:27: error: use of undefined value here causes illegal behavior
1520// :82:27: note: when computing vector element at index '0'1508// :82:27: note: when computing vector element at index '0'
1521// :82:27: error: use of undefined value here causes illegal behavior1509// :82:27: error: use of undefined value here causes illegal behavior
1510// :82:27: note: when computing vector element at index '0'
1522// :82:27: error: use of undefined value here causes illegal behavior1511// :82:27: error: use of undefined value here causes illegal behavior
1512// :82:27: note: when computing vector element at index '0'
1523// :82:27: error: use of undefined value here causes illegal behavior1513// :82:27: error: use of undefined value here causes illegal behavior
1514// :82:27: note: when computing vector element at index '0'
1524// :82:27: error: use of undefined value here causes illegal behavior1515// :82:27: error: use of undefined value here causes illegal behavior
1516// :82:27: note: when computing vector element at index '0'
1525// :82:27: error: use of undefined value here causes illegal behavior1517// :82:27: error: use of undefined value here causes illegal behavior
1518// :82:27: note: when computing vector element at index '1'
1526// :82:27: error: use of undefined value here causes illegal behavior1519// :82:27: error: use of undefined value here causes illegal behavior
1520// :82:27: note: when computing vector element at index '1'
1527// :82:27: error: use of undefined value here causes illegal behavior1521// :82:27: error: use of undefined value here causes illegal behavior
1528// :82:27: note: when computing vector element at index '1'1522// :82:27: note: when computing vector element at index '1'
1529// :82:27: error: use of undefined value here causes illegal behavior1523// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1533,19 +1527,25 @@ const std = @import("std");...@@ -1533,19 +1527,25 @@ const std = @import("std");
1533// :82:27: error: use of undefined value here causes illegal behavior1527// :82:27: error: use of undefined value here causes illegal behavior
1534// :82:27: note: when computing vector element at index '1'1528// :82:27: note: when computing vector element at index '1'
1535// :82:27: error: use of undefined value here causes illegal behavior1529// :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'
1537// :82:27: error: use of undefined value here causes illegal behavior1531// :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'
1539// :82:27: error: use of undefined value here causes illegal behavior1533// :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'
1541// :82:27: error: use of undefined value here causes illegal behavior1535// :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'
1543// :82:27: error: use of undefined value here causes illegal behavior1537// :82:27: error: use of undefined value here causes illegal behavior
1538// :82:27: note: when computing vector element at index '1'
1544// :82:27: error: use of undefined value here causes illegal behavior1539// :82:27: error: use of undefined value here causes illegal behavior
1540// :82:27: note: when computing vector element at index '1'
1545// :82:27: error: use of undefined value here causes illegal behavior1541// :82:27: error: use of undefined value here causes illegal behavior
1542// :82:27: note: when computing vector element at index '1'
1546// :82:27: error: use of undefined value here causes illegal behavior1543// :82:27: error: use of undefined value here causes illegal behavior
1544// :82:27: note: when computing vector element at index '1'
1547// :82:27: error: use of undefined value here causes illegal behavior1545// :82:27: error: use of undefined value here causes illegal behavior
1546// :82:27: note: when computing vector element at index '1'
1548// :82:27: error: use of undefined value here causes illegal behavior1547// :82:27: error: use of undefined value here causes illegal behavior
1548// :82:27: note: when computing vector element at index '1'
1549// :82:27: error: use of undefined value here causes illegal behavior1549// :82:27: error: use of undefined value here causes illegal behavior
1550// :82:27: note: when computing vector element at index '1'1550// :82:27: note: when computing vector element at index '1'
1551// :82:27: error: use of undefined value here causes illegal behavior1551// :82:27: error: use of undefined value here causes illegal behavior
...@@ -1555,44 +1555,37 @@ const std = @import("std");...@@ -1555,44 +1555,37 @@ const std = @import("std");
1555// :82:27: error: use of undefined value here causes illegal behavior1555// :82:27: error: use of undefined value here causes illegal behavior
1556// :82:27: note: when computing vector element at index '1'1556// :82:27: note: when computing vector element at index '1'
1557// :82:27: error: use of undefined value here causes illegal behavior1557// :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'
1559// :82:27: error: use of undefined value here causes illegal behavior1559// :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'
1561// :82:27: error: use of undefined value here causes illegal behavior1561// :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'
1563// :82:27: error: use of undefined value here causes illegal behavior1563// :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'
1565// :87:17: error: use of undefined value here causes illegal behavior1565// :87:17: error: use of undefined value here causes illegal behavior
1566// :87:17: error: use of undefined value here causes illegal behavior1566// :87:17: error: use of undefined value here causes illegal behavior
1567// :87:17: note: when computing vector element at index '0'
1568// :87:17: error: use of undefined value here causes illegal behavior1567// :87:17: error: use of undefined value here causes illegal behavior
1569// :87:17: note: when computing vector element at index '0'
1570// :87:17: error: use of undefined value here causes illegal behavior1568// :87:17: error: use of undefined value here causes illegal behavior
1571// :87:17: note: when computing vector element at index '0'
1572// :87:17: error: use of undefined value here causes illegal behavior1569// :87:17: error: use of undefined value here causes illegal behavior
1573// :87:17: note: when computing vector element at index '1'
1574// :87:17: error: use of undefined value here causes illegal behavior1570// :87:17: error: use of undefined value here causes illegal behavior
1575// :87:17: note: when computing vector element at index '0'
1576// :87:17: error: use of undefined value here causes illegal behavior1571// :87:17: error: use of undefined value here causes illegal behavior
1577// :87:17: note: when computing vector element at index '0'1572// :87:17: note: when computing vector element at index '0'
1578// :87:17: error: use of undefined value here causes illegal behavior1573// :87:17: error: use of undefined value here causes illegal behavior
1579// :87:17: note: when computing vector element at index '0'1574// :87:17: note: when computing vector element at index '0'
1580// :87:17: error: use of undefined value here causes illegal behavior1575// :87:17: error: use of undefined value here causes illegal behavior
1581// :87:17: error: use of undefined value here causes illegal behavior
1582// :87:17: note: when computing vector element at index '0'1576// :87:17: note: when computing vector element at index '0'
1583// :87:17: error: use of undefined value here causes illegal behavior1577// :87:17: error: use of undefined value here causes illegal behavior
1584// :87:17: note: when computing vector element at index '0'1578// :87:17: note: when computing vector element at index '0'
1585// :87:17: error: use of undefined value here causes illegal behavior1579// :87:17: error: use of undefined value here causes illegal behavior
1586// :87:17: note: when computing vector element at index '0'1580// :87:17: note: when computing vector element at index '0'
1587// :87:17: error: use of undefined value here causes illegal behavior1581// :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
1590// :87:17: note: when computing vector element at index '0'1582// :87:17: note: when computing vector element at index '0'
1591// :87:17: error: use of undefined value here causes illegal behavior1583// :87:17: error: use of undefined value here causes illegal behavior
1592// :87:17: note: when computing vector element at index '0'1584// :87:17: note: when computing vector element at index '0'
1593// :87:17: error: use of undefined value here causes illegal behavior1585// :87:17: error: use of undefined value here causes illegal behavior
1594// :87:17: note: when computing vector element at index '0'1586// :87:17: note: when computing vector element at index '0'
1595// :87:17: error: use of undefined value here causes illegal behavior1587// :87:17: error: use of undefined value here causes illegal behavior
1588// :87:17: note: when computing vector element at index '0'
1596// :87:17: error: use of undefined value here causes illegal behavior1589// :87:17: error: use of undefined value here causes illegal behavior
1597// :87:17: note: when computing vector element at index '0'1590// :87:17: note: when computing vector element at index '0'
1598// :87:17: error: use of undefined value here causes illegal behavior1591// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1600,7 +1593,7 @@ const std = @import("std");...@@ -1600,7 +1593,7 @@ const std = @import("std");
1600// :87:17: error: use of undefined value here causes illegal behavior1593// :87:17: error: use of undefined value here causes illegal behavior
1601// :87:17: note: when computing vector element at index '0'1594// :87:17: note: when computing vector element at index '0'
1602// :87:17: error: use of undefined value here causes illegal behavior1595// :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'
1604// :87:17: error: use of undefined value here causes illegal behavior1597// :87:17: error: use of undefined value here causes illegal behavior
1605// :87:17: note: when computing vector element at index '0'1598// :87:17: note: when computing vector element at index '0'
1606// :87:17: error: use of undefined value here causes illegal behavior1599// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1608,6 +1601,7 @@ const std = @import("std");...@@ -1608,6 +1601,7 @@ const std = @import("std");
1608// :87:17: error: use of undefined value here causes illegal behavior1601// :87:17: error: use of undefined value here causes illegal behavior
1609// :87:17: note: when computing vector element at index '0'1602// :87:17: note: when computing vector element at index '0'
1610// :87:17: error: use of undefined value here causes illegal behavior1603// :87:17: error: use of undefined value here causes illegal behavior
1604// :87:17: note: when computing vector element at index '0'
1611// :87:17: error: use of undefined value here causes illegal behavior1605// :87:17: error: use of undefined value here causes illegal behavior
1612// :87:17: note: when computing vector element at index '0'1606// :87:17: note: when computing vector element at index '0'
1613// :87:17: error: use of undefined value here causes illegal behavior1607// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1615,7 +1609,7 @@ const std = @import("std");...@@ -1615,7 +1609,7 @@ const std = @import("std");
1615// :87:17: error: use of undefined value here causes illegal behavior1609// :87:17: error: use of undefined value here causes illegal behavior
1616// :87:17: note: when computing vector element at index '0'1610// :87:17: note: when computing vector element at index '0'
1617// :87:17: error: use of undefined value here causes illegal behavior1611// :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'
1619// :87:17: error: use of undefined value here causes illegal behavior1613// :87:17: error: use of undefined value here causes illegal behavior
1620// :87:17: note: when computing vector element at index '0'1614// :87:17: note: when computing vector element at index '0'
1621// :87:17: error: use of undefined value here causes illegal behavior1615// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1623,6 +1617,7 @@ const std = @import("std");...@@ -1623,6 +1617,7 @@ const std = @import("std");
1623// :87:17: error: use of undefined value here causes illegal behavior1617// :87:17: error: use of undefined value here causes illegal behavior
1624// :87:17: note: when computing vector element at index '0'1618// :87:17: note: when computing vector element at index '0'
1625// :87:17: error: use of undefined value here causes illegal behavior1619// :87:17: error: use of undefined value here causes illegal behavior
1620// :87:17: note: when computing vector element at index '0'
1626// :87:17: error: use of undefined value here causes illegal behavior1621// :87:17: error: use of undefined value here causes illegal behavior
1627// :87:17: note: when computing vector element at index '0'1622// :87:17: note: when computing vector element at index '0'
1628// :87:17: error: use of undefined value here causes illegal behavior1623// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1630,7 +1625,7 @@ const std = @import("std");...@@ -1630,7 +1625,7 @@ const std = @import("std");
1630// :87:17: error: use of undefined value here causes illegal behavior1625// :87:17: error: use of undefined value here causes illegal behavior
1631// :87:17: note: when computing vector element at index '0'1626// :87:17: note: when computing vector element at index '0'
1632// :87:17: error: use of undefined value here causes illegal behavior1627// :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'
1634// :87:17: error: use of undefined value here causes illegal behavior1629// :87:17: error: use of undefined value here causes illegal behavior
1635// :87:17: note: when computing vector element at index '0'1630// :87:17: note: when computing vector element at index '0'
1636// :87:17: error: use of undefined value here causes illegal behavior1631// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1638,6 +1633,7 @@ const std = @import("std");...@@ -1638,6 +1633,7 @@ const std = @import("std");
1638// :87:17: error: use of undefined value here causes illegal behavior1633// :87:17: error: use of undefined value here causes illegal behavior
1639// :87:17: note: when computing vector element at index '0'1634// :87:17: note: when computing vector element at index '0'
1640// :87:17: error: use of undefined value here causes illegal behavior1635// :87:17: error: use of undefined value here causes illegal behavior
1636// :87:17: note: when computing vector element at index '0'
1641// :87:17: error: use of undefined value here causes illegal behavior1637// :87:17: error: use of undefined value here causes illegal behavior
1642// :87:17: note: when computing vector element at index '0'1638// :87:17: note: when computing vector element at index '0'
1643// :87:17: error: use of undefined value here causes illegal behavior1639// :87:17: error: use of undefined value here causes illegal behavior
...@@ -1647,108 +1643,105 @@ const std = @import("std");...@@ -1647,108 +1643,105 @@ const std = @import("std");
1647// :87:17: error: use of undefined value here causes illegal behavior1643// :87:17: error: use of undefined value here causes illegal behavior
1648// :87:17: note: when computing vector element at index '1'1644// :87:17: note: when computing vector element at index '1'
1649// :87:17: error: use of undefined value here causes illegal behavior1645// :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'
1651// :87:17: error: use of undefined value here causes illegal behavior1647// :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'
1653// :87:17: error: use of undefined value here causes illegal behavior1649// :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'
1655// :87:22: error: use of undefined value here causes illegal behavior1655// :87:22: error: use of undefined value here causes illegal behavior
1656// :87:22: error: use of undefined value here causes illegal behavior1656// :87:22: error: use of undefined value here causes illegal behavior
1657// :87:22: note: when computing vector element at index '0'
1658// :87:22: error: use of undefined value here causes illegal behavior1657// :87:22: error: use of undefined value here causes illegal behavior
1659// :87:22: note: when computing vector element at index '0'
1660// :87:22: error: use of undefined value here causes illegal behavior1658// :87:22: error: use of undefined value here causes illegal behavior
1661// :87:22: note: when computing vector element at index '1'
1662// :87:22: error: use of undefined value here causes illegal behavior1659// :87:22: error: use of undefined value here causes illegal behavior
1663// :87:22: note: when computing vector element at index '0'
1664// :87:22: error: use of undefined value here causes illegal behavior1660// :87:22: error: use of undefined value here causes illegal behavior
1665// :87:22: note: when computing vector element at index '0'
1666// :87:22: error: use of undefined value here causes illegal behavior1661// :87:22: error: use of undefined value here causes illegal behavior
1662// :87:22: note: when computing vector element at index '0'
1667// :87:22: error: use of undefined value here causes illegal behavior1663// :87:22: error: use of undefined value here causes illegal behavior
1668// :87:22: note: when computing vector element at index '0'1664// :87:22: note: when computing vector element at index '0'
1669// :87:22: error: use of undefined value here causes illegal behavior1665// :87:22: error: use of undefined value here causes illegal behavior
1670// :87:22: note: when computing vector element at index '0'1666// :87:22: note: when computing vector element at index '0'
1671// :87:22: error: use of undefined value here causes illegal behavior1667// :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'
1673// :87:22: error: use of undefined value here causes illegal behavior1669// :87:22: error: use of undefined value here causes illegal behavior
1674// :87:22: note: when computing vector element at index '0'1670// :87:22: note: when computing vector element at index '0'
1675// :87:22: error: use of undefined value here causes illegal behavior1671// :87:22: error: use of undefined value here causes illegal behavior
1676// :87:22: note: when computing vector element at index '0'1672// :87:22: note: when computing vector element at index '0'
1677// :87:22: error: use of undefined value here causes illegal behavior1673// :87:22: error: use of undefined value here causes illegal behavior
1674// :87:22: note: when computing vector element at index '0'
1678// :87:22: error: use of undefined value here causes illegal behavior1675// :87:22: error: use of undefined value here causes illegal behavior
1679// :87:22: note: when computing vector element at index '0'1676// :87:22: note: when computing vector element at index '0'
1680// :87:22: error: use of undefined value here causes illegal behavior1677// :87:22: error: use of undefined value here causes illegal behavior
1681// :87:22: note: when computing vector element at index '0'1678// :87:22: note: when computing vector element at index '0'
1682// :87:22: error: use of undefined value here causes illegal behavior1679// :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'
1684// :87:22: error: use of undefined value here causes illegal behavior1681// :87:22: error: use of undefined value here causes illegal behavior
1685// :87:22: note: when computing vector element at index '0'1682// :87:22: note: when computing vector element at index '0'
1686// :87:22: error: use of undefined value here causes illegal behavior1683// :87:22: error: use of undefined value here causes illegal behavior
1687// :87:22: note: when computing vector element at index '0'1684// :87:22: note: when computing vector element at index '0'
1688// :87:22: error: use of undefined value here causes illegal behavior1685// :87:22: error: use of undefined value here causes illegal behavior
1686// :87:22: note: when computing vector element at index '0'
1689// :87:22: error: use of undefined value here causes illegal behavior1687// :87:22: error: use of undefined value here causes illegal behavior
1690// :87:22: note: when computing vector element at index '0'1688// :87:22: note: when computing vector element at index '0'
1691// :87:22: error: use of undefined value here causes illegal behavior1689// :87:22: error: use of undefined value here causes illegal behavior
1692// :87:22: note: when computing vector element at index '0'1690// :87:22: note: when computing vector element at index '0'
1693// :87:22: error: use of undefined value here causes illegal behavior1691// :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'
1695// :87:22: error: use of undefined value here causes illegal behavior1693// :87:22: error: use of undefined value here causes illegal behavior
1696// :87:22: note: when computing vector element at index '0'1694// :87:22: note: when computing vector element at index '0'
1697// :87:22: error: use of undefined value here causes illegal behavior1695// :87:22: error: use of undefined value here causes illegal behavior
1698// :87:22: note: when computing vector element at index '0'1696// :87:22: note: when computing vector element at index '0'
1699// :87:22: error: use of undefined value here causes illegal behavior1697// :87:22: error: use of undefined value here causes illegal behavior
1698// :87:22: note: when computing vector element at index '0'
1700// :87:22: error: use of undefined value here causes illegal behavior1699// :87:22: error: use of undefined value here causes illegal behavior
1701// :87:22: note: when computing vector element at index '0'1700// :87:22: note: when computing vector element at index '0'
1702// :87:22: error: use of undefined value here causes illegal behavior1701// :87:22: error: use of undefined value here causes illegal behavior
1703// :87:22: note: when computing vector element at index '0'1702// :87:22: note: when computing vector element at index '0'
1704// :87:22: error: use of undefined value here causes illegal behavior1703// :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'
1706// :87:22: error: use of undefined value here causes illegal behavior1705// :87:22: error: use of undefined value here causes illegal behavior
1707// :87:22: note: when computing vector element at index '0'1706// :87:22: note: when computing vector element at index '0'
1708// :87:22: error: use of undefined value here causes illegal behavior1707// :87:22: error: use of undefined value here causes illegal behavior
1709// :87:22: note: when computing vector element at index '0'1708// :87:22: note: when computing vector element at index '0'
1710// :87:22: error: use of undefined value here causes illegal behavior1709// :87:22: error: use of undefined value here causes illegal behavior
1710// :87:22: note: when computing vector element at index '1'
1711// :87:22: error: use of undefined value here causes illegal behavior1711// :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'
1713// :87:22: error: use of undefined value here causes illegal behavior1713// :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'
1715// :87:22: error: use of undefined value here causes illegal behavior1715// :87:22: error: use of undefined value here causes illegal behavior
1716// :87:22: note: when computing vector element at index '1'1716// :87:22: note: when computing vector element at index '1'
1717// :87:22: error: use of undefined value here causes illegal behavior1717// :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'
1719// :87:22: error: use of undefined value here causes illegal behavior1719// :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'
1721// :90:27: error: use of undefined value here causes illegal behavior1721// :90:27: error: use of undefined value here causes illegal behavior
1722// :90:27: error: use of undefined value here causes illegal behavior1722// :90:27: error: use of undefined value here causes illegal behavior
1723// :90:27: note: when computing vector element at index '0'
1724// :90:27: error: use of undefined value here causes illegal behavior1723// :90:27: error: use of undefined value here causes illegal behavior
1725// :90:27: note: when computing vector element at index '0'
1726// :90:27: error: use of undefined value here causes illegal behavior1724// :90:27: error: use of undefined value here causes illegal behavior
1727// :90:27: note: when computing vector element at index '0'
1728// :90:27: error: use of undefined value here causes illegal behavior1725// :90:27: error: use of undefined value here causes illegal behavior
1729// :90:27: note: when computing vector element at index '1'
1730// :90:27: error: use of undefined value here causes illegal behavior1726// :90:27: error: use of undefined value here causes illegal behavior
1731// :90:27: note: when computing vector element at index '0'
1732// :90:27: error: use of undefined value here causes illegal behavior1727// :90:27: error: use of undefined value here causes illegal behavior
1733// :90:27: note: when computing vector element at index '0'1728// :90:27: note: when computing vector element at index '0'
1734// :90:27: error: use of undefined value here causes illegal behavior1729// :90:27: error: use of undefined value here causes illegal behavior
1735// :90:27: note: when computing vector element at index '0'1730// :90:27: note: when computing vector element at index '0'
1736// :90:27: error: use of undefined value here causes illegal behavior1731// :90:27: error: use of undefined value here causes illegal behavior
1737// :90:27: error: use of undefined value here causes illegal behavior
1738// :90:27: note: when computing vector element at index '0'1732// :90:27: note: when computing vector element at index '0'
1739// :90:27: error: use of undefined value here causes illegal behavior1733// :90:27: error: use of undefined value here causes illegal behavior
1740// :90:27: note: when computing vector element at index '0'1734// :90:27: note: when computing vector element at index '0'
1741// :90:27: error: use of undefined value here causes illegal behavior1735// :90:27: error: use of undefined value here causes illegal behavior
1742// :90:27: note: when computing vector element at index '0'1736// :90:27: note: when computing vector element at index '0'
1743// :90:27: error: use of undefined value here causes illegal behavior1737// :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
1746// :90:27: note: when computing vector element at index '0'1738// :90:27: note: when computing vector element at index '0'
1747// :90:27: error: use of undefined value here causes illegal behavior1739// :90:27: error: use of undefined value here causes illegal behavior
1748// :90:27: note: when computing vector element at index '0'1740// :90:27: note: when computing vector element at index '0'
1749// :90:27: error: use of undefined value here causes illegal behavior1741// :90:27: error: use of undefined value here causes illegal behavior
1750// :90:27: note: when computing vector element at index '0'1742// :90:27: note: when computing vector element at index '0'
1751// :90:27: error: use of undefined value here causes illegal behavior1743// :90:27: error: use of undefined value here causes illegal behavior
1744// :90:27: note: when computing vector element at index '0'
1752// :90:27: error: use of undefined value here causes illegal behavior1745// :90:27: error: use of undefined value here causes illegal behavior
1753// :90:27: note: when computing vector element at index '0'1746// :90:27: note: when computing vector element at index '0'
1754// :90:27: error: use of undefined value here causes illegal behavior1747// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1756,7 +1749,7 @@ const std = @import("std");...@@ -1756,7 +1749,7 @@ const std = @import("std");
1756// :90:27: error: use of undefined value here causes illegal behavior1749// :90:27: error: use of undefined value here causes illegal behavior
1757// :90:27: note: when computing vector element at index '0'1750// :90:27: note: when computing vector element at index '0'
1758// :90:27: error: use of undefined value here causes illegal behavior1751// :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'
1760// :90:27: error: use of undefined value here causes illegal behavior1753// :90:27: error: use of undefined value here causes illegal behavior
1761// :90:27: note: when computing vector element at index '0'1754// :90:27: note: when computing vector element at index '0'
1762// :90:27: error: use of undefined value here causes illegal behavior1755// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1764,6 +1757,7 @@ const std = @import("std");...@@ -1764,6 +1757,7 @@ const std = @import("std");
1764// :90:27: error: use of undefined value here causes illegal behavior1757// :90:27: error: use of undefined value here causes illegal behavior
1765// :90:27: note: when computing vector element at index '0'1758// :90:27: note: when computing vector element at index '0'
1766// :90:27: error: use of undefined value here causes illegal behavior1759// :90:27: error: use of undefined value here causes illegal behavior
1760// :90:27: note: when computing vector element at index '0'
1767// :90:27: error: use of undefined value here causes illegal behavior1761// :90:27: error: use of undefined value here causes illegal behavior
1768// :90:27: note: when computing vector element at index '0'1762// :90:27: note: when computing vector element at index '0'
1769// :90:27: error: use of undefined value here causes illegal behavior1763// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1771,7 +1765,7 @@ const std = @import("std");...@@ -1771,7 +1765,7 @@ const std = @import("std");
1771// :90:27: error: use of undefined value here causes illegal behavior1765// :90:27: error: use of undefined value here causes illegal behavior
1772// :90:27: note: when computing vector element at index '0'1766// :90:27: note: when computing vector element at index '0'
1773// :90:27: error: use of undefined value here causes illegal behavior1767// :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'
1775// :90:27: error: use of undefined value here causes illegal behavior1769// :90:27: error: use of undefined value here causes illegal behavior
1776// :90:27: note: when computing vector element at index '0'1770// :90:27: note: when computing vector element at index '0'
1777// :90:27: error: use of undefined value here causes illegal behavior1771// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1779,6 +1773,7 @@ const std = @import("std");...@@ -1779,6 +1773,7 @@ const std = @import("std");
1779// :90:27: error: use of undefined value here causes illegal behavior1773// :90:27: error: use of undefined value here causes illegal behavior
1780// :90:27: note: when computing vector element at index '0'1774// :90:27: note: when computing vector element at index '0'
1781// :90:27: error: use of undefined value here causes illegal behavior1775// :90:27: error: use of undefined value here causes illegal behavior
1776// :90:27: note: when computing vector element at index '0'
1782// :90:27: error: use of undefined value here causes illegal behavior1777// :90:27: error: use of undefined value here causes illegal behavior
1783// :90:27: note: when computing vector element at index '0'1778// :90:27: note: when computing vector element at index '0'
1784// :90:27: error: use of undefined value here causes illegal behavior1779// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1786,7 +1781,7 @@ const std = @import("std");...@@ -1786,7 +1781,7 @@ const std = @import("std");
1786// :90:27: error: use of undefined value here causes illegal behavior1781// :90:27: error: use of undefined value here causes illegal behavior
1787// :90:27: note: when computing vector element at index '0'1782// :90:27: note: when computing vector element at index '0'
1788// :90:27: error: use of undefined value here causes illegal behavior1783// :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'
1790// :90:27: error: use of undefined value here causes illegal behavior1785// :90:27: error: use of undefined value here causes illegal behavior
1791// :90:27: note: when computing vector element at index '0'1786// :90:27: note: when computing vector element at index '0'
1792// :90:27: error: use of undefined value here causes illegal behavior1787// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1794,6 +1789,7 @@ const std = @import("std");...@@ -1794,6 +1789,7 @@ const std = @import("std");
1794// :90:27: error: use of undefined value here causes illegal behavior1789// :90:27: error: use of undefined value here causes illegal behavior
1795// :90:27: note: when computing vector element at index '0'1790// :90:27: note: when computing vector element at index '0'
1796// :90:27: error: use of undefined value here causes illegal behavior1791// :90:27: error: use of undefined value here causes illegal behavior
1792// :90:27: note: when computing vector element at index '0'
1797// :90:27: error: use of undefined value here causes illegal behavior1793// :90:27: error: use of undefined value here causes illegal behavior
1798// :90:27: note: when computing vector element at index '0'1794// :90:27: note: when computing vector element at index '0'
1799// :90:27: error: use of undefined value here causes illegal behavior1795// :90:27: error: use of undefined value here causes illegal behavior
...@@ -1803,108 +1799,105 @@ const std = @import("std");...@@ -1803,108 +1799,105 @@ const std = @import("std");
1803// :90:27: error: use of undefined value here causes illegal behavior1799// :90:27: error: use of undefined value here causes illegal behavior
1804// :90:27: note: when computing vector element at index '1'1800// :90:27: note: when computing vector element at index '1'
1805// :90:27: error: use of undefined value here causes illegal behavior1801// :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'
1807// :90:27: error: use of undefined value here causes illegal behavior1803// :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'
1809// :90:27: error: use of undefined value here causes illegal behavior1805// :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'
1811// :90:30: error: use of undefined value here causes illegal behavior1811// :90:30: error: use of undefined value here causes illegal behavior
1812// :90:30: error: use of undefined value here causes illegal behavior1812// :90:30: error: use of undefined value here causes illegal behavior
1813// :90:30: note: when computing vector element at index '0'
1814// :90:30: error: use of undefined value here causes illegal behavior1813// :90:30: error: use of undefined value here causes illegal behavior
1815// :90:30: note: when computing vector element at index '0'
1816// :90:30: error: use of undefined value here causes illegal behavior1814// :90:30: error: use of undefined value here causes illegal behavior
1817// :90:30: note: when computing vector element at index '1'
1818// :90:30: error: use of undefined value here causes illegal behavior1815// :90:30: error: use of undefined value here causes illegal behavior
1819// :90:30: note: when computing vector element at index '0'
1820// :90:30: error: use of undefined value here causes illegal behavior1816// :90:30: error: use of undefined value here causes illegal behavior
1821// :90:30: note: when computing vector element at index '0'
1822// :90:30: error: use of undefined value here causes illegal behavior1817// :90:30: error: use of undefined value here causes illegal behavior
1818// :90:30: note: when computing vector element at index '0'
1823// :90:30: error: use of undefined value here causes illegal behavior1819// :90:30: error: use of undefined value here causes illegal behavior
1824// :90:30: note: when computing vector element at index '0'1820// :90:30: note: when computing vector element at index '0'
1825// :90:30: error: use of undefined value here causes illegal behavior1821// :90:30: error: use of undefined value here causes illegal behavior
1826// :90:30: note: when computing vector element at index '0'1822// :90:30: note: when computing vector element at index '0'
1827// :90:30: error: use of undefined value here causes illegal behavior1823// :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'
1829// :90:30: error: use of undefined value here causes illegal behavior1825// :90:30: error: use of undefined value here causes illegal behavior
1830// :90:30: note: when computing vector element at index '0'1826// :90:30: note: when computing vector element at index '0'
1831// :90:30: error: use of undefined value here causes illegal behavior1827// :90:30: error: use of undefined value here causes illegal behavior
1832// :90:30: note: when computing vector element at index '0'1828// :90:30: note: when computing vector element at index '0'
1833// :90:30: error: use of undefined value here causes illegal behavior1829// :90:30: error: use of undefined value here causes illegal behavior
1830// :90:30: note: when computing vector element at index '0'
1834// :90:30: error: use of undefined value here causes illegal behavior1831// :90:30: error: use of undefined value here causes illegal behavior
1835// :90:30: note: when computing vector element at index '0'1832// :90:30: note: when computing vector element at index '0'
1836// :90:30: error: use of undefined value here causes illegal behavior1833// :90:30: error: use of undefined value here causes illegal behavior
1837// :90:30: note: when computing vector element at index '0'1834// :90:30: note: when computing vector element at index '0'
1838// :90:30: error: use of undefined value here causes illegal behavior1835// :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'
1840// :90:30: error: use of undefined value here causes illegal behavior1837// :90:30: error: use of undefined value here causes illegal behavior
1841// :90:30: note: when computing vector element at index '0'1838// :90:30: note: when computing vector element at index '0'
1842// :90:30: error: use of undefined value here causes illegal behavior1839// :90:30: error: use of undefined value here causes illegal behavior
1843// :90:30: note: when computing vector element at index '0'1840// :90:30: note: when computing vector element at index '0'
1844// :90:30: error: use of undefined value here causes illegal behavior1841// :90:30: error: use of undefined value here causes illegal behavior
1842// :90:30: note: when computing vector element at index '0'
1845// :90:30: error: use of undefined value here causes illegal behavior1843// :90:30: error: use of undefined value here causes illegal behavior
1846// :90:30: note: when computing vector element at index '0'1844// :90:30: note: when computing vector element at index '0'
1847// :90:30: error: use of undefined value here causes illegal behavior1845// :90:30: error: use of undefined value here causes illegal behavior
1848// :90:30: note: when computing vector element at index '0'1846// :90:30: note: when computing vector element at index '0'
1849// :90:30: error: use of undefined value here causes illegal behavior1847// :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'
1851// :90:30: error: use of undefined value here causes illegal behavior1849// :90:30: error: use of undefined value here causes illegal behavior
1852// :90:30: note: when computing vector element at index '0'1850// :90:30: note: when computing vector element at index '0'
1853// :90:30: error: use of undefined value here causes illegal behavior1851// :90:30: error: use of undefined value here causes illegal behavior
1854// :90:30: note: when computing vector element at index '0'1852// :90:30: note: when computing vector element at index '0'
1855// :90:30: error: use of undefined value here causes illegal behavior1853// :90:30: error: use of undefined value here causes illegal behavior
1854// :90:30: note: when computing vector element at index '0'
1856// :90:30: error: use of undefined value here causes illegal behavior1855// :90:30: error: use of undefined value here causes illegal behavior
1857// :90:30: note: when computing vector element at index '0'1856// :90:30: note: when computing vector element at index '0'
1858// :90:30: error: use of undefined value here causes illegal behavior1857// :90:30: error: use of undefined value here causes illegal behavior
1859// :90:30: note: when computing vector element at index '0'1858// :90:30: note: when computing vector element at index '0'
1860// :90:30: error: use of undefined value here causes illegal behavior1859// :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'
1862// :90:30: error: use of undefined value here causes illegal behavior1861// :90:30: error: use of undefined value here causes illegal behavior
1863// :90:30: note: when computing vector element at index '0'1862// :90:30: note: when computing vector element at index '0'
1864// :90:30: error: use of undefined value here causes illegal behavior1863// :90:30: error: use of undefined value here causes illegal behavior
1865// :90:30: note: when computing vector element at index '0'1864// :90:30: note: when computing vector element at index '0'
1866// :90:30: error: use of undefined value here causes illegal behavior1865// :90:30: error: use of undefined value here causes illegal behavior
1866// :90:30: note: when computing vector element at index '1'
1867// :90:30: error: use of undefined value here causes illegal behavior1867// :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'
1869// :90:30: error: use of undefined value here causes illegal behavior1869// :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'
1871// :90:30: error: use of undefined value here causes illegal behavior1871// :90:30: error: use of undefined value here causes illegal behavior
1872// :90:30: note: when computing vector element at index '1'1872// :90:30: note: when computing vector element at index '1'
1873// :90:30: error: use of undefined value here causes illegal behavior1873// :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'
1875// :90:30: error: use of undefined value here causes illegal behavior1875// :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'
1877// :93:34: error: use of undefined value here causes illegal behavior1877// :93:34: error: use of undefined value here causes illegal behavior
1878// :93:34: error: use of undefined value here causes illegal behavior1878// :93:34: error: use of undefined value here causes illegal behavior
1879// :93:34: note: when computing vector element at index '0'
1880// :93:34: error: use of undefined value here causes illegal behavior1879// :93:34: error: use of undefined value here causes illegal behavior
1881// :93:34: note: when computing vector element at index '0'
1882// :93:34: error: use of undefined value here causes illegal behavior1880// :93:34: error: use of undefined value here causes illegal behavior
1883// :93:34: note: when computing vector element at index '0'
1884// :93:34: error: use of undefined value here causes illegal behavior1881// :93:34: error: use of undefined value here causes illegal behavior
1885// :93:34: note: when computing vector element at index '1'
1886// :93:34: error: use of undefined value here causes illegal behavior1882// :93:34: error: use of undefined value here causes illegal behavior
1887// :93:34: note: when computing vector element at index '0'
1888// :93:34: error: use of undefined value here causes illegal behavior1883// :93:34: error: use of undefined value here causes illegal behavior
1889// :93:34: note: when computing vector element at index '0'1884// :93:34: note: when computing vector element at index '0'
1890// :93:34: error: use of undefined value here causes illegal behavior1885// :93:34: error: use of undefined value here causes illegal behavior
1891// :93:34: note: when computing vector element at index '0'1886// :93:34: note: when computing vector element at index '0'
1892// :93:34: error: use of undefined value here causes illegal behavior1887// :93:34: error: use of undefined value here causes illegal behavior
1893// :93:34: error: use of undefined value here causes illegal behavior
1894// :93:34: note: when computing vector element at index '0'1888// :93:34: note: when computing vector element at index '0'
1895// :93:34: error: use of undefined value here causes illegal behavior1889// :93:34: error: use of undefined value here causes illegal behavior
1896// :93:34: note: when computing vector element at index '0'1890// :93:34: note: when computing vector element at index '0'
1897// :93:34: error: use of undefined value here causes illegal behavior1891// :93:34: error: use of undefined value here causes illegal behavior
1898// :93:34: note: when computing vector element at index '0'1892// :93:34: note: when computing vector element at index '0'
1899// :93:34: error: use of undefined value here causes illegal behavior1893// :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
1902// :93:34: note: when computing vector element at index '0'1894// :93:34: note: when computing vector element at index '0'
1903// :93:34: error: use of undefined value here causes illegal behavior1895// :93:34: error: use of undefined value here causes illegal behavior
1904// :93:34: note: when computing vector element at index '0'1896// :93:34: note: when computing vector element at index '0'
1905// :93:34: error: use of undefined value here causes illegal behavior1897// :93:34: error: use of undefined value here causes illegal behavior
1906// :93:34: note: when computing vector element at index '0'1898// :93:34: note: when computing vector element at index '0'
1907// :93:34: error: use of undefined value here causes illegal behavior1899// :93:34: error: use of undefined value here causes illegal behavior
1900// :93:34: note: when computing vector element at index '0'
1908// :93:34: error: use of undefined value here causes illegal behavior1901// :93:34: error: use of undefined value here causes illegal behavior
1909// :93:34: note: when computing vector element at index '0'1902// :93:34: note: when computing vector element at index '0'
1910// :93:34: error: use of undefined value here causes illegal behavior1903// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1912,7 +1905,7 @@ const std = @import("std");...@@ -1912,7 +1905,7 @@ const std = @import("std");
1912// :93:34: error: use of undefined value here causes illegal behavior1905// :93:34: error: use of undefined value here causes illegal behavior
1913// :93:34: note: when computing vector element at index '0'1906// :93:34: note: when computing vector element at index '0'
1914// :93:34: error: use of undefined value here causes illegal behavior1907// :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'
1916// :93:34: error: use of undefined value here causes illegal behavior1909// :93:34: error: use of undefined value here causes illegal behavior
1917// :93:34: note: when computing vector element at index '0'1910// :93:34: note: when computing vector element at index '0'
1918// :93:34: error: use of undefined value here causes illegal behavior1911// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1920,6 +1913,7 @@ const std = @import("std");...@@ -1920,6 +1913,7 @@ const std = @import("std");
1920// :93:34: error: use of undefined value here causes illegal behavior1913// :93:34: error: use of undefined value here causes illegal behavior
1921// :93:34: note: when computing vector element at index '0'1914// :93:34: note: when computing vector element at index '0'
1922// :93:34: error: use of undefined value here causes illegal behavior1915// :93:34: error: use of undefined value here causes illegal behavior
1916// :93:34: note: when computing vector element at index '0'
1923// :93:34: error: use of undefined value here causes illegal behavior1917// :93:34: error: use of undefined value here causes illegal behavior
1924// :93:34: note: when computing vector element at index '0'1918// :93:34: note: when computing vector element at index '0'
1925// :93:34: error: use of undefined value here causes illegal behavior1919// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1927,7 +1921,7 @@ const std = @import("std");...@@ -1927,7 +1921,7 @@ const std = @import("std");
1927// :93:34: error: use of undefined value here causes illegal behavior1921// :93:34: error: use of undefined value here causes illegal behavior
1928// :93:34: note: when computing vector element at index '0'1922// :93:34: note: when computing vector element at index '0'
1929// :93:34: error: use of undefined value here causes illegal behavior1923// :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'
1931// :93:34: error: use of undefined value here causes illegal behavior1925// :93:34: error: use of undefined value here causes illegal behavior
1932// :93:34: note: when computing vector element at index '0'1926// :93:34: note: when computing vector element at index '0'
1933// :93:34: error: use of undefined value here causes illegal behavior1927// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1935,6 +1929,7 @@ const std = @import("std");...@@ -1935,6 +1929,7 @@ const std = @import("std");
1935// :93:34: error: use of undefined value here causes illegal behavior1929// :93:34: error: use of undefined value here causes illegal behavior
1936// :93:34: note: when computing vector element at index '0'1930// :93:34: note: when computing vector element at index '0'
1937// :93:34: error: use of undefined value here causes illegal behavior1931// :93:34: error: use of undefined value here causes illegal behavior
1932// :93:34: note: when computing vector element at index '0'
1938// :93:34: error: use of undefined value here causes illegal behavior1933// :93:34: error: use of undefined value here causes illegal behavior
1939// :93:34: note: when computing vector element at index '0'1934// :93:34: note: when computing vector element at index '0'
1940// :93:34: error: use of undefined value here causes illegal behavior1935// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1942,7 +1937,7 @@ const std = @import("std");...@@ -1942,7 +1937,7 @@ const std = @import("std");
1942// :93:34: error: use of undefined value here causes illegal behavior1937// :93:34: error: use of undefined value here causes illegal behavior
1943// :93:34: note: when computing vector element at index '0'1938// :93:34: note: when computing vector element at index '0'
1944// :93:34: error: use of undefined value here causes illegal behavior1939// :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'
1946// :93:34: error: use of undefined value here causes illegal behavior1941// :93:34: error: use of undefined value here causes illegal behavior
1947// :93:34: note: when computing vector element at index '0'1942// :93:34: note: when computing vector element at index '0'
1948// :93:34: error: use of undefined value here causes illegal behavior1943// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1950,6 +1945,7 @@ const std = @import("std");...@@ -1950,6 +1945,7 @@ const std = @import("std");
1950// :93:34: error: use of undefined value here causes illegal behavior1945// :93:34: error: use of undefined value here causes illegal behavior
1951// :93:34: note: when computing vector element at index '0'1946// :93:34: note: when computing vector element at index '0'
1952// :93:34: error: use of undefined value here causes illegal behavior1947// :93:34: error: use of undefined value here causes illegal behavior
1948// :93:34: note: when computing vector element at index '0'
1953// :93:34: error: use of undefined value here causes illegal behavior1949// :93:34: error: use of undefined value here causes illegal behavior
1954// :93:34: note: when computing vector element at index '0'1950// :93:34: note: when computing vector element at index '0'
1955// :93:34: error: use of undefined value here causes illegal behavior1951// :93:34: error: use of undefined value here causes illegal behavior
...@@ -1959,108 +1955,105 @@ const std = @import("std");...@@ -1959,108 +1955,105 @@ const std = @import("std");
1959// :93:34: error: use of undefined value here causes illegal behavior1955// :93:34: error: use of undefined value here causes illegal behavior
1960// :93:34: note: when computing vector element at index '1'1956// :93:34: note: when computing vector element at index '1'
1961// :93:34: error: use of undefined value here causes illegal behavior1957// :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'
1963// :93:34: error: use of undefined value here causes illegal behavior1959// :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'
1965// :93:34: error: use of undefined value here causes illegal behavior1961// :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'
1967// :93:37: error: use of undefined value here causes illegal behavior1967// :93:37: error: use of undefined value here causes illegal behavior
1968// :93:37: error: use of undefined value here causes illegal behavior1968// :93:37: error: use of undefined value here causes illegal behavior
1969// :93:37: note: when computing vector element at index '0'
1970// :93:37: error: use of undefined value here causes illegal behavior1969// :93:37: error: use of undefined value here causes illegal behavior
1971// :93:37: note: when computing vector element at index '0'
1972// :93:37: error: use of undefined value here causes illegal behavior1970// :93:37: error: use of undefined value here causes illegal behavior
1973// :93:37: note: when computing vector element at index '1'
1974// :93:37: error: use of undefined value here causes illegal behavior1971// :93:37: error: use of undefined value here causes illegal behavior
1975// :93:37: note: when computing vector element at index '0'
1976// :93:37: error: use of undefined value here causes illegal behavior1972// :93:37: error: use of undefined value here causes illegal behavior
1977// :93:37: note: when computing vector element at index '0'
1978// :93:37: error: use of undefined value here causes illegal behavior1973// :93:37: error: use of undefined value here causes illegal behavior
1974// :93:37: note: when computing vector element at index '0'
1979// :93:37: error: use of undefined value here causes illegal behavior1975// :93:37: error: use of undefined value here causes illegal behavior
1980// :93:37: note: when computing vector element at index '0'1976// :93:37: note: when computing vector element at index '0'
1981// :93:37: error: use of undefined value here causes illegal behavior1977// :93:37: error: use of undefined value here causes illegal behavior
1982// :93:37: note: when computing vector element at index '0'1978// :93:37: note: when computing vector element at index '0'
1983// :93:37: error: use of undefined value here causes illegal behavior1979// :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'
1985// :93:37: error: use of undefined value here causes illegal behavior1981// :93:37: error: use of undefined value here causes illegal behavior
1986// :93:37: note: when computing vector element at index '0'1982// :93:37: note: when computing vector element at index '0'
1987// :93:37: error: use of undefined value here causes illegal behavior1983// :93:37: error: use of undefined value here causes illegal behavior
1988// :93:37: note: when computing vector element at index '0'1984// :93:37: note: when computing vector element at index '0'
1989// :93:37: error: use of undefined value here causes illegal behavior1985// :93:37: error: use of undefined value here causes illegal behavior
1986// :93:37: note: when computing vector element at index '0'
1990// :93:37: error: use of undefined value here causes illegal behavior1987// :93:37: error: use of undefined value here causes illegal behavior
1991// :93:37: note: when computing vector element at index '0'1988// :93:37: note: when computing vector element at index '0'
1992// :93:37: error: use of undefined value here causes illegal behavior1989// :93:37: error: use of undefined value here causes illegal behavior
1993// :93:37: note: when computing vector element at index '0'1990// :93:37: note: when computing vector element at index '0'
1994// :93:37: error: use of undefined value here causes illegal behavior1991// :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'
1996// :93:37: error: use of undefined value here causes illegal behavior1993// :93:37: error: use of undefined value here causes illegal behavior
1997// :93:37: note: when computing vector element at index '0'1994// :93:37: note: when computing vector element at index '0'
1998// :93:37: error: use of undefined value here causes illegal behavior1995// :93:37: error: use of undefined value here causes illegal behavior
1999// :93:37: note: when computing vector element at index '0'1996// :93:37: note: when computing vector element at index '0'
2000// :93:37: error: use of undefined value here causes illegal behavior1997// :93:37: error: use of undefined value here causes illegal behavior
1998// :93:37: note: when computing vector element at index '0'
2001// :93:37: error: use of undefined value here causes illegal behavior1999// :93:37: error: use of undefined value here causes illegal behavior
2002// :93:37: note: when computing vector element at index '0'2000// :93:37: note: when computing vector element at index '0'
2003// :93:37: error: use of undefined value here causes illegal behavior2001// :93:37: error: use of undefined value here causes illegal behavior
2004// :93:37: note: when computing vector element at index '0'2002// :93:37: note: when computing vector element at index '0'
2005// :93:37: error: use of undefined value here causes illegal behavior2003// :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'
2007// :93:37: error: use of undefined value here causes illegal behavior2005// :93:37: error: use of undefined value here causes illegal behavior
2008// :93:37: note: when computing vector element at index '0'2006// :93:37: note: when computing vector element at index '0'
2009// :93:37: error: use of undefined value here causes illegal behavior2007// :93:37: error: use of undefined value here causes illegal behavior
2010// :93:37: note: when computing vector element at index '0'2008// :93:37: note: when computing vector element at index '0'
2011// :93:37: error: use of undefined value here causes illegal behavior2009// :93:37: error: use of undefined value here causes illegal behavior
2010// :93:37: note: when computing vector element at index '0'
2012// :93:37: error: use of undefined value here causes illegal behavior2011// :93:37: error: use of undefined value here causes illegal behavior
2013// :93:37: note: when computing vector element at index '0'2012// :93:37: note: when computing vector element at index '0'
2014// :93:37: error: use of undefined value here causes illegal behavior2013// :93:37: error: use of undefined value here causes illegal behavior
2015// :93:37: note: when computing vector element at index '0'2014// :93:37: note: when computing vector element at index '0'
2016// :93:37: error: use of undefined value here causes illegal behavior2015// :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'
2018// :93:37: error: use of undefined value here causes illegal behavior2017// :93:37: error: use of undefined value here causes illegal behavior
2019// :93:37: note: when computing vector element at index '0'2018// :93:37: note: when computing vector element at index '0'
2020// :93:37: error: use of undefined value here causes illegal behavior2019// :93:37: error: use of undefined value here causes illegal behavior
2021// :93:37: note: when computing vector element at index '0'2020// :93:37: note: when computing vector element at index '0'
2022// :93:37: error: use of undefined value here causes illegal behavior2021// :93:37: error: use of undefined value here causes illegal behavior
2022// :93:37: note: when computing vector element at index '1'
2023// :93:37: error: use of undefined value here causes illegal behavior2023// :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'
2025// :93:37: error: use of undefined value here causes illegal behavior2025// :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'
2027// :93:37: error: use of undefined value here causes illegal behavior2027// :93:37: error: use of undefined value here causes illegal behavior
2028// :93:37: note: when computing vector element at index '1'2028// :93:37: note: when computing vector element at index '1'
2029// :93:37: error: use of undefined value here causes illegal behavior2029// :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'
2031// :93:37: error: use of undefined value here causes illegal behavior2031// :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'
2033// :96:17: error: use of undefined value here causes illegal behavior2033// :96:17: error: use of undefined value here causes illegal behavior
2034// :96:17: error: use of undefined value here causes illegal behavior2034// :96:17: error: use of undefined value here causes illegal behavior
2035// :96:17: note: when computing vector element at index '0'
2036// :96:17: error: use of undefined value here causes illegal behavior2035// :96:17: error: use of undefined value here causes illegal behavior
2037// :96:17: note: when computing vector element at index '0'
2038// :96:17: error: use of undefined value here causes illegal behavior2036// :96:17: error: use of undefined value here causes illegal behavior
2039// :96:17: note: when computing vector element at index '0'
2040// :96:17: error: use of undefined value here causes illegal behavior2037// :96:17: error: use of undefined value here causes illegal behavior
2041// :96:17: note: when computing vector element at index '1'
2042// :96:17: error: use of undefined value here causes illegal behavior2038// :96:17: error: use of undefined value here causes illegal behavior
2043// :96:17: note: when computing vector element at index '0'
2044// :96:17: error: use of undefined value here causes illegal behavior2039// :96:17: error: use of undefined value here causes illegal behavior
2045// :96:17: note: when computing vector element at index '0'2040// :96:17: note: when computing vector element at index '0'
2046// :96:17: error: use of undefined value here causes illegal behavior2041// :96:17: error: use of undefined value here causes illegal behavior
2047// :96:17: note: when computing vector element at index '0'2042// :96:17: note: when computing vector element at index '0'
2048// :96:17: error: use of undefined value here causes illegal behavior2043// :96:17: error: use of undefined value here causes illegal behavior
2049// :96:17: error: use of undefined value here causes illegal behavior
2050// :96:17: note: when computing vector element at index '0'2044// :96:17: note: when computing vector element at index '0'
2051// :96:17: error: use of undefined value here causes illegal behavior2045// :96:17: error: use of undefined value here causes illegal behavior
2052// :96:17: note: when computing vector element at index '0'2046// :96:17: note: when computing vector element at index '0'
2053// :96:17: error: use of undefined value here causes illegal behavior2047// :96:17: error: use of undefined value here causes illegal behavior
2054// :96:17: note: when computing vector element at index '0'2048// :96:17: note: when computing vector element at index '0'
2055// :96:17: error: use of undefined value here causes illegal behavior2049// :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
2058// :96:17: note: when computing vector element at index '0'2050// :96:17: note: when computing vector element at index '0'
2059// :96:17: error: use of undefined value here causes illegal behavior2051// :96:17: error: use of undefined value here causes illegal behavior
2060// :96:17: note: when computing vector element at index '0'2052// :96:17: note: when computing vector element at index '0'
2061// :96:17: error: use of undefined value here causes illegal behavior2053// :96:17: error: use of undefined value here causes illegal behavior
2062// :96:17: note: when computing vector element at index '0'2054// :96:17: note: when computing vector element at index '0'
2063// :96:17: error: use of undefined value here causes illegal behavior2055// :96:17: error: use of undefined value here causes illegal behavior
2056// :96:17: note: when computing vector element at index '0'
2064// :96:17: error: use of undefined value here causes illegal behavior2057// :96:17: error: use of undefined value here causes illegal behavior
2065// :96:17: note: when computing vector element at index '0'2058// :96:17: note: when computing vector element at index '0'
2066// :96:17: error: use of undefined value here causes illegal behavior2059// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2068,7 +2061,7 @@ const std = @import("std");...@@ -2068,7 +2061,7 @@ const std = @import("std");
2068// :96:17: error: use of undefined value here causes illegal behavior2061// :96:17: error: use of undefined value here causes illegal behavior
2069// :96:17: note: when computing vector element at index '0'2062// :96:17: note: when computing vector element at index '0'
2070// :96:17: error: use of undefined value here causes illegal behavior2063// :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'
2072// :96:17: error: use of undefined value here causes illegal behavior2065// :96:17: error: use of undefined value here causes illegal behavior
2073// :96:17: note: when computing vector element at index '0'2066// :96:17: note: when computing vector element at index '0'
2074// :96:17: error: use of undefined value here causes illegal behavior2067// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2076,6 +2069,7 @@ const std = @import("std");...@@ -2076,6 +2069,7 @@ const std = @import("std");
2076// :96:17: error: use of undefined value here causes illegal behavior2069// :96:17: error: use of undefined value here causes illegal behavior
2077// :96:17: note: when computing vector element at index '0'2070// :96:17: note: when computing vector element at index '0'
2078// :96:17: error: use of undefined value here causes illegal behavior2071// :96:17: error: use of undefined value here causes illegal behavior
2072// :96:17: note: when computing vector element at index '0'
2079// :96:17: error: use of undefined value here causes illegal behavior2073// :96:17: error: use of undefined value here causes illegal behavior
2080// :96:17: note: when computing vector element at index '0'2074// :96:17: note: when computing vector element at index '0'
2081// :96:17: error: use of undefined value here causes illegal behavior2075// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2083,7 +2077,7 @@ const std = @import("std");...@@ -2083,7 +2077,7 @@ const std = @import("std");
2083// :96:17: error: use of undefined value here causes illegal behavior2077// :96:17: error: use of undefined value here causes illegal behavior
2084// :96:17: note: when computing vector element at index '0'2078// :96:17: note: when computing vector element at index '0'
2085// :96:17: error: use of undefined value here causes illegal behavior2079// :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'
2087// :96:17: error: use of undefined value here causes illegal behavior2081// :96:17: error: use of undefined value here causes illegal behavior
2088// :96:17: note: when computing vector element at index '0'2082// :96:17: note: when computing vector element at index '0'
2089// :96:17: error: use of undefined value here causes illegal behavior2083// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2091,6 +2085,7 @@ const std = @import("std");...@@ -2091,6 +2085,7 @@ const std = @import("std");
2091// :96:17: error: use of undefined value here causes illegal behavior2085// :96:17: error: use of undefined value here causes illegal behavior
2092// :96:17: note: when computing vector element at index '0'2086// :96:17: note: when computing vector element at index '0'
2093// :96:17: error: use of undefined value here causes illegal behavior2087// :96:17: error: use of undefined value here causes illegal behavior
2088// :96:17: note: when computing vector element at index '0'
2094// :96:17: error: use of undefined value here causes illegal behavior2089// :96:17: error: use of undefined value here causes illegal behavior
2095// :96:17: note: when computing vector element at index '0'2090// :96:17: note: when computing vector element at index '0'
2096// :96:17: error: use of undefined value here causes illegal behavior2091// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2098,7 +2093,7 @@ const std = @import("std");...@@ -2098,7 +2093,7 @@ const std = @import("std");
2098// :96:17: error: use of undefined value here causes illegal behavior2093// :96:17: error: use of undefined value here causes illegal behavior
2099// :96:17: note: when computing vector element at index '0'2094// :96:17: note: when computing vector element at index '0'
2100// :96:17: error: use of undefined value here causes illegal behavior2095// :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'
2102// :96:17: error: use of undefined value here causes illegal behavior2097// :96:17: error: use of undefined value here causes illegal behavior
2103// :96:17: note: when computing vector element at index '0'2098// :96:17: note: when computing vector element at index '0'
2104// :96:17: error: use of undefined value here causes illegal behavior2099// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2106,6 +2101,7 @@ const std = @import("std");...@@ -2106,6 +2101,7 @@ const std = @import("std");
2106// :96:17: error: use of undefined value here causes illegal behavior2101// :96:17: error: use of undefined value here causes illegal behavior
2107// :96:17: note: when computing vector element at index '0'2102// :96:17: note: when computing vector element at index '0'
2108// :96:17: error: use of undefined value here causes illegal behavior2103// :96:17: error: use of undefined value here causes illegal behavior
2104// :96:17: note: when computing vector element at index '0'
2109// :96:17: error: use of undefined value here causes illegal behavior2105// :96:17: error: use of undefined value here causes illegal behavior
2110// :96:17: note: when computing vector element at index '0'2106// :96:17: note: when computing vector element at index '0'
2111// :96:17: error: use of undefined value here causes illegal behavior2107// :96:17: error: use of undefined value here causes illegal behavior
...@@ -2115,67 +2111,65 @@ const std = @import("std");...@@ -2115,67 +2111,65 @@ const std = @import("std");
2115// :96:17: error: use of undefined value here causes illegal behavior2111// :96:17: error: use of undefined value here causes illegal behavior
2116// :96:17: note: when computing vector element at index '1'2112// :96:17: note: when computing vector element at index '1'
2117// :96:17: error: use of undefined value here causes illegal behavior2113// :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'
2119// :96:17: error: use of undefined value here causes illegal behavior2115// :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'
2121// :96:17: error: use of undefined value here causes illegal behavior2117// :96:17: error: use of undefined value here causes illegal behavior
2122// :96:17: note: when computing vector element at index '0'2118// :96:17: note: when computing vector element at index '1'
2123// :96:22: error: use of undefined value here causes illegal behavior2119// :96:17: error: use of undefined value here causes illegal behavior
2124// :96:22: error: use of undefined value here causes illegal behavior2120// :96:17: note: when computing vector element at index '1'
2125// :96:22: note: when computing vector element at index '0'2121// :96:17: error: use of undefined value here causes illegal behavior
2122// :96:17: note: when computing vector element at index '1'
2126// :96:22: error: use of undefined value here causes illegal behavior2123// :96:22: error: use of undefined value here causes illegal behavior
2127// :96:22: note: when computing vector element at index '0'
2128// :96:22: error: use of undefined value here causes illegal behavior2124// :96:22: error: use of undefined value here causes illegal behavior
2129// :96:22: note: when computing vector element at index '1'
2130// :96:22: error: use of undefined value here causes illegal behavior2125// :96:22: error: use of undefined value here causes illegal behavior
2131// :96:22: note: when computing vector element at index '0'
2132// :96:22: error: use of undefined value here causes illegal behavior2126// :96:22: error: use of undefined value here causes illegal behavior
2133// :96:22: note: when computing vector element at index '0'
2134// :96:22: error: use of undefined value here causes illegal behavior2127// :96:22: error: use of undefined value here causes illegal behavior
2135// :96:22: error: use of undefined value here causes illegal behavior2128// :96:22: error: use of undefined value here causes illegal behavior
2136// :96:22: note: when computing vector element at index '0'
2137// :96:22: error: use of undefined value here causes illegal behavior2129// :96:22: error: use of undefined value here causes illegal behavior
2138// :96:22: note: when computing vector element at index '0'2130// :96:22: note: when computing vector element at index '0'
2139// :96:22: error: use of undefined value here causes illegal behavior2131// :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
2142// :96:22: note: when computing vector element at index '0'2132// :96:22: note: when computing vector element at index '0'
2143// :96:22: error: use of undefined value here causes illegal behavior2133// :96:22: error: use of undefined value here causes illegal behavior
2144// :96:22: note: when computing vector element at index '0'2134// :96:22: note: when computing vector element at index '0'
2145// :96:22: error: use of undefined value here causes illegal behavior2135// :96:22: error: use of undefined value here causes illegal behavior
2136// :96:22: note: when computing vector element at index '0'
2146// :96:22: error: use of undefined value here causes illegal behavior2137// :96:22: error: use of undefined value here causes illegal behavior
2147// :96:22: note: when computing vector element at index '0'2138// :96:22: note: when computing vector element at index '0'
2148// :96:22: error: use of undefined value here causes illegal behavior2139// :96:22: error: use of undefined value here causes illegal behavior
2149// :96:22: note: when computing vector element at index '0'2140// :96:22: note: when computing vector element at index '0'
2150// :96:22: error: use of undefined value here causes illegal behavior2141// :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'
2152// :96:22: error: use of undefined value here causes illegal behavior2143// :96:22: error: use of undefined value here causes illegal behavior
2153// :96:22: note: when computing vector element at index '0'2144// :96:22: note: when computing vector element at index '0'
2154// :96:22: error: use of undefined value here causes illegal behavior2145// :96:22: error: use of undefined value here causes illegal behavior
2155// :96:22: note: when computing vector element at index '0'2146// :96:22: note: when computing vector element at index '0'
2156// :96:22: error: use of undefined value here causes illegal behavior2147// :96:22: error: use of undefined value here causes illegal behavior
2148// :96:22: note: when computing vector element at index '0'
2157// :96:22: error: use of undefined value here causes illegal behavior2149// :96:22: error: use of undefined value here causes illegal behavior
2158// :96:22: note: when computing vector element at index '0'2150// :96:22: note: when computing vector element at index '0'
2159// :96:22: error: use of undefined value here causes illegal behavior2151// :96:22: error: use of undefined value here causes illegal behavior
2160// :96:22: note: when computing vector element at index '0'2152// :96:22: note: when computing vector element at index '0'
2161// :96:22: error: use of undefined value here causes illegal behavior2153// :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'
2163// :96:22: error: use of undefined value here causes illegal behavior2155// :96:22: error: use of undefined value here causes illegal behavior
2164// :96:22: note: when computing vector element at index '0'2156// :96:22: note: when computing vector element at index '0'
2165// :96:22: error: use of undefined value here causes illegal behavior2157// :96:22: error: use of undefined value here causes illegal behavior
2166// :96:22: note: when computing vector element at index '0'2158// :96:22: note: when computing vector element at index '0'
2167// :96:22: error: use of undefined value here causes illegal behavior2159// :96:22: error: use of undefined value here causes illegal behavior
2160// :96:22: note: when computing vector element at index '0'
2168// :96:22: error: use of undefined value here causes illegal behavior2161// :96:22: error: use of undefined value here causes illegal behavior
2169// :96:22: note: when computing vector element at index '0'2162// :96:22: note: when computing vector element at index '0'
2170// :96:22: error: use of undefined value here causes illegal behavior2163// :96:22: error: use of undefined value here causes illegal behavior
2171// :96:22: note: when computing vector element at index '0'2164// :96:22: note: when computing vector element at index '0'
2172// :96:22: error: use of undefined value here causes illegal behavior2165// :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'
2174// :96:22: error: use of undefined value here causes illegal behavior2167// :96:22: error: use of undefined value here causes illegal behavior
2175// :96:22: note: when computing vector element at index '0'2168// :96:22: note: when computing vector element at index '0'
2176// :96:22: error: use of undefined value here causes illegal behavior2169// :96:22: error: use of undefined value here causes illegal behavior
2177// :96:22: note: when computing vector element at index '0'2170// :96:22: note: when computing vector element at index '0'
2178// :96:22: error: use of undefined value here causes illegal behavior2171// :96:22: error: use of undefined value here causes illegal behavior
2172// :96:22: note: when computing vector element at index '0'
2179// :96:22: error: use of undefined value here causes illegal behavior2173// :96:22: error: use of undefined value here causes illegal behavior
2180// :96:22: note: when computing vector element at index '0'2174// :96:22: note: when computing vector element at index '0'
2181// :96:22: error: use of undefined value here causes illegal behavior2175// :96:22: error: use of undefined value here causes illegal behavior
...@@ -2183,40 +2177,39 @@ const std = @import("std");...@@ -2183,40 +2177,39 @@ const std = @import("std");
2183// :96:22: error: use of undefined value here causes illegal behavior2177// :96:22: error: use of undefined value here causes illegal behavior
2184// :96:22: note: when computing vector element at index '1'2178// :96:22: note: when computing vector element at index '1'
2185// :96:22: error: use of undefined value here causes illegal behavior2179// :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'
2187// :96:22: error: use of undefined value here causes illegal behavior2181// :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'
2189// :99:27: error: use of undefined value here causes illegal behavior2189// :99:27: error: use of undefined value here causes illegal behavior
2190// :99:27: error: use of undefined value here causes illegal behavior2190// :99:27: error: use of undefined value here causes illegal behavior
2191// :99:27: note: when computing vector element at index '0'
2192// :99:27: error: use of undefined value here causes illegal behavior2191// :99:27: error: use of undefined value here causes illegal behavior
2193// :99:27: note: when computing vector element at index '0'
2194// :99:27: error: use of undefined value here causes illegal behavior2192// :99:27: error: use of undefined value here causes illegal behavior
2195// :99:27: note: when computing vector element at index '0'
2196// :99:27: error: use of undefined value here causes illegal behavior2193// :99:27: error: use of undefined value here causes illegal behavior
2197// :99:27: note: when computing vector element at index '1'
2198// :99:27: error: use of undefined value here causes illegal behavior2194// :99:27: error: use of undefined value here causes illegal behavior
2199// :99:27: note: when computing vector element at index '0'
2200// :99:27: error: use of undefined value here causes illegal behavior2195// :99:27: error: use of undefined value here causes illegal behavior
2201// :99:27: note: when computing vector element at index '0'2196// :99:27: note: when computing vector element at index '0'
2202// :99:27: error: use of undefined value here causes illegal behavior2197// :99:27: error: use of undefined value here causes illegal behavior
2203// :99:27: note: when computing vector element at index '0'2198// :99:27: note: when computing vector element at index '0'
2204// :99:27: error: use of undefined value here causes illegal behavior2199// :99:27: error: use of undefined value here causes illegal behavior
2205// :99:27: error: use of undefined value here causes illegal behavior
2206// :99:27: note: when computing vector element at index '0'2200// :99:27: note: when computing vector element at index '0'
2207// :99:27: error: use of undefined value here causes illegal behavior2201// :99:27: error: use of undefined value here causes illegal behavior
2208// :99:27: note: when computing vector element at index '0'2202// :99:27: note: when computing vector element at index '0'
2209// :99:27: error: use of undefined value here causes illegal behavior2203// :99:27: error: use of undefined value here causes illegal behavior
2210// :99:27: note: when computing vector element at index '0'2204// :99:27: note: when computing vector element at index '0'
2211// :99:27: error: use of undefined value here causes illegal behavior2205// :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
2214// :99:27: note: when computing vector element at index '0'2206// :99:27: note: when computing vector element at index '0'
2215// :99:27: error: use of undefined value here causes illegal behavior2207// :99:27: error: use of undefined value here causes illegal behavior
2216// :99:27: note: when computing vector element at index '0'2208// :99:27: note: when computing vector element at index '0'
2217// :99:27: error: use of undefined value here causes illegal behavior2209// :99:27: error: use of undefined value here causes illegal behavior
2218// :99:27: note: when computing vector element at index '0'2210// :99:27: note: when computing vector element at index '0'
2219// :99:27: error: use of undefined value here causes illegal behavior2211// :99:27: error: use of undefined value here causes illegal behavior
2212// :99:27: note: when computing vector element at index '0'
2220// :99:27: error: use of undefined value here causes illegal behavior2213// :99:27: error: use of undefined value here causes illegal behavior
2221// :99:27: note: when computing vector element at index '0'2214// :99:27: note: when computing vector element at index '0'
2222// :99:27: error: use of undefined value here causes illegal behavior2215// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2224,7 +2217,7 @@ const std = @import("std");...@@ -2224,7 +2217,7 @@ const std = @import("std");
2224// :99:27: error: use of undefined value here causes illegal behavior2217// :99:27: error: use of undefined value here causes illegal behavior
2225// :99:27: note: when computing vector element at index '0'2218// :99:27: note: when computing vector element at index '0'
2226// :99:27: error: use of undefined value here causes illegal behavior2219// :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'
2228// :99:27: error: use of undefined value here causes illegal behavior2221// :99:27: error: use of undefined value here causes illegal behavior
2229// :99:27: note: when computing vector element at index '0'2222// :99:27: note: when computing vector element at index '0'
2230// :99:27: error: use of undefined value here causes illegal behavior2223// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2232,6 +2225,7 @@ const std = @import("std");...@@ -2232,6 +2225,7 @@ const std = @import("std");
2232// :99:27: error: use of undefined value here causes illegal behavior2225// :99:27: error: use of undefined value here causes illegal behavior
2233// :99:27: note: when computing vector element at index '0'2226// :99:27: note: when computing vector element at index '0'
2234// :99:27: error: use of undefined value here causes illegal behavior2227// :99:27: error: use of undefined value here causes illegal behavior
2228// :99:27: note: when computing vector element at index '0'
2235// :99:27: error: use of undefined value here causes illegal behavior2229// :99:27: error: use of undefined value here causes illegal behavior
2236// :99:27: note: when computing vector element at index '0'2230// :99:27: note: when computing vector element at index '0'
2237// :99:27: error: use of undefined value here causes illegal behavior2231// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2239,7 +2233,7 @@ const std = @import("std");...@@ -2239,7 +2233,7 @@ const std = @import("std");
2239// :99:27: error: use of undefined value here causes illegal behavior2233// :99:27: error: use of undefined value here causes illegal behavior
2240// :99:27: note: when computing vector element at index '0'2234// :99:27: note: when computing vector element at index '0'
2241// :99:27: error: use of undefined value here causes illegal behavior2235// :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'
2243// :99:27: error: use of undefined value here causes illegal behavior2237// :99:27: error: use of undefined value here causes illegal behavior
2244// :99:27: note: when computing vector element at index '0'2238// :99:27: note: when computing vector element at index '0'
2245// :99:27: error: use of undefined value here causes illegal behavior2239// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2247,6 +2241,7 @@ const std = @import("std");...@@ -2247,6 +2241,7 @@ const std = @import("std");
2247// :99:27: error: use of undefined value here causes illegal behavior2241// :99:27: error: use of undefined value here causes illegal behavior
2248// :99:27: note: when computing vector element at index '0'2242// :99:27: note: when computing vector element at index '0'
2249// :99:27: error: use of undefined value here causes illegal behavior2243// :99:27: error: use of undefined value here causes illegal behavior
2244// :99:27: note: when computing vector element at index '0'
2250// :99:27: error: use of undefined value here causes illegal behavior2245// :99:27: error: use of undefined value here causes illegal behavior
2251// :99:27: note: when computing vector element at index '0'2246// :99:27: note: when computing vector element at index '0'
2252// :99:27: error: use of undefined value here causes illegal behavior2247// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2254,7 +2249,7 @@ const std = @import("std");...@@ -2254,7 +2249,7 @@ const std = @import("std");
2254// :99:27: error: use of undefined value here causes illegal behavior2249// :99:27: error: use of undefined value here causes illegal behavior
2255// :99:27: note: when computing vector element at index '0'2250// :99:27: note: when computing vector element at index '0'
2256// :99:27: error: use of undefined value here causes illegal behavior2251// :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'
2258// :99:27: error: use of undefined value here causes illegal behavior2253// :99:27: error: use of undefined value here causes illegal behavior
2259// :99:27: note: when computing vector element at index '0'2254// :99:27: note: when computing vector element at index '0'
2260// :99:27: error: use of undefined value here causes illegal behavior2255// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2262,6 +2257,7 @@ const std = @import("std");...@@ -2262,6 +2257,7 @@ const std = @import("std");
2262// :99:27: error: use of undefined value here causes illegal behavior2257// :99:27: error: use of undefined value here causes illegal behavior
2263// :99:27: note: when computing vector element at index '0'2258// :99:27: note: when computing vector element at index '0'
2264// :99:27: error: use of undefined value here causes illegal behavior2259// :99:27: error: use of undefined value here causes illegal behavior
2260// :99:27: note: when computing vector element at index '0'
2265// :99:27: error: use of undefined value here causes illegal behavior2261// :99:27: error: use of undefined value here causes illegal behavior
2266// :99:27: note: when computing vector element at index '0'2262// :99:27: note: when computing vector element at index '0'
2267// :99:27: error: use of undefined value here causes illegal behavior2263// :99:27: error: use of undefined value here causes illegal behavior
...@@ -2271,77 +2267,81 @@ const std = @import("std");...@@ -2271,77 +2267,81 @@ const std = @import("std");
2271// :99:27: error: use of undefined value here causes illegal behavior2267// :99:27: error: use of undefined value here causes illegal behavior
2272// :99:27: note: when computing vector element at index '1'2268// :99:27: note: when computing vector element at index '1'
2273// :99:27: error: use of undefined value here causes illegal behavior2269// :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'
2275// :99:27: error: use of undefined value here causes illegal behavior2271// :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'
2277// :99:27: error: use of undefined value here causes illegal behavior2273// :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'
2279// :99:30: error: use of undefined value here causes illegal behavior2279// :99:30: error: use of undefined value here causes illegal behavior
2280// :99:30: error: use of undefined value here causes illegal behavior2280// :99:30: error: use of undefined value here causes illegal behavior
2281// :99:30: note: when computing vector element at index '0'
2282// :99:30: error: use of undefined value here causes illegal behavior2281// :99:30: error: use of undefined value here causes illegal behavior
2283// :99:30: note: when computing vector element at index '0'
2284// :99:30: error: use of undefined value here causes illegal behavior2282// :99:30: error: use of undefined value here causes illegal behavior
2285// :99:30: note: when computing vector element at index '1'
2286// :99:30: error: use of undefined value here causes illegal behavior2283// :99:30: error: use of undefined value here causes illegal behavior
2287// :99:30: note: when computing vector element at index '0'
2288// :99:30: error: use of undefined value here causes illegal behavior2284// :99:30: error: use of undefined value here causes illegal behavior
2289// :99:30: note: when computing vector element at index '0'
2290// :99:30: error: use of undefined value here causes illegal behavior2285// :99:30: error: use of undefined value here causes illegal behavior
2286// :99:30: note: when computing vector element at index '0'
2291// :99:30: error: use of undefined value here causes illegal behavior2287// :99:30: error: use of undefined value here causes illegal behavior
2292// :99:30: note: when computing vector element at index '0'2288// :99:30: note: when computing vector element at index '0'
2293// :99:30: error: use of undefined value here causes illegal behavior2289// :99:30: error: use of undefined value here causes illegal behavior
2294// :99:30: note: when computing vector element at index '0'2290// :99:30: note: when computing vector element at index '0'
2295// :99:30: error: use of undefined value here causes illegal behavior2291// :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'
2297// :99:30: error: use of undefined value here causes illegal behavior2293// :99:30: error: use of undefined value here causes illegal behavior
2298// :99:30: note: when computing vector element at index '0'2294// :99:30: note: when computing vector element at index '0'
2299// :99:30: error: use of undefined value here causes illegal behavior2295// :99:30: error: use of undefined value here causes illegal behavior
2300// :99:30: note: when computing vector element at index '0'2296// :99:30: note: when computing vector element at index '0'
2301// :99:30: error: use of undefined value here causes illegal behavior2297// :99:30: error: use of undefined value here causes illegal behavior
2298// :99:30: note: when computing vector element at index '0'
2302// :99:30: error: use of undefined value here causes illegal behavior2299// :99:30: error: use of undefined value here causes illegal behavior
2303// :99:30: note: when computing vector element at index '0'2300// :99:30: note: when computing vector element at index '0'
2304// :99:30: error: use of undefined value here causes illegal behavior2301// :99:30: error: use of undefined value here causes illegal behavior
2305// :99:30: note: when computing vector element at index '0'2302// :99:30: note: when computing vector element at index '0'
2306// :99:30: error: use of undefined value here causes illegal behavior2303// :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'
2308// :99:30: error: use of undefined value here causes illegal behavior2305// :99:30: error: use of undefined value here causes illegal behavior
2309// :99:30: note: when computing vector element at index '0'2306// :99:30: note: when computing vector element at index '0'
2310// :99:30: error: use of undefined value here causes illegal behavior2307// :99:30: error: use of undefined value here causes illegal behavior
2311// :99:30: note: when computing vector element at index '0'2308// :99:30: note: when computing vector element at index '0'
2312// :99:30: error: use of undefined value here causes illegal behavior2309// :99:30: error: use of undefined value here causes illegal behavior
2310// :99:30: note: when computing vector element at index '0'
2313// :99:30: error: use of undefined value here causes illegal behavior2311// :99:30: error: use of undefined value here causes illegal behavior
2314// :99:30: note: when computing vector element at index '0'2312// :99:30: note: when computing vector element at index '0'
2315// :99:30: error: use of undefined value here causes illegal behavior2313// :99:30: error: use of undefined value here causes illegal behavior
2316// :99:30: note: when computing vector element at index '0'2314// :99:30: note: when computing vector element at index '0'
2317// :99:30: error: use of undefined value here causes illegal behavior2315// :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'
2319// :99:30: error: use of undefined value here causes illegal behavior2317// :99:30: error: use of undefined value here causes illegal behavior
2320// :99:30: note: when computing vector element at index '0'2318// :99:30: note: when computing vector element at index '0'
2321// :99:30: error: use of undefined value here causes illegal behavior2319// :99:30: error: use of undefined value here causes illegal behavior
2322// :99:30: note: when computing vector element at index '0'2320// :99:30: note: when computing vector element at index '0'
2323// :99:30: error: use of undefined value here causes illegal behavior2321// :99:30: error: use of undefined value here causes illegal behavior
2322// :99:30: note: when computing vector element at index '0'
2324// :99:30: error: use of undefined value here causes illegal behavior2323// :99:30: error: use of undefined value here causes illegal behavior
2325// :99:30: note: when computing vector element at index '0'2324// :99:30: note: when computing vector element at index '0'
2326// :99:30: error: use of undefined value here causes illegal behavior2325// :99:30: error: use of undefined value here causes illegal behavior
2327// :99:30: note: when computing vector element at index '0'2326// :99:30: note: when computing vector element at index '0'
2328// :99:30: error: use of undefined value here causes illegal behavior2327// :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'
2330// :99:30: error: use of undefined value here causes illegal behavior2329// :99:30: error: use of undefined value here causes illegal behavior
2331// :99:30: note: when computing vector element at index '0'2330// :99:30: note: when computing vector element at index '0'
2332// :99:30: error: use of undefined value here causes illegal behavior2331// :99:30: error: use of undefined value here causes illegal behavior
2333// :99:30: note: when computing vector element at index '0'2332// :99:30: note: when computing vector element at index '0'
2334// :99:30: error: use of undefined value here causes illegal behavior2333// :99:30: error: use of undefined value here causes illegal behavior
2334// :99:30: note: when computing vector element at index '1'
2335// :99:30: error: use of undefined value here causes illegal behavior2335// :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'
2337// :99:30: error: use of undefined value here causes illegal behavior2337// :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'
2339// :99:30: error: use of undefined value here causes illegal behavior2339// :99:30: error: use of undefined value here causes illegal behavior
2340// :99:30: note: when computing vector element at index '1'2340// :99:30: note: when computing vector element at index '1'
2341// :99:30: error: use of undefined value here causes illegal behavior2341// :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'
2343// :99:30: error: use of undefined value here causes illegal behavior2343// :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'
2345// :104:22: error: use of undefined value here causes illegal behavior2345// :104:22: error: use of undefined value here causes illegal behavior
2346// :104:22: error: use of undefined value here causes illegal behavior2346// :104:22: error: use of undefined value here causes illegal behavior
2347// :104:22: error: use of undefined value here causes illegal behavior2347// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2349,21 +2349,13 @@ const std = @import("std");...@@ -2349,21 +2349,13 @@ const std = @import("std");
2349// :104:22: error: use of undefined value here causes illegal behavior2349// :104:22: error: use of undefined value here causes illegal behavior
2350// :104:22: error: use of undefined value here causes illegal behavior2350// :104:22: error: use of undefined value here causes illegal behavior
2351// :104:22: error: use of undefined value here causes illegal behavior2351// :104:22: error: use of undefined value here causes illegal behavior
2352// :104:22: note: when computing vector element at index '1'
2353// :104:22: error: use of undefined value here causes illegal behavior2352// :104:22: error: use of undefined value here causes illegal behavior
2354// :104:22: note: when computing vector element at index '1'
2355// :104:22: error: use of undefined value here causes illegal behavior2353// :104:22: error: use of undefined value here causes illegal behavior
2356// :104:22: note: when computing vector element at index '1'
2357// :104:22: error: use of undefined value here causes illegal behavior2354// :104:22: error: use of undefined value here causes illegal behavior
2358// :104:22: note: when computing vector element at index '1'
2359// :104:22: error: use of undefined value here causes illegal behavior2355// :104:22: error: use of undefined value here causes illegal behavior
2360// :104:22: note: when computing vector element at index '0'
2361// :104:22: error: use of undefined value here causes illegal behavior2356// :104:22: error: use of undefined value here causes illegal behavior
2362// :104:22: note: when computing vector element at index '0'
2363// :104:22: error: use of undefined value here causes illegal behavior2357// :104:22: error: use of undefined value here causes illegal behavior
2364// :104:22: note: when computing vector element at index '0'
2365// :104:22: error: use of undefined value here causes illegal behavior2358// :104:22: error: use of undefined value here causes illegal behavior
2366// :104:22: note: when computing vector element at index '0'
2367// :104:22: error: use of undefined value here causes illegal behavior2359// :104:22: error: use of undefined value here causes illegal behavior
2368// :104:22: error: use of undefined value here causes illegal behavior2360// :104:22: error: use of undefined value here causes illegal behavior
2369// :104:22: error: use of undefined value here causes illegal behavior2361// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2371,21 +2363,13 @@ const std = @import("std");...@@ -2371,21 +2363,13 @@ const std = @import("std");
2371// :104:22: error: use of undefined value here causes illegal behavior2363// :104:22: error: use of undefined value here causes illegal behavior
2372// :104:22: error: use of undefined value here causes illegal behavior2364// :104:22: error: use of undefined value here causes illegal behavior
2373// :104:22: error: use of undefined value here causes illegal behavior2365// :104:22: error: use of undefined value here causes illegal behavior
2374// :104:22: note: when computing vector element at index '1'
2375// :104:22: error: use of undefined value here causes illegal behavior2366// :104:22: error: use of undefined value here causes illegal behavior
2376// :104:22: note: when computing vector element at index '1'
2377// :104:22: error: use of undefined value here causes illegal behavior2367// :104:22: error: use of undefined value here causes illegal behavior
2378// :104:22: note: when computing vector element at index '1'
2379// :104:22: error: use of undefined value here causes illegal behavior2368// :104:22: error: use of undefined value here causes illegal behavior
2380// :104:22: note: when computing vector element at index '1'
2381// :104:22: error: use of undefined value here causes illegal behavior2369// :104:22: error: use of undefined value here causes illegal behavior
2382// :104:22: note: when computing vector element at index '0'
2383// :104:22: error: use of undefined value here causes illegal behavior2370// :104:22: error: use of undefined value here causes illegal behavior
2384// :104:22: note: when computing vector element at index '0'
2385// :104:22: error: use of undefined value here causes illegal behavior2371// :104:22: error: use of undefined value here causes illegal behavior
2386// :104:22: note: when computing vector element at index '0'
2387// :104:22: error: use of undefined value here causes illegal behavior2372// :104:22: error: use of undefined value here causes illegal behavior
2388// :104:22: note: when computing vector element at index '0'
2389// :104:22: error: use of undefined value here causes illegal behavior2373// :104:22: error: use of undefined value here causes illegal behavior
2390// :104:22: error: use of undefined value here causes illegal behavior2374// :104:22: error: use of undefined value here causes illegal behavior
2391// :104:22: error: use of undefined value here causes illegal behavior2375// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2393,13 +2377,11 @@ const std = @import("std");...@@ -2393,13 +2377,11 @@ const std = @import("std");
2393// :104:22: error: use of undefined value here causes illegal behavior2377// :104:22: error: use of undefined value here causes illegal behavior
2394// :104:22: error: use of undefined value here causes illegal behavior2378// :104:22: error: use of undefined value here causes illegal behavior
2395// :104:22: error: use of undefined value here causes illegal behavior2379// :104:22: error: use of undefined value here causes illegal behavior
2396// :104:22: note: when computing vector element at index '1'
2397// :104:22: error: use of undefined value here causes illegal behavior2380// :104:22: error: use of undefined value here causes illegal behavior
2398// :104:22: note: when computing vector element at index '1'
2399// :104:22: error: use of undefined value here causes illegal behavior2381// :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'
2401// :104:22: error: use of undefined value here causes illegal behavior2383// :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'
2403// :104:22: error: use of undefined value here causes illegal behavior2385// :104:22: error: use of undefined value here causes illegal behavior
2404// :104:22: note: when computing vector element at index '0'2386// :104:22: note: when computing vector element at index '0'
2405// :104:22: error: use of undefined value here causes illegal behavior2387// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2409,19 +2391,25 @@ const std = @import("std");...@@ -2409,19 +2391,25 @@ const std = @import("std");
2409// :104:22: error: use of undefined value here causes illegal behavior2391// :104:22: error: use of undefined value here causes illegal behavior
2410// :104:22: note: when computing vector element at index '0'2392// :104:22: note: when computing vector element at index '0'
2411// :104:22: error: use of undefined value here causes illegal behavior2393// :104:22: error: use of undefined value here causes illegal behavior
2394// :104:22: note: when computing vector element at index '0'
2412// :104:22: error: use of undefined value here causes illegal behavior2395// :104:22: error: use of undefined value here causes illegal behavior
2396// :104:22: note: when computing vector element at index '0'
2413// :104:22: error: use of undefined value here causes illegal behavior2397// :104:22: error: use of undefined value here causes illegal behavior
2398// :104:22: note: when computing vector element at index '0'
2414// :104:22: error: use of undefined value here causes illegal behavior2399// :104:22: error: use of undefined value here causes illegal behavior
2400// :104:22: note: when computing vector element at index '0'
2415// :104:22: error: use of undefined value here causes illegal behavior2401// :104:22: error: use of undefined value here causes illegal behavior
2402// :104:22: note: when computing vector element at index '0'
2416// :104:22: error: use of undefined value here causes illegal behavior2403// :104:22: error: use of undefined value here causes illegal behavior
2404// :104:22: note: when computing vector element at index '0'
2417// :104:22: error: use of undefined value here causes illegal behavior2405// :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'
2419// :104:22: error: use of undefined value here causes illegal behavior2407// :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'
2421// :104:22: error: use of undefined value here causes illegal behavior2409// :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'
2423// :104:22: error: use of undefined value here causes illegal behavior2411// :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'
2425// :104:22: error: use of undefined value here causes illegal behavior2413// :104:22: error: use of undefined value here causes illegal behavior
2426// :104:22: note: when computing vector element at index '0'2414// :104:22: note: when computing vector element at index '0'
2427// :104:22: error: use of undefined value here causes illegal behavior2415// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2431,11 +2419,17 @@ const std = @import("std");...@@ -2431,11 +2419,17 @@ const std = @import("std");
2431// :104:22: error: use of undefined value here causes illegal behavior2419// :104:22: error: use of undefined value here causes illegal behavior
2432// :104:22: note: when computing vector element at index '0'2420// :104:22: note: when computing vector element at index '0'
2433// :104:22: error: use of undefined value here causes illegal behavior2421// :104:22: error: use of undefined value here causes illegal behavior
2422// :104:22: note: when computing vector element at index '0'
2434// :104:22: error: use of undefined value here causes illegal behavior2423// :104:22: error: use of undefined value here causes illegal behavior
2424// :104:22: note: when computing vector element at index '0'
2435// :104:22: error: use of undefined value here causes illegal behavior2425// :104:22: error: use of undefined value here causes illegal behavior
2426// :104:22: note: when computing vector element at index '0'
2436// :104:22: error: use of undefined value here causes illegal behavior2427// :104:22: error: use of undefined value here causes illegal behavior
2428// :104:22: note: when computing vector element at index '0'
2437// :104:22: error: use of undefined value here causes illegal behavior2429// :104:22: error: use of undefined value here causes illegal behavior
2430// :104:22: note: when computing vector element at index '1'
2438// :104:22: error: use of undefined value here causes illegal behavior2431// :104:22: error: use of undefined value here causes illegal behavior
2432// :104:22: note: when computing vector element at index '1'
2439// :104:22: error: use of undefined value here causes illegal behavior2433// :104:22: error: use of undefined value here causes illegal behavior
2440// :104:22: note: when computing vector element at index '1'2434// :104:22: note: when computing vector element at index '1'
2441// :104:22: error: use of undefined value here causes illegal behavior2435// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2445,19 +2439,25 @@ const std = @import("std");...@@ -2445,19 +2439,25 @@ const std = @import("std");
2445// :104:22: error: use of undefined value here causes illegal behavior2439// :104:22: error: use of undefined value here causes illegal behavior
2446// :104:22: note: when computing vector element at index '1'2440// :104:22: note: when computing vector element at index '1'
2447// :104:22: error: use of undefined value here causes illegal behavior2441// :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'
2449// :104:22: error: use of undefined value here causes illegal behavior2443// :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'
2451// :104:22: error: use of undefined value here causes illegal behavior2445// :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'
2453// :104:22: error: use of undefined value here causes illegal behavior2447// :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'
2455// :104:22: error: use of undefined value here causes illegal behavior2449// :104:22: error: use of undefined value here causes illegal behavior
2450// :104:22: note: when computing vector element at index '1'
2456// :104:22: error: use of undefined value here causes illegal behavior2451// :104:22: error: use of undefined value here causes illegal behavior
2452// :104:22: note: when computing vector element at index '1'
2457// :104:22: error: use of undefined value here causes illegal behavior2453// :104:22: error: use of undefined value here causes illegal behavior
2454// :104:22: note: when computing vector element at index '1'
2458// :104:22: error: use of undefined value here causes illegal behavior2455// :104:22: error: use of undefined value here causes illegal behavior
2456// :104:22: note: when computing vector element at index '1'
2459// :104:22: error: use of undefined value here causes illegal behavior2457// :104:22: error: use of undefined value here causes illegal behavior
2458// :104:22: note: when computing vector element at index '1'
2460// :104:22: error: use of undefined value here causes illegal behavior2459// :104:22: error: use of undefined value here causes illegal behavior
2460// :104:22: note: when computing vector element at index '1'
2461// :104:22: error: use of undefined value here causes illegal behavior2461// :104:22: error: use of undefined value here causes illegal behavior
2462// :104:22: note: when computing vector element at index '1'2462// :104:22: note: when computing vector element at index '1'
2463// :104:22: error: use of undefined value here causes illegal behavior2463// :104:22: error: use of undefined value here causes illegal behavior
...@@ -2467,13 +2467,13 @@ const std = @import("std");...@@ -2467,13 +2467,13 @@ const std = @import("std");
2467// :104:22: error: use of undefined value here causes illegal behavior2467// :104:22: error: use of undefined value here causes illegal behavior
2468// :104:22: note: when computing vector element at index '1'2468// :104:22: note: when computing vector element at index '1'
2469// :104:22: error: use of undefined value here causes illegal behavior2469// :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'
2471// :104:22: error: use of undefined value here causes illegal behavior2471// :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'
2473// :104:22: error: use of undefined value here causes illegal behavior2473// :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'
2475// :104:22: error: use of undefined value here causes illegal behavior2475// :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'
2477// :107:30: error: use of undefined value here causes illegal behavior2477// :107:30: error: use of undefined value here causes illegal behavior
2478// :107:30: error: use of undefined value here causes illegal behavior2478// :107:30: error: use of undefined value here causes illegal behavior
2479// :107:30: error: use of undefined value here causes illegal behavior2479// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2481,21 +2481,13 @@ const std = @import("std");...@@ -2481,21 +2481,13 @@ const std = @import("std");
2481// :107:30: error: use of undefined value here causes illegal behavior2481// :107:30: error: use of undefined value here causes illegal behavior
2482// :107:30: error: use of undefined value here causes illegal behavior2482// :107:30: error: use of undefined value here causes illegal behavior
2483// :107:30: error: use of undefined value here causes illegal behavior2483// :107:30: error: use of undefined value here causes illegal behavior
2484// :107:30: note: when computing vector element at index '1'
2485// :107:30: error: use of undefined value here causes illegal behavior2484// :107:30: error: use of undefined value here causes illegal behavior
2486// :107:30: note: when computing vector element at index '1'
2487// :107:30: error: use of undefined value here causes illegal behavior2485// :107:30: error: use of undefined value here causes illegal behavior
2488// :107:30: note: when computing vector element at index '1'
2489// :107:30: error: use of undefined value here causes illegal behavior2486// :107:30: error: use of undefined value here causes illegal behavior
2490// :107:30: note: when computing vector element at index '1'
2491// :107:30: error: use of undefined value here causes illegal behavior2487// :107:30: error: use of undefined value here causes illegal behavior
2492// :107:30: note: when computing vector element at index '0'
2493// :107:30: error: use of undefined value here causes illegal behavior2488// :107:30: error: use of undefined value here causes illegal behavior
2494// :107:30: note: when computing vector element at index '0'
2495// :107:30: error: use of undefined value here causes illegal behavior2489// :107:30: error: use of undefined value here causes illegal behavior
2496// :107:30: note: when computing vector element at index '0'
2497// :107:30: error: use of undefined value here causes illegal behavior2490// :107:30: error: use of undefined value here causes illegal behavior
2498// :107:30: note: when computing vector element at index '0'
2499// :107:30: error: use of undefined value here causes illegal behavior2491// :107:30: error: use of undefined value here causes illegal behavior
2500// :107:30: error: use of undefined value here causes illegal behavior2492// :107:30: error: use of undefined value here causes illegal behavior
2501// :107:30: error: use of undefined value here causes illegal behavior2493// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2503,21 +2495,13 @@ const std = @import("std");...@@ -2503,21 +2495,13 @@ const std = @import("std");
2503// :107:30: error: use of undefined value here causes illegal behavior2495// :107:30: error: use of undefined value here causes illegal behavior
2504// :107:30: error: use of undefined value here causes illegal behavior2496// :107:30: error: use of undefined value here causes illegal behavior
2505// :107:30: error: use of undefined value here causes illegal behavior2497// :107:30: error: use of undefined value here causes illegal behavior
2506// :107:30: note: when computing vector element at index '1'
2507// :107:30: error: use of undefined value here causes illegal behavior2498// :107:30: error: use of undefined value here causes illegal behavior
2508// :107:30: note: when computing vector element at index '1'
2509// :107:30: error: use of undefined value here causes illegal behavior2499// :107:30: error: use of undefined value here causes illegal behavior
2510// :107:30: note: when computing vector element at index '1'
2511// :107:30: error: use of undefined value here causes illegal behavior2500// :107:30: error: use of undefined value here causes illegal behavior
2512// :107:30: note: when computing vector element at index '1'
2513// :107:30: error: use of undefined value here causes illegal behavior2501// :107:30: error: use of undefined value here causes illegal behavior
2514// :107:30: note: when computing vector element at index '0'
2515// :107:30: error: use of undefined value here causes illegal behavior2502// :107:30: error: use of undefined value here causes illegal behavior
2516// :107:30: note: when computing vector element at index '0'
2517// :107:30: error: use of undefined value here causes illegal behavior2503// :107:30: error: use of undefined value here causes illegal behavior
2518// :107:30: note: when computing vector element at index '0'
2519// :107:30: error: use of undefined value here causes illegal behavior2504// :107:30: error: use of undefined value here causes illegal behavior
2520// :107:30: note: when computing vector element at index '0'
2521// :107:30: error: use of undefined value here causes illegal behavior2505// :107:30: error: use of undefined value here causes illegal behavior
2522// :107:30: error: use of undefined value here causes illegal behavior2506// :107:30: error: use of undefined value here causes illegal behavior
2523// :107:30: error: use of undefined value here causes illegal behavior2507// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2525,13 +2509,11 @@ const std = @import("std");...@@ -2525,13 +2509,11 @@ const std = @import("std");
2525// :107:30: error: use of undefined value here causes illegal behavior2509// :107:30: error: use of undefined value here causes illegal behavior
2526// :107:30: error: use of undefined value here causes illegal behavior2510// :107:30: error: use of undefined value here causes illegal behavior
2527// :107:30: error: use of undefined value here causes illegal behavior2511// :107:30: error: use of undefined value here causes illegal behavior
2528// :107:30: note: when computing vector element at index '1'
2529// :107:30: error: use of undefined value here causes illegal behavior2512// :107:30: error: use of undefined value here causes illegal behavior
2530// :107:30: note: when computing vector element at index '1'
2531// :107:30: error: use of undefined value here causes illegal behavior2513// :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'
2533// :107:30: error: use of undefined value here causes illegal behavior2515// :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'
2535// :107:30: error: use of undefined value here causes illegal behavior2517// :107:30: error: use of undefined value here causes illegal behavior
2536// :107:30: note: when computing vector element at index '0'2518// :107:30: note: when computing vector element at index '0'
2537// :107:30: error: use of undefined value here causes illegal behavior2519// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2541,19 +2523,25 @@ const std = @import("std");...@@ -2541,19 +2523,25 @@ const std = @import("std");
2541// :107:30: error: use of undefined value here causes illegal behavior2523// :107:30: error: use of undefined value here causes illegal behavior
2542// :107:30: note: when computing vector element at index '0'2524// :107:30: note: when computing vector element at index '0'
2543// :107:30: error: use of undefined value here causes illegal behavior2525// :107:30: error: use of undefined value here causes illegal behavior
2526// :107:30: note: when computing vector element at index '0'
2544// :107:30: error: use of undefined value here causes illegal behavior2527// :107:30: error: use of undefined value here causes illegal behavior
2528// :107:30: note: when computing vector element at index '0'
2545// :107:30: error: use of undefined value here causes illegal behavior2529// :107:30: error: use of undefined value here causes illegal behavior
2530// :107:30: note: when computing vector element at index '0'
2546// :107:30: error: use of undefined value here causes illegal behavior2531// :107:30: error: use of undefined value here causes illegal behavior
2532// :107:30: note: when computing vector element at index '0'
2547// :107:30: error: use of undefined value here causes illegal behavior2533// :107:30: error: use of undefined value here causes illegal behavior
2534// :107:30: note: when computing vector element at index '0'
2548// :107:30: error: use of undefined value here causes illegal behavior2535// :107:30: error: use of undefined value here causes illegal behavior
2536// :107:30: note: when computing vector element at index '0'
2549// :107:30: error: use of undefined value here causes illegal behavior2537// :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'
2551// :107:30: error: use of undefined value here causes illegal behavior2539// :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'
2553// :107:30: error: use of undefined value here causes illegal behavior2541// :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'
2555// :107:30: error: use of undefined value here causes illegal behavior2543// :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'
2557// :107:30: error: use of undefined value here causes illegal behavior2545// :107:30: error: use of undefined value here causes illegal behavior
2558// :107:30: note: when computing vector element at index '0'2546// :107:30: note: when computing vector element at index '0'
2559// :107:30: error: use of undefined value here causes illegal behavior2547// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2563,11 +2551,17 @@ const std = @import("std");...@@ -2563,11 +2551,17 @@ const std = @import("std");
2563// :107:30: error: use of undefined value here causes illegal behavior2551// :107:30: error: use of undefined value here causes illegal behavior
2564// :107:30: note: when computing vector element at index '0'2552// :107:30: note: when computing vector element at index '0'
2565// :107:30: error: use of undefined value here causes illegal behavior2553// :107:30: error: use of undefined value here causes illegal behavior
2554// :107:30: note: when computing vector element at index '0'
2566// :107:30: error: use of undefined value here causes illegal behavior2555// :107:30: error: use of undefined value here causes illegal behavior
2556// :107:30: note: when computing vector element at index '0'
2567// :107:30: error: use of undefined value here causes illegal behavior2557// :107:30: error: use of undefined value here causes illegal behavior
2558// :107:30: note: when computing vector element at index '0'
2568// :107:30: error: use of undefined value here causes illegal behavior2559// :107:30: error: use of undefined value here causes illegal behavior
2560// :107:30: note: when computing vector element at index '0'
2569// :107:30: error: use of undefined value here causes illegal behavior2561// :107:30: error: use of undefined value here causes illegal behavior
2562// :107:30: note: when computing vector element at index '1'
2570// :107:30: error: use of undefined value here causes illegal behavior2563// :107:30: error: use of undefined value here causes illegal behavior
2564// :107:30: note: when computing vector element at index '1'
2571// :107:30: error: use of undefined value here causes illegal behavior2565// :107:30: error: use of undefined value here causes illegal behavior
2572// :107:30: note: when computing vector element at index '1'2566// :107:30: note: when computing vector element at index '1'
2573// :107:30: error: use of undefined value here causes illegal behavior2567// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2577,19 +2571,25 @@ const std = @import("std");...@@ -2577,19 +2571,25 @@ const std = @import("std");
2577// :107:30: error: use of undefined value here causes illegal behavior2571// :107:30: error: use of undefined value here causes illegal behavior
2578// :107:30: note: when computing vector element at index '1'2572// :107:30: note: when computing vector element at index '1'
2579// :107:30: error: use of undefined value here causes illegal behavior2573// :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'
2581// :107:30: error: use of undefined value here causes illegal behavior2575// :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'
2583// :107:30: error: use of undefined value here causes illegal behavior2577// :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'
2585// :107:30: error: use of undefined value here causes illegal behavior2579// :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'
2587// :107:30: error: use of undefined value here causes illegal behavior2581// :107:30: error: use of undefined value here causes illegal behavior
2582// :107:30: note: when computing vector element at index '1'
2588// :107:30: error: use of undefined value here causes illegal behavior2583// :107:30: error: use of undefined value here causes illegal behavior
2584// :107:30: note: when computing vector element at index '1'
2589// :107:30: error: use of undefined value here causes illegal behavior2585// :107:30: error: use of undefined value here causes illegal behavior
2586// :107:30: note: when computing vector element at index '1'
2590// :107:30: error: use of undefined value here causes illegal behavior2587// :107:30: error: use of undefined value here causes illegal behavior
2588// :107:30: note: when computing vector element at index '1'
2591// :107:30: error: use of undefined value here causes illegal behavior2589// :107:30: error: use of undefined value here causes illegal behavior
2590// :107:30: note: when computing vector element at index '1'
2592// :107:30: error: use of undefined value here causes illegal behavior2591// :107:30: error: use of undefined value here causes illegal behavior
2592// :107:30: note: when computing vector element at index '1'
2593// :107:30: error: use of undefined value here causes illegal behavior2593// :107:30: error: use of undefined value here causes illegal behavior
2594// :107:30: note: when computing vector element at index '1'2594// :107:30: note: when computing vector element at index '1'
2595// :107:30: error: use of undefined value here causes illegal behavior2595// :107:30: error: use of undefined value here causes illegal behavior
...@@ -2599,13 +2599,13 @@ const std = @import("std");...@@ -2599,13 +2599,13 @@ const std = @import("std");
2599// :107:30: error: use of undefined value here causes illegal behavior2599// :107:30: error: use of undefined value here causes illegal behavior
2600// :107:30: note: when computing vector element at index '1'2600// :107:30: note: when computing vector element at index '1'
2601// :107:30: error: use of undefined value here causes illegal behavior2601// :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'
2603// :107:30: error: use of undefined value here causes illegal behavior2603// :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'
2605// :107:30: error: use of undefined value here causes illegal behavior2605// :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'
2607// :107:30: error: use of undefined value here causes illegal behavior2607// :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'
2609// :110:37: error: use of undefined value here causes illegal behavior2609// :110:37: error: use of undefined value here causes illegal behavior
2610// :110:37: error: use of undefined value here causes illegal behavior2610// :110:37: error: use of undefined value here causes illegal behavior
2611// :110:37: error: use of undefined value here causes illegal behavior2611// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2613,21 +2613,13 @@ const std = @import("std");...@@ -2613,21 +2613,13 @@ const std = @import("std");
2613// :110:37: error: use of undefined value here causes illegal behavior2613// :110:37: error: use of undefined value here causes illegal behavior
2614// :110:37: error: use of undefined value here causes illegal behavior2614// :110:37: error: use of undefined value here causes illegal behavior
2615// :110:37: error: use of undefined value here causes illegal behavior2615// :110:37: error: use of undefined value here causes illegal behavior
2616// :110:37: note: when computing vector element at index '1'
2617// :110:37: error: use of undefined value here causes illegal behavior2616// :110:37: error: use of undefined value here causes illegal behavior
2618// :110:37: note: when computing vector element at index '1'
2619// :110:37: error: use of undefined value here causes illegal behavior2617// :110:37: error: use of undefined value here causes illegal behavior
2620// :110:37: note: when computing vector element at index '1'
2621// :110:37: error: use of undefined value here causes illegal behavior2618// :110:37: error: use of undefined value here causes illegal behavior
2622// :110:37: note: when computing vector element at index '1'
2623// :110:37: error: use of undefined value here causes illegal behavior2619// :110:37: error: use of undefined value here causes illegal behavior
2624// :110:37: note: when computing vector element at index '0'
2625// :110:37: error: use of undefined value here causes illegal behavior2620// :110:37: error: use of undefined value here causes illegal behavior
2626// :110:37: note: when computing vector element at index '0'
2627// :110:37: error: use of undefined value here causes illegal behavior2621// :110:37: error: use of undefined value here causes illegal behavior
2628// :110:37: note: when computing vector element at index '0'
2629// :110:37: error: use of undefined value here causes illegal behavior2622// :110:37: error: use of undefined value here causes illegal behavior
2630// :110:37: note: when computing vector element at index '0'
2631// :110:37: error: use of undefined value here causes illegal behavior2623// :110:37: error: use of undefined value here causes illegal behavior
2632// :110:37: error: use of undefined value here causes illegal behavior2624// :110:37: error: use of undefined value here causes illegal behavior
2633// :110:37: error: use of undefined value here causes illegal behavior2625// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2635,21 +2627,13 @@ const std = @import("std");...@@ -2635,21 +2627,13 @@ const std = @import("std");
2635// :110:37: error: use of undefined value here causes illegal behavior2627// :110:37: error: use of undefined value here causes illegal behavior
2636// :110:37: error: use of undefined value here causes illegal behavior2628// :110:37: error: use of undefined value here causes illegal behavior
2637// :110:37: error: use of undefined value here causes illegal behavior2629// :110:37: error: use of undefined value here causes illegal behavior
2638// :110:37: note: when computing vector element at index '1'
2639// :110:37: error: use of undefined value here causes illegal behavior2630// :110:37: error: use of undefined value here causes illegal behavior
2640// :110:37: note: when computing vector element at index '1'
2641// :110:37: error: use of undefined value here causes illegal behavior2631// :110:37: error: use of undefined value here causes illegal behavior
2642// :110:37: note: when computing vector element at index '1'
2643// :110:37: error: use of undefined value here causes illegal behavior2632// :110:37: error: use of undefined value here causes illegal behavior
2644// :110:37: note: when computing vector element at index '1'
2645// :110:37: error: use of undefined value here causes illegal behavior2633// :110:37: error: use of undefined value here causes illegal behavior
2646// :110:37: note: when computing vector element at index '0'
2647// :110:37: error: use of undefined value here causes illegal behavior2634// :110:37: error: use of undefined value here causes illegal behavior
2648// :110:37: note: when computing vector element at index '0'
2649// :110:37: error: use of undefined value here causes illegal behavior2635// :110:37: error: use of undefined value here causes illegal behavior
2650// :110:37: note: when computing vector element at index '0'
2651// :110:37: error: use of undefined value here causes illegal behavior2636// :110:37: error: use of undefined value here causes illegal behavior
2652// :110:37: note: when computing vector element at index '0'
2653// :110:37: error: use of undefined value here causes illegal behavior2637// :110:37: error: use of undefined value here causes illegal behavior
2654// :110:37: error: use of undefined value here causes illegal behavior2638// :110:37: error: use of undefined value here causes illegal behavior
2655// :110:37: error: use of undefined value here causes illegal behavior2639// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2657,13 +2641,11 @@ const std = @import("std");...@@ -2657,13 +2641,11 @@ const std = @import("std");
2657// :110:37: error: use of undefined value here causes illegal behavior2641// :110:37: error: use of undefined value here causes illegal behavior
2658// :110:37: error: use of undefined value here causes illegal behavior2642// :110:37: error: use of undefined value here causes illegal behavior
2659// :110:37: error: use of undefined value here causes illegal behavior2643// :110:37: error: use of undefined value here causes illegal behavior
2660// :110:37: note: when computing vector element at index '1'
2661// :110:37: error: use of undefined value here causes illegal behavior2644// :110:37: error: use of undefined value here causes illegal behavior
2662// :110:37: note: when computing vector element at index '1'
2663// :110:37: error: use of undefined value here causes illegal behavior2645// :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'
2665// :110:37: error: use of undefined value here causes illegal behavior2647// :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'
2667// :110:37: error: use of undefined value here causes illegal behavior2649// :110:37: error: use of undefined value here causes illegal behavior
2668// :110:37: note: when computing vector element at index '0'2650// :110:37: note: when computing vector element at index '0'
2669// :110:37: error: use of undefined value here causes illegal behavior2651// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2673,19 +2655,25 @@ const std = @import("std");...@@ -2673,19 +2655,25 @@ const std = @import("std");
2673// :110:37: error: use of undefined value here causes illegal behavior2655// :110:37: error: use of undefined value here causes illegal behavior
2674// :110:37: note: when computing vector element at index '0'2656// :110:37: note: when computing vector element at index '0'
2675// :110:37: error: use of undefined value here causes illegal behavior2657// :110:37: error: use of undefined value here causes illegal behavior
2658// :110:37: note: when computing vector element at index '0'
2676// :110:37: error: use of undefined value here causes illegal behavior2659// :110:37: error: use of undefined value here causes illegal behavior
2660// :110:37: note: when computing vector element at index '0'
2677// :110:37: error: use of undefined value here causes illegal behavior2661// :110:37: error: use of undefined value here causes illegal behavior
2662// :110:37: note: when computing vector element at index '0'
2678// :110:37: error: use of undefined value here causes illegal behavior2663// :110:37: error: use of undefined value here causes illegal behavior
2664// :110:37: note: when computing vector element at index '0'
2679// :110:37: error: use of undefined value here causes illegal behavior2665// :110:37: error: use of undefined value here causes illegal behavior
2666// :110:37: note: when computing vector element at index '0'
2680// :110:37: error: use of undefined value here causes illegal behavior2667// :110:37: error: use of undefined value here causes illegal behavior
2668// :110:37: note: when computing vector element at index '0'
2681// :110:37: error: use of undefined value here causes illegal behavior2669// :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'
2683// :110:37: error: use of undefined value here causes illegal behavior2671// :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'
2685// :110:37: error: use of undefined value here causes illegal behavior2673// :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'
2687// :110:37: error: use of undefined value here causes illegal behavior2675// :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'
2689// :110:37: error: use of undefined value here causes illegal behavior2677// :110:37: error: use of undefined value here causes illegal behavior
2690// :110:37: note: when computing vector element at index '0'2678// :110:37: note: when computing vector element at index '0'
2691// :110:37: error: use of undefined value here causes illegal behavior2679// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2695,11 +2683,17 @@ const std = @import("std");...@@ -2695,11 +2683,17 @@ const std = @import("std");
2695// :110:37: error: use of undefined value here causes illegal behavior2683// :110:37: error: use of undefined value here causes illegal behavior
2696// :110:37: note: when computing vector element at index '0'2684// :110:37: note: when computing vector element at index '0'
2697// :110:37: error: use of undefined value here causes illegal behavior2685// :110:37: error: use of undefined value here causes illegal behavior
2686// :110:37: note: when computing vector element at index '0'
2698// :110:37: error: use of undefined value here causes illegal behavior2687// :110:37: error: use of undefined value here causes illegal behavior
2688// :110:37: note: when computing vector element at index '0'
2699// :110:37: error: use of undefined value here causes illegal behavior2689// :110:37: error: use of undefined value here causes illegal behavior
2690// :110:37: note: when computing vector element at index '0'
2700// :110:37: error: use of undefined value here causes illegal behavior2691// :110:37: error: use of undefined value here causes illegal behavior
2692// :110:37: note: when computing vector element at index '0'
2701// :110:37: error: use of undefined value here causes illegal behavior2693// :110:37: error: use of undefined value here causes illegal behavior
2694// :110:37: note: when computing vector element at index '1'
2702// :110:37: error: use of undefined value here causes illegal behavior2695// :110:37: error: use of undefined value here causes illegal behavior
2696// :110:37: note: when computing vector element at index '1'
2703// :110:37: error: use of undefined value here causes illegal behavior2697// :110:37: error: use of undefined value here causes illegal behavior
2704// :110:37: note: when computing vector element at index '1'2698// :110:37: note: when computing vector element at index '1'
2705// :110:37: error: use of undefined value here causes illegal behavior2699// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2709,19 +2703,25 @@ const std = @import("std");...@@ -2709,19 +2703,25 @@ const std = @import("std");
2709// :110:37: error: use of undefined value here causes illegal behavior2703// :110:37: error: use of undefined value here causes illegal behavior
2710// :110:37: note: when computing vector element at index '1'2704// :110:37: note: when computing vector element at index '1'
2711// :110:37: error: use of undefined value here causes illegal behavior2705// :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'
2713// :110:37: error: use of undefined value here causes illegal behavior2707// :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'
2715// :110:37: error: use of undefined value here causes illegal behavior2709// :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'
2717// :110:37: error: use of undefined value here causes illegal behavior2711// :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'
2719// :110:37: error: use of undefined value here causes illegal behavior2713// :110:37: error: use of undefined value here causes illegal behavior
2714// :110:37: note: when computing vector element at index '1'
2720// :110:37: error: use of undefined value here causes illegal behavior2715// :110:37: error: use of undefined value here causes illegal behavior
2716// :110:37: note: when computing vector element at index '1'
2721// :110:37: error: use of undefined value here causes illegal behavior2717// :110:37: error: use of undefined value here causes illegal behavior
2718// :110:37: note: when computing vector element at index '1'
2722// :110:37: error: use of undefined value here causes illegal behavior2719// :110:37: error: use of undefined value here causes illegal behavior
2720// :110:37: note: when computing vector element at index '1'
2723// :110:37: error: use of undefined value here causes illegal behavior2721// :110:37: error: use of undefined value here causes illegal behavior
2722// :110:37: note: when computing vector element at index '1'
2724// :110:37: error: use of undefined value here causes illegal behavior2723// :110:37: error: use of undefined value here causes illegal behavior
2724// :110:37: note: when computing vector element at index '1'
2725// :110:37: error: use of undefined value here causes illegal behavior2725// :110:37: error: use of undefined value here causes illegal behavior
2726// :110:37: note: when computing vector element at index '1'2726// :110:37: note: when computing vector element at index '1'
2727// :110:37: error: use of undefined value here causes illegal behavior2727// :110:37: error: use of undefined value here causes illegal behavior
...@@ -2731,13 +2731,13 @@ const std = @import("std");...@@ -2731,13 +2731,13 @@ const std = @import("std");
2731// :110:37: error: use of undefined value here causes illegal behavior2731// :110:37: error: use of undefined value here causes illegal behavior
2732// :110:37: note: when computing vector element at index '1'2732// :110:37: note: when computing vector element at index '1'
2733// :110:37: error: use of undefined value here causes illegal behavior2733// :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'
2735// :110:37: error: use of undefined value here causes illegal behavior2735// :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'
2737// :110:37: error: use of undefined value here causes illegal behavior2737// :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'
2739// :110:37: error: use of undefined value here causes illegal behavior2739// :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'
2741// :113:22: error: use of undefined value here causes illegal behavior2741// :113:22: error: use of undefined value here causes illegal behavior
2742// :113:22: error: use of undefined value here causes illegal behavior2742// :113:22: error: use of undefined value here causes illegal behavior
2743// :113:22: error: use of undefined value here causes illegal behavior2743// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2745,21 +2745,13 @@ const std = @import("std");...@@ -2745,21 +2745,13 @@ const std = @import("std");
2745// :113:22: error: use of undefined value here causes illegal behavior2745// :113:22: error: use of undefined value here causes illegal behavior
2746// :113:22: error: use of undefined value here causes illegal behavior2746// :113:22: error: use of undefined value here causes illegal behavior
2747// :113:22: error: use of undefined value here causes illegal behavior2747// :113:22: error: use of undefined value here causes illegal behavior
2748// :113:22: note: when computing vector element at index '1'
2749// :113:22: error: use of undefined value here causes illegal behavior2748// :113:22: error: use of undefined value here causes illegal behavior
2750// :113:22: note: when computing vector element at index '1'
2751// :113:22: error: use of undefined value here causes illegal behavior2749// :113:22: error: use of undefined value here causes illegal behavior
2752// :113:22: note: when computing vector element at index '1'
2753// :113:22: error: use of undefined value here causes illegal behavior2750// :113:22: error: use of undefined value here causes illegal behavior
2754// :113:22: note: when computing vector element at index '1'
2755// :113:22: error: use of undefined value here causes illegal behavior2751// :113:22: error: use of undefined value here causes illegal behavior
2756// :113:22: note: when computing vector element at index '0'
2757// :113:22: error: use of undefined value here causes illegal behavior2752// :113:22: error: use of undefined value here causes illegal behavior
2758// :113:22: note: when computing vector element at index '0'
2759// :113:22: error: use of undefined value here causes illegal behavior2753// :113:22: error: use of undefined value here causes illegal behavior
2760// :113:22: note: when computing vector element at index '0'
2761// :113:22: error: use of undefined value here causes illegal behavior2754// :113:22: error: use of undefined value here causes illegal behavior
2762// :113:22: note: when computing vector element at index '0'
2763// :113:22: error: use of undefined value here causes illegal behavior2755// :113:22: error: use of undefined value here causes illegal behavior
2764// :113:22: error: use of undefined value here causes illegal behavior2756// :113:22: error: use of undefined value here causes illegal behavior
2765// :113:22: error: use of undefined value here causes illegal behavior2757// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2767,21 +2759,13 @@ const std = @import("std");...@@ -2767,21 +2759,13 @@ const std = @import("std");
2767// :113:22: error: use of undefined value here causes illegal behavior2759// :113:22: error: use of undefined value here causes illegal behavior
2768// :113:22: error: use of undefined value here causes illegal behavior2760// :113:22: error: use of undefined value here causes illegal behavior
2769// :113:22: error: use of undefined value here causes illegal behavior2761// :113:22: error: use of undefined value here causes illegal behavior
2770// :113:22: note: when computing vector element at index '1'
2771// :113:22: error: use of undefined value here causes illegal behavior2762// :113:22: error: use of undefined value here causes illegal behavior
2772// :113:22: note: when computing vector element at index '1'
2773// :113:22: error: use of undefined value here causes illegal behavior2763// :113:22: error: use of undefined value here causes illegal behavior
2774// :113:22: note: when computing vector element at index '1'
2775// :113:22: error: use of undefined value here causes illegal behavior2764// :113:22: error: use of undefined value here causes illegal behavior
2776// :113:22: note: when computing vector element at index '1'
2777// :113:22: error: use of undefined value here causes illegal behavior2765// :113:22: error: use of undefined value here causes illegal behavior
2778// :113:22: note: when computing vector element at index '0'
2779// :113:22: error: use of undefined value here causes illegal behavior2766// :113:22: error: use of undefined value here causes illegal behavior
2780// :113:22: note: when computing vector element at index '0'
2781// :113:22: error: use of undefined value here causes illegal behavior2767// :113:22: error: use of undefined value here causes illegal behavior
2782// :113:22: note: when computing vector element at index '0'
2783// :113:22: error: use of undefined value here causes illegal behavior2768// :113:22: error: use of undefined value here causes illegal behavior
2784// :113:22: note: when computing vector element at index '0'
2785// :113:22: error: use of undefined value here causes illegal behavior2769// :113:22: error: use of undefined value here causes illegal behavior
2786// :113:22: error: use of undefined value here causes illegal behavior2770// :113:22: error: use of undefined value here causes illegal behavior
2787// :113:22: error: use of undefined value here causes illegal behavior2771// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2789,13 +2773,11 @@ const std = @import("std");...@@ -2789,13 +2773,11 @@ const std = @import("std");
2789// :113:22: error: use of undefined value here causes illegal behavior2773// :113:22: error: use of undefined value here causes illegal behavior
2790// :113:22: error: use of undefined value here causes illegal behavior2774// :113:22: error: use of undefined value here causes illegal behavior
2791// :113:22: error: use of undefined value here causes illegal behavior2775// :113:22: error: use of undefined value here causes illegal behavior
2792// :113:22: note: when computing vector element at index '1'
2793// :113:22: error: use of undefined value here causes illegal behavior2776// :113:22: error: use of undefined value here causes illegal behavior
2794// :113:22: note: when computing vector element at index '1'
2795// :113:22: error: use of undefined value here causes illegal behavior2777// :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'
2797// :113:22: error: use of undefined value here causes illegal behavior2779// :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'
2799// :113:22: error: use of undefined value here causes illegal behavior2781// :113:22: error: use of undefined value here causes illegal behavior
2800// :113:22: note: when computing vector element at index '0'2782// :113:22: note: when computing vector element at index '0'
2801// :113:22: error: use of undefined value here causes illegal behavior2783// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2805,19 +2787,25 @@ const std = @import("std");...@@ -2805,19 +2787,25 @@ const std = @import("std");
2805// :113:22: error: use of undefined value here causes illegal behavior2787// :113:22: error: use of undefined value here causes illegal behavior
2806// :113:22: note: when computing vector element at index '0'2788// :113:22: note: when computing vector element at index '0'
2807// :113:22: error: use of undefined value here causes illegal behavior2789// :113:22: error: use of undefined value here causes illegal behavior
2790// :113:22: note: when computing vector element at index '0'
2808// :113:22: error: use of undefined value here causes illegal behavior2791// :113:22: error: use of undefined value here causes illegal behavior
2792// :113:22: note: when computing vector element at index '0'
2809// :113:22: error: use of undefined value here causes illegal behavior2793// :113:22: error: use of undefined value here causes illegal behavior
2794// :113:22: note: when computing vector element at index '0'
2810// :113:22: error: use of undefined value here causes illegal behavior2795// :113:22: error: use of undefined value here causes illegal behavior
2796// :113:22: note: when computing vector element at index '0'
2811// :113:22: error: use of undefined value here causes illegal behavior2797// :113:22: error: use of undefined value here causes illegal behavior
2798// :113:22: note: when computing vector element at index '0'
2812// :113:22: error: use of undefined value here causes illegal behavior2799// :113:22: error: use of undefined value here causes illegal behavior
2800// :113:22: note: when computing vector element at index '0'
2813// :113:22: error: use of undefined value here causes illegal behavior2801// :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'
2815// :113:22: error: use of undefined value here causes illegal behavior2803// :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'
2817// :113:22: error: use of undefined value here causes illegal behavior2805// :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'
2819// :113:22: error: use of undefined value here causes illegal behavior2807// :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'
2821// :113:22: error: use of undefined value here causes illegal behavior2809// :113:22: error: use of undefined value here causes illegal behavior
2822// :113:22: note: when computing vector element at index '0'2810// :113:22: note: when computing vector element at index '0'
2823// :113:22: error: use of undefined value here causes illegal behavior2811// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2827,11 +2815,17 @@ const std = @import("std");...@@ -2827,11 +2815,17 @@ const std = @import("std");
2827// :113:22: error: use of undefined value here causes illegal behavior2815// :113:22: error: use of undefined value here causes illegal behavior
2828// :113:22: note: when computing vector element at index '0'2816// :113:22: note: when computing vector element at index '0'
2829// :113:22: error: use of undefined value here causes illegal behavior2817// :113:22: error: use of undefined value here causes illegal behavior
2818// :113:22: note: when computing vector element at index '0'
2830// :113:22: error: use of undefined value here causes illegal behavior2819// :113:22: error: use of undefined value here causes illegal behavior
2820// :113:22: note: when computing vector element at index '0'
2831// :113:22: error: use of undefined value here causes illegal behavior2821// :113:22: error: use of undefined value here causes illegal behavior
2822// :113:22: note: when computing vector element at index '0'
2832// :113:22: error: use of undefined value here causes illegal behavior2823// :113:22: error: use of undefined value here causes illegal behavior
2824// :113:22: note: when computing vector element at index '0'
2833// :113:22: error: use of undefined value here causes illegal behavior2825// :113:22: error: use of undefined value here causes illegal behavior
2826// :113:22: note: when computing vector element at index '1'
2834// :113:22: error: use of undefined value here causes illegal behavior2827// :113:22: error: use of undefined value here causes illegal behavior
2828// :113:22: note: when computing vector element at index '1'
2835// :113:22: error: use of undefined value here causes illegal behavior2829// :113:22: error: use of undefined value here causes illegal behavior
2836// :113:22: note: when computing vector element at index '1'2830// :113:22: note: when computing vector element at index '1'
2837// :113:22: error: use of undefined value here causes illegal behavior2831// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2841,19 +2835,25 @@ const std = @import("std");...@@ -2841,19 +2835,25 @@ const std = @import("std");
2841// :113:22: error: use of undefined value here causes illegal behavior2835// :113:22: error: use of undefined value here causes illegal behavior
2842// :113:22: note: when computing vector element at index '1'2836// :113:22: note: when computing vector element at index '1'
2843// :113:22: error: use of undefined value here causes illegal behavior2837// :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'
2845// :113:22: error: use of undefined value here causes illegal behavior2839// :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'
2847// :113:22: error: use of undefined value here causes illegal behavior2841// :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'
2849// :113:22: error: use of undefined value here causes illegal behavior2843// :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'
2851// :113:22: error: use of undefined value here causes illegal behavior2845// :113:22: error: use of undefined value here causes illegal behavior
2846// :113:22: note: when computing vector element at index '1'
2852// :113:22: error: use of undefined value here causes illegal behavior2847// :113:22: error: use of undefined value here causes illegal behavior
2848// :113:22: note: when computing vector element at index '1'
2853// :113:22: error: use of undefined value here causes illegal behavior2849// :113:22: error: use of undefined value here causes illegal behavior
2850// :113:22: note: when computing vector element at index '1'
2854// :113:22: error: use of undefined value here causes illegal behavior2851// :113:22: error: use of undefined value here causes illegal behavior
2852// :113:22: note: when computing vector element at index '1'
2855// :113:22: error: use of undefined value here causes illegal behavior2853// :113:22: error: use of undefined value here causes illegal behavior
2854// :113:22: note: when computing vector element at index '1'
2856// :113:22: error: use of undefined value here causes illegal behavior2855// :113:22: error: use of undefined value here causes illegal behavior
2856// :113:22: note: when computing vector element at index '1'
2857// :113:22: error: use of undefined value here causes illegal behavior2857// :113:22: error: use of undefined value here causes illegal behavior
2858// :113:22: note: when computing vector element at index '1'2858// :113:22: note: when computing vector element at index '1'
2859// :113:22: error: use of undefined value here causes illegal behavior2859// :113:22: error: use of undefined value here causes illegal behavior
...@@ -2863,13 +2863,13 @@ const std = @import("std");...@@ -2863,13 +2863,13 @@ const std = @import("std");
2863// :113:22: error: use of undefined value here causes illegal behavior2863// :113:22: error: use of undefined value here causes illegal behavior
2864// :113:22: note: when computing vector element at index '1'2864// :113:22: note: when computing vector element at index '1'
2865// :113:22: error: use of undefined value here causes illegal behavior2865// :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'
2867// :113:22: error: use of undefined value here causes illegal behavior2867// :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'
2869// :113:22: error: use of undefined value here causes illegal behavior2869// :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'
2871// :113:22: error: use of undefined value here causes illegal behavior2871// :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'
2873// :116:30: error: use of undefined value here causes illegal behavior2873// :116:30: error: use of undefined value here causes illegal behavior
2874// :116:30: error: use of undefined value here causes illegal behavior2874// :116:30: error: use of undefined value here causes illegal behavior
2875// :116:30: error: use of undefined value here causes illegal behavior2875// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2877,21 +2877,13 @@ const std = @import("std");...@@ -2877,21 +2877,13 @@ const std = @import("std");
2877// :116:30: error: use of undefined value here causes illegal behavior2877// :116:30: error: use of undefined value here causes illegal behavior
2878// :116:30: error: use of undefined value here causes illegal behavior2878// :116:30: error: use of undefined value here causes illegal behavior
2879// :116:30: error: use of undefined value here causes illegal behavior2879// :116:30: error: use of undefined value here causes illegal behavior
2880// :116:30: note: when computing vector element at index '1'
2881// :116:30: error: use of undefined value here causes illegal behavior2880// :116:30: error: use of undefined value here causes illegal behavior
2882// :116:30: note: when computing vector element at index '1'
2883// :116:30: error: use of undefined value here causes illegal behavior2881// :116:30: error: use of undefined value here causes illegal behavior
2884// :116:30: note: when computing vector element at index '1'
2885// :116:30: error: use of undefined value here causes illegal behavior2882// :116:30: error: use of undefined value here causes illegal behavior
2886// :116:30: note: when computing vector element at index '1'
2887// :116:30: error: use of undefined value here causes illegal behavior2883// :116:30: error: use of undefined value here causes illegal behavior
2888// :116:30: note: when computing vector element at index '0'
2889// :116:30: error: use of undefined value here causes illegal behavior2884// :116:30: error: use of undefined value here causes illegal behavior
2890// :116:30: note: when computing vector element at index '0'
2891// :116:30: error: use of undefined value here causes illegal behavior2885// :116:30: error: use of undefined value here causes illegal behavior
2892// :116:30: note: when computing vector element at index '0'
2893// :116:30: error: use of undefined value here causes illegal behavior2886// :116:30: error: use of undefined value here causes illegal behavior
2894// :116:30: note: when computing vector element at index '0'
2895// :116:30: error: use of undefined value here causes illegal behavior2887// :116:30: error: use of undefined value here causes illegal behavior
2896// :116:30: error: use of undefined value here causes illegal behavior2888// :116:30: error: use of undefined value here causes illegal behavior
2897// :116:30: error: use of undefined value here causes illegal behavior2889// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2899,21 +2891,13 @@ const std = @import("std");...@@ -2899,21 +2891,13 @@ const std = @import("std");
2899// :116:30: error: use of undefined value here causes illegal behavior2891// :116:30: error: use of undefined value here causes illegal behavior
2900// :116:30: error: use of undefined value here causes illegal behavior2892// :116:30: error: use of undefined value here causes illegal behavior
2901// :116:30: error: use of undefined value here causes illegal behavior2893// :116:30: error: use of undefined value here causes illegal behavior
2902// :116:30: note: when computing vector element at index '1'
2903// :116:30: error: use of undefined value here causes illegal behavior2894// :116:30: error: use of undefined value here causes illegal behavior
2904// :116:30: note: when computing vector element at index '1'
2905// :116:30: error: use of undefined value here causes illegal behavior2895// :116:30: error: use of undefined value here causes illegal behavior
2906// :116:30: note: when computing vector element at index '1'
2907// :116:30: error: use of undefined value here causes illegal behavior2896// :116:30: error: use of undefined value here causes illegal behavior
2908// :116:30: note: when computing vector element at index '1'
2909// :116:30: error: use of undefined value here causes illegal behavior2897// :116:30: error: use of undefined value here causes illegal behavior
2910// :116:30: note: when computing vector element at index '0'
2911// :116:30: error: use of undefined value here causes illegal behavior2898// :116:30: error: use of undefined value here causes illegal behavior
2912// :116:30: note: when computing vector element at index '0'
2913// :116:30: error: use of undefined value here causes illegal behavior2899// :116:30: error: use of undefined value here causes illegal behavior
2914// :116:30: note: when computing vector element at index '0'
2915// :116:30: error: use of undefined value here causes illegal behavior2900// :116:30: error: use of undefined value here causes illegal behavior
2916// :116:30: note: when computing vector element at index '0'
2917// :116:30: error: use of undefined value here causes illegal behavior2901// :116:30: error: use of undefined value here causes illegal behavior
2918// :116:30: error: use of undefined value here causes illegal behavior2902// :116:30: error: use of undefined value here causes illegal behavior
2919// :116:30: error: use of undefined value here causes illegal behavior2903// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2921,13 +2905,11 @@ const std = @import("std");...@@ -2921,13 +2905,11 @@ const std = @import("std");
2921// :116:30: error: use of undefined value here causes illegal behavior2905// :116:30: error: use of undefined value here causes illegal behavior
2922// :116:30: error: use of undefined value here causes illegal behavior2906// :116:30: error: use of undefined value here causes illegal behavior
2923// :116:30: error: use of undefined value here causes illegal behavior2907// :116:30: error: use of undefined value here causes illegal behavior
2924// :116:30: note: when computing vector element at index '1'
2925// :116:30: error: use of undefined value here causes illegal behavior2908// :116:30: error: use of undefined value here causes illegal behavior
2926// :116:30: note: when computing vector element at index '1'
2927// :116:30: error: use of undefined value here causes illegal behavior2909// :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'
2929// :116:30: error: use of undefined value here causes illegal behavior2911// :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'
2931// :116:30: error: use of undefined value here causes illegal behavior2913// :116:30: error: use of undefined value here causes illegal behavior
2932// :116:30: note: when computing vector element at index '0'2914// :116:30: note: when computing vector element at index '0'
2933// :116:30: error: use of undefined value here causes illegal behavior2915// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2937,19 +2919,25 @@ const std = @import("std");...@@ -2937,19 +2919,25 @@ const std = @import("std");
2937// :116:30: error: use of undefined value here causes illegal behavior2919// :116:30: error: use of undefined value here causes illegal behavior
2938// :116:30: note: when computing vector element at index '0'2920// :116:30: note: when computing vector element at index '0'
2939// :116:30: error: use of undefined value here causes illegal behavior2921// :116:30: error: use of undefined value here causes illegal behavior
2922// :116:30: note: when computing vector element at index '0'
2940// :116:30: error: use of undefined value here causes illegal behavior2923// :116:30: error: use of undefined value here causes illegal behavior
2924// :116:30: note: when computing vector element at index '0'
2941// :116:30: error: use of undefined value here causes illegal behavior2925// :116:30: error: use of undefined value here causes illegal behavior
2926// :116:30: note: when computing vector element at index '0'
2942// :116:30: error: use of undefined value here causes illegal behavior2927// :116:30: error: use of undefined value here causes illegal behavior
2928// :116:30: note: when computing vector element at index '0'
2943// :116:30: error: use of undefined value here causes illegal behavior2929// :116:30: error: use of undefined value here causes illegal behavior
2930// :116:30: note: when computing vector element at index '0'
2944// :116:30: error: use of undefined value here causes illegal behavior2931// :116:30: error: use of undefined value here causes illegal behavior
2932// :116:30: note: when computing vector element at index '0'
2945// :116:30: error: use of undefined value here causes illegal behavior2933// :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'
2947// :116:30: error: use of undefined value here causes illegal behavior2935// :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'
2949// :116:30: error: use of undefined value here causes illegal behavior2937// :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'
2951// :116:30: error: use of undefined value here causes illegal behavior2939// :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'
2953// :116:30: error: use of undefined value here causes illegal behavior2941// :116:30: error: use of undefined value here causes illegal behavior
2954// :116:30: note: when computing vector element at index '0'2942// :116:30: note: when computing vector element at index '0'
2955// :116:30: error: use of undefined value here causes illegal behavior2943// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2959,11 +2947,17 @@ const std = @import("std");...@@ -2959,11 +2947,17 @@ const std = @import("std");
2959// :116:30: error: use of undefined value here causes illegal behavior2947// :116:30: error: use of undefined value here causes illegal behavior
2960// :116:30: note: when computing vector element at index '0'2948// :116:30: note: when computing vector element at index '0'
2961// :116:30: error: use of undefined value here causes illegal behavior2949// :116:30: error: use of undefined value here causes illegal behavior
2950// :116:30: note: when computing vector element at index '0'
2962// :116:30: error: use of undefined value here causes illegal behavior2951// :116:30: error: use of undefined value here causes illegal behavior
2952// :116:30: note: when computing vector element at index '0'
2963// :116:30: error: use of undefined value here causes illegal behavior2953// :116:30: error: use of undefined value here causes illegal behavior
2954// :116:30: note: when computing vector element at index '0'
2964// :116:30: error: use of undefined value here causes illegal behavior2955// :116:30: error: use of undefined value here causes illegal behavior
2956// :116:30: note: when computing vector element at index '0'
2965// :116:30: error: use of undefined value here causes illegal behavior2957// :116:30: error: use of undefined value here causes illegal behavior
2958// :116:30: note: when computing vector element at index '1'
2966// :116:30: error: use of undefined value here causes illegal behavior2959// :116:30: error: use of undefined value here causes illegal behavior
2960// :116:30: note: when computing vector element at index '1'
2967// :116:30: error: use of undefined value here causes illegal behavior2961// :116:30: error: use of undefined value here causes illegal behavior
2968// :116:30: note: when computing vector element at index '1'2962// :116:30: note: when computing vector element at index '1'
2969// :116:30: error: use of undefined value here causes illegal behavior2963// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2973,19 +2967,25 @@ const std = @import("std");...@@ -2973,19 +2967,25 @@ const std = @import("std");
2973// :116:30: error: use of undefined value here causes illegal behavior2967// :116:30: error: use of undefined value here causes illegal behavior
2974// :116:30: note: when computing vector element at index '1'2968// :116:30: note: when computing vector element at index '1'
2975// :116:30: error: use of undefined value here causes illegal behavior2969// :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'
2977// :116:30: error: use of undefined value here causes illegal behavior2971// :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'
2979// :116:30: error: use of undefined value here causes illegal behavior2973// :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'
2981// :116:30: error: use of undefined value here causes illegal behavior2975// :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'
2983// :116:30: error: use of undefined value here causes illegal behavior2977// :116:30: error: use of undefined value here causes illegal behavior
2978// :116:30: note: when computing vector element at index '1'
2984// :116:30: error: use of undefined value here causes illegal behavior2979// :116:30: error: use of undefined value here causes illegal behavior
2980// :116:30: note: when computing vector element at index '1'
2985// :116:30: error: use of undefined value here causes illegal behavior2981// :116:30: error: use of undefined value here causes illegal behavior
2982// :116:30: note: when computing vector element at index '1'
2986// :116:30: error: use of undefined value here causes illegal behavior2983// :116:30: error: use of undefined value here causes illegal behavior
2984// :116:30: note: when computing vector element at index '1'
2987// :116:30: error: use of undefined value here causes illegal behavior2985// :116:30: error: use of undefined value here causes illegal behavior
2986// :116:30: note: when computing vector element at index '1'
2988// :116:30: error: use of undefined value here causes illegal behavior2987// :116:30: error: use of undefined value here causes illegal behavior
2988// :116:30: note: when computing vector element at index '1'
2989// :116:30: error: use of undefined value here causes illegal behavior2989// :116:30: error: use of undefined value here causes illegal behavior
2990// :116:30: note: when computing vector element at index '1'2990// :116:30: note: when computing vector element at index '1'
2991// :116:30: error: use of undefined value here causes illegal behavior2991// :116:30: error: use of undefined value here causes illegal behavior
...@@ -2995,10 +2995,10 @@ const std = @import("std");...@@ -2995,10 +2995,10 @@ const std = @import("std");
2995// :116:30: error: use of undefined value here causes illegal behavior2995// :116:30: error: use of undefined value here causes illegal behavior
2996// :116:30: note: when computing vector element at index '1'2996// :116:30: note: when computing vector element at index '1'
2997// :116:30: error: use of undefined value here causes illegal behavior2997// :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'
2999// :116:30: error: use of undefined value here causes illegal behavior2999// :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'
3001// :116:30: error: use of undefined value here causes illegal behavior3001// :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'
3003// :116:30: error: use of undefined value here causes illegal behavior3003// :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 {...@@ -12,5 +12,5 @@ export fn entry() void {
1212
13// error13// error
14//14//
15// :6:9: error: enum tag value 60 already taken15// :6:9: error: enum tag value '60' for field 'E' already taken
16// :4:9: note: other occurrence here16// :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 {...@@ -15,6 +15,5 @@ export fn entry() usize {
1515
16// error16// error
17//17//
18// :7:11: error: enum field(s) missing in union18// :7:11: error: enum field 'c' missing from union
19// :4:5: note: field 'c' missing, declared here19// :4:5: note: enum field here
20// :1:11: note: enum declared here
test/cases/compile_errors/union_field_ordered_differently_than_enum.zig+3-4
...@@ -21,7 +21,6 @@ export fn entry() usize {...@@ -21,7 +21,6 @@ export fn entry() usize {
2121
22// error22// error
23//23//
24// :4:5: error: union field 'b' ordered differently than corresponding enum field24// :3:15: error: union field order does not match tag enum field order
25// :1:23: note: enum field here25// :5:5: note: union field 'a' is index 1
26// :14:5: error: union field 'b' ordered differently than corresponding enum field26// :1:20: note: enum field 'a' is index 0
27// :10:5: note: enum field here
test/cases/compile_errors/union_noreturn_field_initialized.zig+6-6
...@@ -15,8 +15,8 @@ pub export fn entry2() void {...@@ -15,8 +15,8 @@ pub export fn entry2() void {
15 const U = union(enum) {15 const U = union(enum) {
16 a: noreturn,16 a: noreturn,
17 };17 };
18 var u: U = undefined;18 const u: U = .a;
19 u = .a;19 _ = u;
20}20}
21pub export fn entry3() void {21pub export fn entry3() void {
22 const U = union(enum) {22 const U = union(enum) {
...@@ -30,12 +30,12 @@ pub export fn entry3() void {...@@ -30,12 +30,12 @@ pub export fn entry3() void {
3030
31// error31// error
32//32//
33// :11:14: error: cannot initialize 'noreturn' field of union33// :11:14: error: cannot initialize union field with uninstantiable type 'noreturn'
34// :4:9: note: field 'b' declared here34// :4:9: note: field 'b' declared here
35// :2:15: note: union declared here35// :2:15: note: union declared here
36// :19:10: error: cannot initialize 'noreturn' field of union36// :18:19: error: cannot initialize union field with uninstantiable type 'noreturn'
37// :16:9: note: field 'a' declared here37// :16:9: note: field 'a' declared here
38// :15:15: note: union declared here38// :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' field39// :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: 'noreturn' field here40// :23:9: note: field 'a' has uninstantiable type 'noreturn'
41// :22:15: note: union declared here41// :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 {...@@ -13,6 +13,5 @@ export fn entry() usize {
1313
14// error14// error
15//15//
16// :6:17: error: enum field(s) missing in union16// :6:17: error: enum field 'C' missing from union
17// :4:5: note: field 'C' missing, declared here17// :4:5: note: enum field here
18// :1:16: note: enum declared here
test/cases/compile_errors/union_with_too_small_explicit_signed_tag_type.zig+1-2
...@@ -10,5 +10,4 @@ export fn entry() void {...@@ -10,5 +10,4 @@ export fn entry() void {
1010
11// error11// error
12//12//
13// :1:22: error: specified integer tag type cannot represent every field13// :4:5: error: enum tag value '2' too large for type 'i2'
14// :1:22: note: type 'i2' cannot fit values in range 0...3
test/cases/compile_errors/union_with_too_small_explicit_unsigned_tag_type.zig+1-2
...@@ -11,5 +11,4 @@ export fn entry() void {...@@ -11,5 +11,4 @@ export fn entry() void {
1111
12// error12// error
13//13//
14// :1:22: error: specified integer tag type cannot represent every field14// :6:5: error: enum tag value '4' too large for type 'u2'
15// :1:22: note: type 'u2' cannot fit values in range 0...4
test/cases/compile_errors/untagged_union_integer_conversion.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1const UntaggedUnion = union {};1const UntaggedUnion = union { a: void };
2comptime {2comptime {
3 @intFromEnum(@as(UntaggedUnion, undefined));3 @intFromEnum(@as(UntaggedUnion, undefined));
4}4}
test/cases/compile_errors/variadic_arg_validation.zig+1-1
...@@ -25,4 +25,4 @@ pub export fn entry3() void {...@@ -25,4 +25,4 @@ pub export fn entry3() void {
25// :14:24: error: cannot pass 'u48' to variadic function25// :14:24: error: cannot pass 'u48' to variadic function
26// :14:24: note: only integers with 0 or power of two bits are extern compatible26// :14:24: note: only integers with 0 or power of two bits are extern compatible
27// :18:24: error: cannot pass 'void' to variadic function27// :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 @@...@@ -1,17 +1,20 @@
1comptime {1comptime {
2 _ = enum(i0) { a, _ };2 const E = enum(i0) { a, _ };
3 _ = @as(E, undefined);
3}4}
45
5comptime {6comptime {
6 _ = enum(u0) { a, _ };7 const E = enum(u0) { a, _ };
8 _ = @as(E, undefined);
7}9}
810
9comptime {11comptime {
10 _ = enum(u0) { a, b, _ };12 const E = enum(u0) { a, b, _ };
13 _ = @as(E, undefined);
11}14}
1215
13// error16// error
14//17//
15// :2:9: error: non-exhaustive enum specifies every value18// :2:15: error: non-exhaustive enum specifies every value
16// :6:9: error: non-exhaustive enum specifies every value19// :7:15: error: non-exhaustive enum specifies every value
17// :10:23: error: enumeration value '1' too large for type 'u0'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 {...@@ -44,7 +44,7 @@ comptime {
44}44}
45const std = @import("std");45const std = @import("std");
46const io = std.Io.Threaded.global_single_threaded.io();46const 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'
48#update=increase tag size48#update=increase tag size
49#file=main.zig49#file=main.zig
50const Tag = u3;50const 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 {...@@ -311,12 +311,12 @@ const Eval = struct {
311 .error_bundle => {311 .error_bundle => {
312 const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);312 const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);
313 if (stderr.bufferedLen() > 0) {313 if (stderr.bufferedLen() > 0) {
314 const stderr_data = try mr.toOwnedSlice(1);
315 if (eval.allow_stderr) {314 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()});
317 } else {316 } else {
318 eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr_data});317 eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr.buffered()});
319 }318 }
319 stderr.tossBuffered();
320 }320 }
321 if (result_error_bundle.errorMessageCount() != 0) {321 if (result_error_bundle.errorMessageCount() != 0) {
322 try eval.checkErrorOutcome(update, result_error_bundle);322 try eval.checkErrorOutcome(update, result_error_bundle);
...@@ -327,18 +327,18 @@ const Eval = struct {...@@ -327,18 +327,18 @@ const Eval = struct {
327 .emit_digest => {327 .emit_digest => {
328 var r: std.Io.Reader = .fixed(body);328 var r: std.Io.Reader = .fixed(body);
329 _ = r.takeStruct(std.zig.Server.Message.EmitDigest, .little) catch unreachable;329 _ = r.takeStruct(std.zig.Server.Message.EmitDigest, .little) catch unreachable;
330
330 if (stderr.bufferedLen() > 0) {331 if (stderr.bufferedLen() > 0) {
331 const stderr_data = try mr.toOwnedSlice(1);
332 if (eval.allow_stderr) {332 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()});
334 } else {334 } else {
335 eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr_data});335 eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr.buffered()});
336 }336 }
337 stderr.tossBuffered();
337 }338 }
338
339 if (eval.target.backend == .sema) {339 if (eval.target.backend == .sema) {
340 try eval.checkSuccessOutcome(update, null, prog_node);340 try eval.checkSuccessOutcome(update, null, prog_node);
341 // This message indicates the end of the update.341 continue;
342 }342 }
343343
344 const digest = r.takeArray(Cache.bin_digest_len) catch unreachable;344 const digest = r.takeArray(Cache.bin_digest_len) catch unreachable;
...@@ -352,7 +352,6 @@ const Eval = struct {...@@ -352,7 +352,6 @@ const Eval = struct {
352 const bin_path = try Dir.path.join(arena, &.{ result_dir, bin_name });352 const bin_path = try Dir.path.join(arena, &.{ result_dir, bin_name });
353353
354 try eval.checkSuccessOutcome(update, bin_path, prog_node);354 try eval.checkSuccessOutcome(update, bin_path, prog_node);
355 // This message indicates the end of the update.
356 },355 },
357 else => {356 else => {
358 // Ignore other messages.357 // Ignore other messages.
...@@ -370,7 +369,7 @@ const Eval = struct {...@@ -370,7 +369,7 @@ const Eval = struct {
370 }369 }
371370
372 waitChild(eval.child, eval);371 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", .{});
374 }373 }
375374
376 fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void {375 fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void {
...@@ -417,29 +416,32 @@ const Eval = struct {...@@ -417,29 +416,32 @@ const Eval = struct {
417 is_note: bool,416 is_note: bool,
418 err_idx: std.zig.ErrorBundle.MessageIndex,417 err_idx: std.zig.ErrorBundle.MessageIndex,
419 ) Allocator.Error!void {418 ) Allocator.Error!void {
419 const io = eval.io;
420 const err = eb.getErrorMessage(err_idx);420 const err = eb.getErrorMessage(err_idx);
421 if (err.src_loc == .none) @panic("TODO error message with no source location");
422 if (err.count != 1) @panic("TODO error message with count>1");421 if (err.count != 1) @panic("TODO error message with count>1");
423 const msg = eb.nullTerminatedString(err.msg);422 const msg = eb.nullTerminatedString(err.msg);
424 const src = eb.getSourceLocation(err.src_loc);423 const matches = matches: {
425 const raw_filename = eb.nullTerminatedString(src.src_path);424 if (expected.is_note != is_note) break :matches false;
426425 if (!std.mem.eql(u8, expected.msg, msg)) break :matches false;
427 const io = eval.io;426 if (err.src_loc == .none) {
428427 break :matches expected.src == null;
429 // We need to replace backslashes for consistency between platforms.428 }
430 const filename = name: {429 const expected_src = expected.src orelse break :matches false;
431 if (std.mem.indexOfScalar(u8, raw_filename, '\\') == null) break :name raw_filename;430 const src = eb.getSourceLocation(err.src_loc);
432 const copied = try eval.arena.dupe(u8, raw_filename);431 const raw_filename = eb.nullTerminatedString(src.src_path);
433 std.mem.replaceScalar(u8, copied, '\\', '/');432 // We need to replace backslashes for consistency between platforms.
434 break :name copied;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;
435 };443 };
436444 if (!matches) {
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 {
443 eb.renderToStderr(io, .{}, .auto) catch {};445 eb.renderToStderr(io, .{}, .auto) catch {};
444 eval.fatal("compile error did not match expected error", .{});446 eval.fatal("compile error did not match expected error", .{});
445 }447 }
...@@ -714,10 +716,12 @@ const Case = struct {...@@ -714,10 +716,12 @@ const Case = struct {
714716
715 const ExpectedError = struct {717 const ExpectedError = struct {
716 is_note: bool,718 is_note: bool,
717 filename: []const u8,
718 line: u32,
719 column: u32,
720 msg: []const u8,719 msg: []const u8,
720 src: ?struct {
721 filename: []const u8,
722 line: u32,
723 column: u32,
724 },
721 };725 };
722726
723 fn parse(arena: Allocator, io: Io, bytes: []const u8) !Case {727 fn parse(arena: Allocator, io: Io, bytes: []const u8) !Case {
...@@ -930,16 +934,16 @@ fn parseExpectedError(str: []const u8, l: usize) Case.ExpectedError {...@@ -930,16 +934,16 @@ fn parseExpectedError(str: []const u8, l: usize) Case.ExpectedError {
930934
931 var it = std.mem.splitScalar(u8, str, ':');935 var it = std.mem.splitScalar(u8, str, ':');
932 const filename = it.first();936 const filename = it.first();
933 const line_str = it.next() orelse fatal("line {d}: incomplete error specification", .{l});937 const line_str, const column_str = if (filename.len > 0) .{
934 const column_str = it.next() orelse fatal("line {d}: incomplete error specification", .{l});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 };
935 const error_or_note_str = std.mem.trim(941 const error_or_note_str = std.mem.trim(
936 u8,942 u8,
937 it.next() orelse fatal("line {d}: incomplete error specification", .{l}),943 it.next() orelse fatal("line {d}: incomplete error specification", .{l}),
938 " ",944 " ",
939 );945 );
940 const message = std.mem.trim(u8, it.rest(), " ");946
941 if (filename.len == 0) fatal("line {d}: empty filename", .{l});
942 if (message.len == 0) fatal("line {d}: empty error message", .{l});
943 const is_note = if (std.mem.eql(u8, error_or_note_str, "error"))947 const is_note = if (std.mem.eql(u8, error_or_note_str, "error"))
944 false948 false
945 else if (std.mem.eql(u8, error_or_note_str, "note"))949 else if (std.mem.eql(u8, error_or_note_str, "note"))
...@@ -947,18 +951,19 @@ fn parseExpectedError(str: []const u8, l: usize) Case.ExpectedError {...@@ -947,18 +951,19 @@ fn parseExpectedError(str: []const u8, l: usize) Case.ExpectedError {
947 else951 else
948 fatal("line {d}: expeted 'error' or 'note', found '{s}'", .{ l, error_or_note_str });952 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) catch954 const message = std.mem.trim(u8, it.rest(), " ");
951 fatal("line {d}: invalid line number '{s}'", .{ l, line_str });955 if (message.len == 0) fatal("line {d}: empty error message", .{l});
952
953 const column = std.fmt.parseInt(u32, column_str, 10) catch
954 fatal("line {d}: invalid column number '{s}'", .{ l, column_str });
955956
956 return .{957 return .{
957 .is_note = is_note,958 .is_note = is_note,
958 .filename = filename,
959 .line = line,
960 .column = column,
961 .msg = message,959 .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 },
962 };967 };
963}968}
964969