authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-02 21:11:45-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-07-02 21:11:45-04:00
logbb98620c10992884d58ae97a3a30dd9e26735fea
tree463cb67f3551c397aae17dff5594cd2fd2037ca0
parentd84b386f6034278c8a9e8c3d2b0975ac541584aa
parenta6bf68ccf985787eeac33a97e362d043987905c4
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #9219 from ziglang/unreachable-code

move "unreachable code" error from stage1 to stage2

35 files changed, 4342 insertions(+), 3748 deletions(-)

build.zig+20-12
...@@ -40,7 +40,7 @@ pub fn build(b: *Builder) !void {...@@ -40,7 +40,7 @@ pub fn build(b: *Builder) !void {
4040
41 var test_stage2 = b.addTest("src/test.zig");41 var test_stage2 = b.addTest("src/test.zig");
42 test_stage2.setBuildMode(mode);42 test_stage2.setBuildMode(mode);
43 test_stage2.addPackagePath("stage2_tests", "test/stage2/test.zig");43 test_stage2.addPackagePath("test_cases", "test/cases.zig");
4444
45 const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});45 const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});
4646
...@@ -113,11 +113,15 @@ pub fn build(b: *Builder) !void {...@@ -113,11 +113,15 @@ pub fn build(b: *Builder) !void {
113 if (is_stage1) {113 if (is_stage1) {
114 exe.addIncludeDir("src");114 exe.addIncludeDir("src");
115 exe.addIncludeDir("deps/SoftFloat-3e/source/include");115 exe.addIncludeDir("deps/SoftFloat-3e/source/include");
116
117 test_stage2.addIncludeDir("src");
118 test_stage2.addIncludeDir("deps/SoftFloat-3e/source/include");
116 // This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case119 // This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
117 // of being built by cmake. But when built by zig it's gonna get a compiler_rt so that120 // of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
118 // is pointless.121 // is pointless.
119 exe.addPackagePath("compiler_rt", "src/empty.zig");122 exe.addPackagePath("compiler_rt", "src/empty.zig");
120 exe.defineCMacro("ZIG_LINK_MODE", "Static");123 exe.defineCMacro("ZIG_LINK_MODE", "Static");
124 test_stage2.defineCMacro("ZIG_LINK_MODE", "Static");
121125
122 const softfloat = b.addStaticLibrary("softfloat", null);126 const softfloat = b.addStaticLibrary("softfloat", null);
123 softfloat.setBuildMode(.ReleaseFast);127 softfloat.setBuildMode(.ReleaseFast);
...@@ -126,10 +130,15 @@ pub fn build(b: *Builder) !void {...@@ -126,10 +130,15 @@ pub fn build(b: *Builder) !void {
126 softfloat.addIncludeDir("deps/SoftFloat-3e/source/8086");130 softfloat.addIncludeDir("deps/SoftFloat-3e/source/8086");
127 softfloat.addIncludeDir("deps/SoftFloat-3e/source/include");131 softfloat.addIncludeDir("deps/SoftFloat-3e/source/include");
128 softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });132 softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
133
129 exe.linkLibrary(softfloat);134 exe.linkLibrary(softfloat);
135 test_stage2.linkLibrary(softfloat);
130136
131 exe.addCSourceFiles(&stage1_sources, &exe_cflags);137 exe.addCSourceFiles(&stage1_sources, &exe_cflags);
132 exe.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });138 exe.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
139
140 test_stage2.addCSourceFiles(&stage1_sources, &exe_cflags);
141 test_stage2.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
133 }142 }
134 if (cmake_cfg) |cfg| {143 if (cmake_cfg) |cfg| {
135 // Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.144 // Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
...@@ -139,8 +148,8 @@ pub fn build(b: *Builder) !void {...@@ -139,8 +148,8 @@ pub fn build(b: *Builder) !void {
139 b.addSearchPrefix(cfg.cmake_prefix_path);148 b.addSearchPrefix(cfg.cmake_prefix_path);
140 }149 }
141150
142 try addCmakeCfgOptionsToExe(b, cfg, tracy, exe);151 try addCmakeCfgOptionsToExe(b, cfg, exe);
143 try addCmakeCfgOptionsToExe(b, cfg, tracy, test_stage2);152 try addCmakeCfgOptionsToExe(b, cfg, test_stage2);
144 } else {153 } else {
145 // Here we are -Denable-llvm but no cmake integration.154 // Here we are -Denable-llvm but no cmake integration.
146 try addStaticLlvmOptionsToExe(exe);155 try addStaticLlvmOptionsToExe(exe);
...@@ -233,7 +242,9 @@ pub fn build(b: *Builder) !void {...@@ -233,7 +242,9 @@ pub fn build(b: *Builder) !void {
233 const is_darling_enabled = b.option(bool, "enable-darling", "[Experimental] Use Darling to run cross compiled macOS tests") orelse false;242 const is_darling_enabled = b.option(bool, "enable-darling", "[Experimental] Use Darling to run cross compiled macOS tests") orelse false;
234 const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc");243 const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc");
235244
245 test_stage2.addBuildOption(bool, "enable_logging", enable_logging);
236 test_stage2.addBuildOption(bool, "skip_non_native", skip_non_native);246 test_stage2.addBuildOption(bool, "skip_non_native", skip_non_native);
247 test_stage2.addBuildOption(bool, "skip_compile_errors", skip_compile_errors);
237 test_stage2.addBuildOption(bool, "is_stage1", is_stage1);248 test_stage2.addBuildOption(bool, "is_stage1", is_stage1);
238 test_stage2.addBuildOption(bool, "omit_stage2", omit_stage2);249 test_stage2.addBuildOption(bool, "omit_stage2", omit_stage2);
239 test_stage2.addBuildOption(bool, "have_llvm", enable_llvm);250 test_stage2.addBuildOption(bool, "have_llvm", enable_llvm);
...@@ -243,7 +254,8 @@ pub fn build(b: *Builder) !void {...@@ -243,7 +254,8 @@ pub fn build(b: *Builder) !void {
243 test_stage2.addBuildOption(u32, "mem_leak_frames", mem_leak_frames * 2);254 test_stage2.addBuildOption(u32, "mem_leak_frames", mem_leak_frames * 2);
244 test_stage2.addBuildOption(bool, "enable_darling", is_darling_enabled);255 test_stage2.addBuildOption(bool, "enable_darling", is_darling_enabled);
245 test_stage2.addBuildOption(?[]const u8, "glibc_multi_install_dir", glibc_multi_dir);256 test_stage2.addBuildOption(?[]const u8, "glibc_multi_install_dir", glibc_multi_dir);
246 test_stage2.addBuildOption([]const u8, "version", version);257 test_stage2.addBuildOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
258 test_stage2.addBuildOption(std.SemanticVersion, "semver", semver);
247259
248 const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");260 const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
249 test_stage2_step.dependOn(&test_stage2.step);261 test_stage2_step.dependOn(&test_stage2.step);
...@@ -339,9 +351,6 @@ pub fn build(b: *Builder) !void {...@@ -339,9 +351,6 @@ pub fn build(b: *Builder) !void {
339 }351 }
340 // tests for this feature are disabled until we have the self-hosted compiler available352 // tests for this feature are disabled until we have the self-hosted compiler available
341 // toolchain_step.dependOn(tests.addGenHTests(b, test_filter));353 // toolchain_step.dependOn(tests.addGenHTests(b, test_filter));
342 if (!skip_compile_errors) {
343 toolchain_step.dependOn(tests.addCompileErrorTests(b, test_filter, modes));
344 }
345354
346 const std_step = tests.addPkgTests(355 const std_step = tests.addPkgTests(
347 b,356 b,
...@@ -383,7 +392,6 @@ const exe_cflags = [_][]const u8{...@@ -383,7 +392,6 @@ const exe_cflags = [_][]const u8{
383fn addCmakeCfgOptionsToExe(392fn addCmakeCfgOptionsToExe(
384 b: *Builder,393 b: *Builder,
385 cfg: CMakeConfig,394 cfg: CMakeConfig,
386 tracy: ?[]const u8,
387 exe: *std.build.LibExeObjStep,395 exe: *std.build.LibExeObjStep,
388) !void {396) !void {
389 exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{397 exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
...@@ -397,7 +405,7 @@ fn addCmakeCfgOptionsToExe(...@@ -397,7 +405,7 @@ fn addCmakeCfgOptionsToExe(
397 addCMakeLibraryList(exe, cfg.lld_libraries);405 addCMakeLibraryList(exe, cfg.lld_libraries);
398 addCMakeLibraryList(exe, cfg.llvm_libraries);406 addCMakeLibraryList(exe, cfg.llvm_libraries);
399407
400 const need_cpp_includes = tracy != null;408 const need_cpp_includes = true;
401409
402 // System -lc++ must be used because in this code path we are attempting to link410 // System -lc++ must be used because in this code path we are attempting to link
403 // against system-provided LLVM, Clang, LLD.411 // against system-provided LLVM, Clang, LLD.
...@@ -486,9 +494,9 @@ fn addCxxKnownPath(...@@ -486,9 +494,9 @@ fn addCxxKnownPath(
486 if (need_cpp_includes) {494 if (need_cpp_includes) {
487 // I used these temporarily for testing something but we obviously need a495 // I used these temporarily for testing something but we obviously need a
488 // more general purpose solution here.496 // more general purpose solution here.
489 //exe.addIncludeDir("/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/lib/gcc/x86_64-unknown-linux-gnu/9.2.0/../../../../include/c++/9.2.0");497 //exe.addIncludeDir("/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../include/c++/9.3.0");
490 //exe.addIncludeDir("/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/lib/gcc/x86_64-unknown-linux-gnu/9.2.0/../../../../include/c++/9.2.0/x86_64-unknown-linux-gnu");498 //exe.addIncludeDir("/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../include/c++/9.3.0/x86_64-unknown-linux-gnu");
491 //exe.addIncludeDir("/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/lib/gcc/x86_64-unknown-linux-gnu/9.2.0/../../../../include/c++/9.2.0/backward");499 //exe.addIncludeDir("/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../include/c++/9.3.0/backward");
492 }500 }
493}501}
494502
doc/docgen.zig+34-14
...@@ -8,6 +8,7 @@ const Progress = std.Progress;...@@ -8,6 +8,7 @@ const Progress = std.Progress;
8const print = std.debug.print;8const print = std.debug.print;
9const mem = std.mem;9const mem = std.mem;
10const testing = std.testing;10const testing = std.testing;
11const Allocator = std.mem.Allocator;
1112
12const max_doc_file_size = 10 * 1024 * 1024;13const max_doc_file_size = 10 * 1024 * 1024;
1314
...@@ -326,7 +327,7 @@ const Action = enum {...@@ -326,7 +327,7 @@ const Action = enum {
326 Close,327 Close,
327};328};
328329
329fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {330fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
330 var urls = std.StringHashMap(Token).init(allocator);331 var urls = std.StringHashMap(Token).init(allocator);
331 errdefer urls.deinit();332 errdefer urls.deinit();
332333
...@@ -630,7 +631,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {...@@ -630,7 +631,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
630 };631 };
631}632}
632633
633fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {634fn urlize(allocator: *Allocator, input: []const u8) ![]u8 {
634 var buf = std.ArrayList(u8).init(allocator);635 var buf = std.ArrayList(u8).init(allocator);
635 defer buf.deinit();636 defer buf.deinit();
636637
...@@ -649,7 +650,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {...@@ -649,7 +650,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
649 return buf.toOwnedSlice();650 return buf.toOwnedSlice();
650}651}
651652
652fn escapeHtml(allocator: *mem.Allocator, input: []const u8) ![]u8 {653fn escapeHtml(allocator: *Allocator, input: []const u8) ![]u8 {
653 var buf = std.ArrayList(u8).init(allocator);654 var buf = std.ArrayList(u8).init(allocator);
654 defer buf.deinit();655 defer buf.deinit();
655656
...@@ -695,7 +696,7 @@ test "term color" {...@@ -695,7 +696,7 @@ test "term color" {
695 testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);696 testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);
696}697}
697698
698fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {699fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {
699 var buf = std.ArrayList(u8).init(allocator);700 var buf = std.ArrayList(u8).init(allocator);
700 defer buf.deinit();701 defer buf.deinit();
701702
...@@ -789,8 +790,15 @@ fn isType(name: []const u8) bool {...@@ -789,8 +790,15 @@ fn isType(name: []const u8) bool {
789 return false;790 return false;
790}791}
791792
792fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token: Token, raw_src: []const u8) !void {793fn tokenizeAndPrintRaw(
793 const src = mem.trim(u8, raw_src, " \n");794 allocator: *Allocator,
795 docgen_tokenizer: *Tokenizer,
796 out: anytype,
797 source_token: Token,
798 raw_src: []const u8,
799) !void {
800 const src_non_terminated = mem.trim(u8, raw_src, " \n");
801 const src = try allocator.dupeZ(u8, src_non_terminated);
794 try out.writeAll("<code class=\"zig\">");802 try out.writeAll("<code class=\"zig\">");
795 var tokenizer = std.zig.Tokenizer.init(src);803 var tokenizer = std.zig.Tokenizer.init(src);
796 var index: usize = 0;804 var index: usize = 0;
...@@ -1016,12 +1024,24 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token:...@@ -1016,12 +1024,24 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token:
1016 try out.writeAll("</code>");1024 try out.writeAll("</code>");
1017}1025}
10181026
1019fn tokenizeAndPrint(docgen_tokenizer: *Tokenizer, out: anytype, source_token: Token) !void {1027fn tokenizeAndPrint(
1028 allocator: *Allocator,
1029 docgen_tokenizer: *Tokenizer,
1030 out: anytype,
1031 source_token: Token,
1032) !void {
1020 const raw_src = docgen_tokenizer.buffer[source_token.start..source_token.end];1033 const raw_src = docgen_tokenizer.buffer[source_token.start..source_token.end];
1021 return tokenizeAndPrintRaw(docgen_tokenizer, out, source_token, raw_src);1034 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);
1022}1035}
10231036
1024fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: anytype, zig_exe: []const u8, do_code_tests: bool) !void {1037fn genHtml(
1038 allocator: *Allocator,
1039 tokenizer: *Tokenizer,
1040 toc: *Toc,
1041 out: anytype,
1042 zig_exe: []const u8,
1043 do_code_tests: bool,
1044) !void {
1025 var progress = Progress{};1045 var progress = Progress{};
1026 const root_node = try progress.start("Generating docgen examples", toc.nodes.len);1046 const root_node = try progress.start("Generating docgen examples", toc.nodes.len);
1027 defer root_node.end();1047 defer root_node.end();
...@@ -1048,7 +1068,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any...@@ -1048,7 +1068,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
1048 },1068 },
1049 .Builtin => |tok| {1069 .Builtin => |tok| {
1050 try out.writeAll("<pre>");1070 try out.writeAll("<pre>");
1051 try tokenizeAndPrintRaw(tokenizer, out, tok, builtin_code);1071 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);
1052 try out.writeAll("</pre>");1072 try out.writeAll("</pre>");
1053 },1073 },
1054 .HeaderOpen => |info| {1074 .HeaderOpen => |info| {
...@@ -1069,7 +1089,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any...@@ -1069,7 +1089,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
1069 try out.writeAll("</ul>\n");1089 try out.writeAll("</ul>\n");
1070 },1090 },
1071 .Syntax => |content_tok| {1091 .Syntax => |content_tok| {
1072 try tokenizeAndPrint(tokenizer, out, content_tok);1092 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);
1073 },1093 },
1074 .Code => |code| {1094 .Code => |code| {
1075 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];1095 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
...@@ -1078,7 +1098,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any...@@ -1078,7 +1098,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
1078 try out.print("<p class=\"file\">{s}.zig</p>", .{code.name});1098 try out.print("<p class=\"file\">{s}.zig</p>", .{code.name});
1079 }1099 }
1080 try out.writeAll("<pre>");1100 try out.writeAll("<pre>");
1081 try tokenizeAndPrint(tokenizer, out, code.source_token);1101 try tokenizeAndPrint(allocator, tokenizer, out, code.source_token);
1082 try out.writeAll("</pre>");1102 try out.writeAll("</pre>");
10831103
1084 if (!do_code_tests) {1104 if (!do_code_tests) {
...@@ -1497,7 +1517,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any...@@ -1497,7 +1517,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
1497 }1517 }
1498}1518}
14991519
1500fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {1520fn exec(allocator: *Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {
1501 const result = try ChildProcess.exec(.{1521 const result = try ChildProcess.exec(.{
1502 .allocator = allocator,1522 .allocator = allocator,
1503 .argv = args,1523 .argv = args,
...@@ -1521,7 +1541,7 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u...@@ -1521,7 +1541,7 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
1521 return result;1541 return result;
1522}1542}
15231543
1524fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {1544fn getBuiltinCode(allocator: *Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
1525 const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });1545 const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });
1526 return result.stdout;1546 return result.stdout;
1527}1547}
doc/langref.html.in+18-6
...@@ -3025,7 +3025,7 @@ test "@tagName" {...@@ -3025,7 +3025,7 @@ test "@tagName" {
3025 </p>3025 </p>
3026 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}3026 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}
3027const Foo = enum { a, b, c };3027const Foo = enum { a, b, c };
3028export fn entry(foo: Foo) void { }3028export fn entry(foo: Foo) void { _ = foo; }
3029 {#code_end#}3029 {#code_end#}
3030 <p>3030 <p>
3031 For a C-ABI-compatible enum, provide an explicit tag type to3031 For a C-ABI-compatible enum, provide an explicit tag type to
...@@ -3346,7 +3346,7 @@ test "call foo" {...@@ -3346,7 +3346,7 @@ test "call foo" {
3346 <p>3346 <p>
3347 Blocks are used to limit the scope of variable declarations:3347 Blocks are used to limit the scope of variable declarations:
3348 </p>3348 </p>
3349 {#code_begin|test_err|undeclared identifier#}3349 {#code_begin|test_err|unused local variable#}
3350test "access variable after block scope" {3350test "access variable after block scope" {
3351 {3351 {
3352 var x: i32 = 1;3352 var x: i32 = 1;
...@@ -3377,7 +3377,7 @@ test "labeled break from labeled block expression" {...@@ -3377,7 +3377,7 @@ test "labeled break from labeled block expression" {
33773377
3378 {#header_open|Shadowing#}3378 {#header_open|Shadowing#}
3379 <p>It is never allowed for an identifier to "hide" another one by using the same name:</p>3379 <p>It is never allowed for an identifier to "hide" another one by using the same name:</p>
3380 {#code_begin|test_err|redefinition#}3380 {#code_begin|test_err|local shadows declaration#}
3381const pi = 3.14;3381const pi = 3.14;
33823382
3383test "inside test block" {3383test "inside test block" {
...@@ -4228,8 +4228,8 @@ test "type of unreachable" {...@@ -4228,8 +4228,8 @@ test "type of unreachable" {
4228 comptime {4228 comptime {
4229 // The type of unreachable is noreturn.4229 // The type of unreachable is noreturn.
42304230
4231 // However this assertion will still fail because4231 // However this assertion will still fail to compile because
4232 // evaluating unreachable at compile-time is a compile error.4232 // unreachable expressions are compile errors.
42334233
4234 assert(@TypeOf(unreachable) == noreturn);4234 assert(@TypeOf(unreachable) == noreturn);
4235 }4235 }
...@@ -5257,6 +5257,7 @@ test "float widening" {...@@ -5257,6 +5257,7 @@ test "float widening" {
5257// Compile time coercion of float to int5257// Compile time coercion of float to int
5258test "implicit cast to comptime_int" {5258test "implicit cast to comptime_int" {
5259 var f: f32 = 54.0 / 5;5259 var f: f32 = 54.0 / 5;
5260 _ = f;
5260}5261}
5261 {#code_end#}5262 {#code_end#}
5262 {#header_close#}5263 {#header_close#}
...@@ -5817,6 +5818,7 @@ fn foo(condition: bool) void {...@@ -5817,6 +5818,7 @@ fn foo(condition: bool) void {
5817 if (condition) f32 else u64,5818 if (condition) f32 else u64,
5818 1234,5819 1234,
5819 5678);5820 5678);
5821 _ = result;
5820}5822}
5821 {#code_end#}5823 {#code_end#}
5822 <p>5824 <p>
...@@ -6313,7 +6315,7 @@ pub fn printValue(self: *Writer, value: anytype) !void {...@@ -6313,7 +6315,7 @@ pub fn printValue(self: *Writer, value: anytype) !void {
6313 <p>6315 <p>
6314 And now, what happens if we give too many arguments to {#syntax#}printf{#endsyntax#}?6316 And now, what happens if we give too many arguments to {#syntax#}printf{#endsyntax#}?
6315 </p>6317 </p>
6316 {#code_begin|test_err|Unused argument in "here is a string: '{s}' here is a number: {}#}6318 {#code_begin|test_err|Unused argument in 'here is a string: '{s}' here is a number: {}#}
6317const print = @import("std").debug.print;6319const print = @import("std").debug.print;
63186320
6319const a_number: i32 = 1234;6321const a_number: i32 = 1234;
...@@ -8853,6 +8855,7 @@ pub fn main() void {...@@ -8853,6 +8855,7 @@ pub fn main() void {
8853comptime {8855comptime {
8854 const array: [5]u8 = "hello".*;8856 const array: [5]u8 = "hello".*;
8855 const garbage = array[5];8857 const garbage = array[5];
8858 _ = garbage;
8856}8859}
8857 {#code_end#}8860 {#code_end#}
8858 <p>At runtime:</p>8861 <p>At runtime:</p>
...@@ -8873,6 +8876,7 @@ fn foo(x: []const u8) u8 {...@@ -8873,6 +8876,7 @@ fn foo(x: []const u8) u8 {
8873comptime {8876comptime {
8874 const value: i32 = -1;8877 const value: i32 = -1;
8875 const unsigned = @intCast(u32, value);8878 const unsigned = @intCast(u32, value);
8879 _ = unsigned;
8876}8880}
8877 {#code_end#}8881 {#code_end#}
8878 <p>At runtime:</p>8882 <p>At runtime:</p>
...@@ -8895,6 +8899,7 @@ pub fn main() void {...@@ -8895,6 +8899,7 @@ pub fn main() void {
8895comptime {8899comptime {
8896 const spartan_count: u16 = 300;8900 const spartan_count: u16 = 300;
8897 const byte = @intCast(u8, spartan_count);8901 const byte = @intCast(u8, spartan_count);
8902 _ = byte;
8898}8903}
8899 {#code_end#}8904 {#code_end#}
8900 <p>At runtime:</p>8905 <p>At runtime:</p>
...@@ -9028,6 +9033,7 @@ test "wraparound addition and subtraction" {...@@ -9028,6 +9033,7 @@ test "wraparound addition and subtraction" {
9028 {#code_begin|test_err|operation caused overflow#}9033 {#code_begin|test_err|operation caused overflow#}
9029comptime {9034comptime {
9030 const x = @shlExact(@as(u8, 0b01010101), 2);9035 const x = @shlExact(@as(u8, 0b01010101), 2);
9036 _ = x;
9031}9037}
9032 {#code_end#}9038 {#code_end#}
9033 <p>At runtime:</p>9039 <p>At runtime:</p>
...@@ -9046,6 +9052,7 @@ pub fn main() void {...@@ -9046,6 +9052,7 @@ pub fn main() void {
9046 {#code_begin|test_err|exact shift shifted out 1 bits#}9052 {#code_begin|test_err|exact shift shifted out 1 bits#}
9047comptime {9053comptime {
9048 const x = @shrExact(@as(u8, 0b10101010), 2);9054 const x = @shrExact(@as(u8, 0b10101010), 2);
9055 _ = x;
9049}9056}
9050 {#code_end#}9057 {#code_end#}
9051 <p>At runtime:</p>9058 <p>At runtime:</p>
...@@ -9066,6 +9073,7 @@ comptime {...@@ -9066,6 +9073,7 @@ comptime {
9066 const a: i32 = 1;9073 const a: i32 = 1;
9067 const b: i32 = 0;9074 const b: i32 = 0;
9068 const c = a / b;9075 const c = a / b;
9076 _ = c;
9069}9077}
9070 {#code_end#}9078 {#code_end#}
9071 <p>At runtime:</p>9079 <p>At runtime:</p>
...@@ -9087,6 +9095,7 @@ comptime {...@@ -9087,6 +9095,7 @@ comptime {
9087 const a: i32 = 10;9095 const a: i32 = 10;
9088 const b: i32 = 0;9096 const b: i32 = 0;
9089 const c = a % b;9097 const c = a % b;
9098 _ = c;
9090}9099}
9091 {#code_end#}9100 {#code_end#}
9092 <p>At runtime:</p>9101 <p>At runtime:</p>
...@@ -9108,6 +9117,7 @@ comptime {...@@ -9108,6 +9117,7 @@ comptime {
9108 const a: u32 = 10;9117 const a: u32 = 10;
9109 const b: u32 = 3;9118 const b: u32 = 3;
9110 const c = @divExact(a, b);9119 const c = @divExact(a, b);
9120 _ = c;
9111}9121}
9112 {#code_end#}9122 {#code_end#}
9113 <p>At runtime:</p>9123 <p>At runtime:</p>
...@@ -9300,6 +9310,7 @@ fn foo(set1: Set1) void {...@@ -9300,6 +9310,7 @@ fn foo(set1: Set1) void {
9300comptime {9310comptime {
9301 const ptr = @intToPtr(*align(1) i32, 0x1);9311 const ptr = @intToPtr(*align(1) i32, 0x1);
9302 const aligned = @alignCast(4, ptr);9312 const aligned = @alignCast(4, ptr);
9313 _ = aligned;
9303}9314}
9304 {#code_end#}9315 {#code_end#}
9305 <p>At runtime:</p>9316 <p>At runtime:</p>
...@@ -9414,6 +9425,7 @@ fn bar(f: *Foo) void {...@@ -9414,6 +9425,7 @@ fn bar(f: *Foo) void {
9414comptime {9425comptime {
9415 const opt_ptr: ?*i32 = null;9426 const opt_ptr: ?*i32 = null;
9416 const ptr = @ptrCast(*i32, opt_ptr);9427 const ptr = @ptrCast(*i32, opt_ptr);
9428 _ = ptr;
9417}9429}
9418 {#code_end#}9430 {#code_end#}
9419 <p>At runtime:</p>9431 <p>At runtime:</p>
lib/std/fmt.zig+2-2
...@@ -362,8 +362,8 @@ pub fn format(...@@ -362,8 +362,8 @@ pub fn format(
362 const missing_count = arg_state.args_len - @popCount(ArgSetType, arg_state.used_args);362 const missing_count = arg_state.args_len - @popCount(ArgSetType, arg_state.used_args);
363 switch (missing_count) {363 switch (missing_count) {
364 0 => unreachable,364 0 => unreachable,
365 1 => @compileError("Unused argument in \"" ++ fmt ++ "\""),365 1 => @compileError("Unused argument in '" ++ fmt ++ "'"),
366 else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in \"" ++ fmt ++ "\""),366 else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in '" ++ fmt ++ "'"),
367 }367 }
368 }368 }
369}369}
lib/std/mem.zig+5-5
...@@ -2297,14 +2297,14 @@ pub fn replaceOwned(comptime T: type, allocator: *Allocator, input: []const T, n...@@ -2297,14 +2297,14 @@ pub fn replaceOwned(comptime T: type, allocator: *Allocator, input: []const T, n
2297}2297}
22982298
2299test "replaceOwned" {2299test "replaceOwned" {
2300 const allocator = std.heap.page_allocator;2300 const gpa = std.testing.allocator;
23012301
2302 const base_replace = replaceOwned(u8, allocator, "All your base are belong to us", "base", "Zig") catch unreachable;2302 const base_replace = replaceOwned(u8, gpa, "All your base are belong to us", "base", "Zig") catch @panic("out of memory");
2303 defer allocator.free(base_replace);2303 defer gpa.free(base_replace);
2304 try testing.expect(eql(u8, base_replace, "All your Zig are belong to us"));2304 try testing.expect(eql(u8, base_replace, "All your Zig are belong to us"));
23052305
2306 const zen_replace = replaceOwned(u8, allocator, "Favor reading code over writing code.", " code", "") catch unreachable;2306 const zen_replace = replaceOwned(u8, gpa, "Favor reading code over writing code.", " code", "") catch @panic("out of memory");
2307 defer allocator.free(zen_replace);2307 defer gpa.free(zen_replace);
2308 try testing.expect(eql(u8, zen_replace, "Favor reading over writing."));2308 try testing.expect(eql(u8, zen_replace, "Favor reading over writing."));
2309}2309}
23102310
lib/std/os/uefi/protocols/simple_network_protocol.zig+4-4
...@@ -57,13 +57,13 @@ pub const SimpleNetworkProtocol = extern struct {...@@ -57,13 +57,13 @@ pub const SimpleNetworkProtocol = extern struct {
57 }57 }
5858
59 /// Modifies or resets the current station address, if supported.59 /// Modifies or resets the current station address, if supported.
60 pub fn stationAddress(self: *const SimpleNetworkProtocol, reset: bool, new: ?*const MacAddress) Status {60 pub fn stationAddress(self: *const SimpleNetworkProtocol, reset_flag: bool, new: ?*const MacAddress) Status {
61 return self._station_address(self, reset, new);61 return self._station_address(self, reset_flag, new);
62 }62 }
6363
64 /// Resets or collects the statistics on a network interface.64 /// Resets or collects the statistics on a network interface.
65 pub fn statistics(self: *const SimpleNetworkProtocol, reset_: bool, statistics_size: ?*usize, statistics_table: ?*NetworkStatistics) Status {65 pub fn statistics(self: *const SimpleNetworkProtocol, reset_flag: bool, statistics_size: ?*usize, statistics_table: ?*NetworkStatistics) Status {
66 return self._statistics(self, reset_, statistics_size, statistics_table);66 return self._statistics(self, reset_flag, statistics_size, statistics_table);
67 }67 }
6868
69 /// Converts a multicast IP address to a multicast HW MAC address.69 /// Converts a multicast IP address to a multicast HW MAC address.
lib/std/unicode.zig-1
...@@ -247,7 +247,6 @@ pub const Utf8View = struct {...@@ -247,7 +247,6 @@ pub const Utf8View = struct {
247 } else |err| switch (err) {247 } else |err| switch (err) {
248 error.InvalidUtf8 => {248 error.InvalidUtf8 => {
249 @compileError("invalid utf8");249 @compileError("invalid utf8");
250 unreachable;
251 },250 },
252 }251 }
253 }252 }
lib/std/zig.zig+147-56
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
6const std = @import("std.zig");6const std = @import("std.zig");
7const tokenizer = @import("zig/tokenizer.zig");7const tokenizer = @import("zig/tokenizer.zig");
8const fmt = @import("zig/fmt.zig");8const fmt = @import("zig/fmt.zig");
9const assert = std.debug.assert;
910
10pub const Token = tokenizer.Token;11pub const Token = tokenizer.Token;
11pub const Tokenizer = tokenizer.Tokenizer;12pub const Tokenizer = tokenizer.Tokenizer;
...@@ -183,29 +184,48 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro...@@ -183,29 +184,48 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
183 }184 }
184}185}
185186
187pub const ParsedCharLiteral = union(enum) {
188 success: u32,
189 /// The character after backslash is not recognized.
190 invalid_escape_character: usize,
191 /// Expected hex digit at this index.
192 expected_hex_digit: usize,
193 /// Unicode escape sequence had no digits with rbrace at this index.
194 empty_unicode_escape_sequence: usize,
195 /// Expected hex digit or '}' at this index.
196 expected_hex_digit_or_rbrace: usize,
197 /// The unicode point is outside the range of Unicode codepoints.
198 unicode_escape_overflow: usize,
199 /// Expected '{' at this index.
200 expected_lbrace: usize,
201 /// Expected the terminating single quote at this index.
202 expected_end: usize,
203 /// The character at this index cannot be represented without an escape sequence.
204 invalid_character: usize,
205};
206
186/// Only validates escape sequence characters.207/// Only validates escape sequence characters.
187/// Slice must be valid utf8 starting and ending with "'" and exactly one codepoint in between.208/// Slice must be valid utf8 starting and ending with "'" and exactly one codepoint in between.
188pub fn parseCharLiteral(209pub fn parseCharLiteral(slice: []const u8) ParsedCharLiteral {
189 slice: []const u8,210 assert(slice.len >= 3 and slice[0] == '\'' and slice[slice.len - 1] == '\'');
190 bad_index: *usize, // populated if error.InvalidCharacter is returned
191) error{InvalidCharacter}!u32 {
192 std.debug.assert(slice.len >= 3 and slice[0] == '\'' and slice[slice.len - 1] == '\'');
193211
194 if (slice[1] == '\\') {212 switch (slice[1]) {
195 switch (slice[2]) {213 0 => return .{ .invalid_character = 1 },
196 'n' => return '\n',214 '\\' => switch (slice[2]) {
197 'r' => return '\r',215 'n' => return .{ .success = '\n' },
198 '\\' => return '\\',216 'r' => return .{ .success = '\r' },
199 't' => return '\t',217 '\\' => return .{ .success = '\\' },
200 '\'' => return '\'',218 't' => return .{ .success = '\t' },
201 '"' => return '"',219 '\'' => return .{ .success = '\'' },
220 '"' => return .{ .success = '"' },
202 'x' => {221 'x' => {
203 if (slice.len != 6) {222 if (slice.len < 4) {
204 bad_index.* = slice.len - 2;223 return .{ .expected_hex_digit = 3 };
205 return error.InvalidCharacter;
206 }224 }
207 var value: u32 = 0;225 var value: u32 = 0;
208 for (slice[3..5]) |c, i| {226 var i: usize = 3;
227 while (i < 5) : (i += 1) {
228 const c = slice[i];
209 switch (c) {229 switch (c) {
210 '0'...'9' => {230 '0'...'9' => {
211 value *= 16;231 value *= 16;
...@@ -220,20 +240,28 @@ pub fn parseCharLiteral(...@@ -220,20 +240,28 @@ pub fn parseCharLiteral(
220 value += c - 'A' + 10;240 value += c - 'A' + 10;
221 },241 },
222 else => {242 else => {
223 bad_index.* = 3 + i;243 return .{ .expected_hex_digit = i };
224 return error.InvalidCharacter;
225 },244 },
226 }245 }
227 }246 }
228 return value;247 if (slice[i] != '\'') {
248 return .{ .expected_end = i };
249 }
250 return .{ .success = value };
229 },251 },
230 'u' => {252 'u' => {
231 if (slice.len < "'\\u{0}'".len or slice[3] != '{' or slice[slice.len - 2] != '}') {253 var i: usize = 3;
232 bad_index.* = 2;254 if (slice[i] != '{') {
233 return error.InvalidCharacter;255 return .{ .expected_lbrace = i };
234 }256 }
257 i += 1;
258 if (slice[i] == '}') {
259 return .{ .empty_unicode_escape_sequence = i };
260 }
261
235 var value: u32 = 0;262 var value: u32 = 0;
236 for (slice[4 .. slice.len - 2]) |c, i| {263 while (i < slice.len) : (i += 1) {
264 const c = slice[i];
237 switch (c) {265 switch (c) {
238 '0'...'9' => {266 '0'...'9' => {
239 value *= 16;267 value *= 16;
...@@ -247,49 +275,112 @@ pub fn parseCharLiteral(...@@ -247,49 +275,112 @@ pub fn parseCharLiteral(
247 value *= 16;275 value *= 16;
248 value += c - 'A' + 10;276 value += c - 'A' + 10;
249 },277 },
250 else => {278 '}' => {
251 bad_index.* = 4 + i;279 i += 1;
252 return error.InvalidCharacter;280 break;
253 },281 },
282 else => return .{ .expected_hex_digit_or_rbrace = i },
254 }283 }
255 if (value > 0x10ffff) {284 if (value > 0x10ffff) {
256 bad_index.* = 4 + i;285 return .{ .unicode_escape_overflow = i };
257 return error.InvalidCharacter;
258 }286 }
259 }287 }
260 return value;288 if (slice[i] != '\'') {
261 },289 return .{ .expected_end = i };
262 else => {290 }
263 bad_index.* = 2;291 return .{ .success = value };
264 return error.InvalidCharacter;
265 },292 },
266 }293 else => return .{ .invalid_escape_character = 2 },
294 },
295 else => {
296 const codepoint = std.unicode.utf8Decode(slice[1 .. slice.len - 1]) catch unreachable;
297 return .{ .success = codepoint };
298 },
267 }299 }
268 return std.unicode.utf8Decode(slice[1 .. slice.len - 1]) catch unreachable;
269}300}
270301
271test "parseCharLiteral" {302test "parseCharLiteral" {
272 var bad_index: usize = undefined;303 try std.testing.expectEqual(
273 try std.testing.expectEqual(try parseCharLiteral("'a'", &bad_index), 'a');304 ParsedCharLiteral{ .success = 'a' },
274 try std.testing.expectEqual(try parseCharLiteral("'ä'", &bad_index), 'ä');305 parseCharLiteral("'a'"),
275 try std.testing.expectEqual(try parseCharLiteral("'\\x00'", &bad_index), 0);306 );
276 try std.testing.expectEqual(try parseCharLiteral("'\\x4f'", &bad_index), 0x4f);307 try std.testing.expectEqual(
277 try std.testing.expectEqual(try parseCharLiteral("'\\x4F'", &bad_index), 0x4f);308 ParsedCharLiteral{ .success = 'ä' },
278 try std.testing.expectEqual(try parseCharLiteral("'ぁ'", &bad_index), 0x3041);309 parseCharLiteral("'ä'"),
279 try std.testing.expectEqual(try parseCharLiteral("'\\u{0}'", &bad_index), 0);310 );
280 try std.testing.expectEqual(try parseCharLiteral("'\\u{3041}'", &bad_index), 0x3041);311 try std.testing.expectEqual(
281 try std.testing.expectEqual(try parseCharLiteral("'\\u{7f}'", &bad_index), 0x7f);312 ParsedCharLiteral{ .success = 0 },
282 try std.testing.expectEqual(try parseCharLiteral("'\\u{7FFF}'", &bad_index), 0x7FFF);313 parseCharLiteral("'\\x00'"),
314 );
315 try std.testing.expectEqual(
316 ParsedCharLiteral{ .success = 0x4f },
317 parseCharLiteral("'\\x4f'"),
318 );
319 try std.testing.expectEqual(
320 ParsedCharLiteral{ .success = 0x4f },
321 parseCharLiteral("'\\x4F'"),
322 );
323 try std.testing.expectEqual(
324 ParsedCharLiteral{ .success = 0x3041 },
325 parseCharLiteral("'ぁ'"),
326 );
327 try std.testing.expectEqual(
328 ParsedCharLiteral{ .success = 0 },
329 parseCharLiteral("'\\u{0}'"),
330 );
331 try std.testing.expectEqual(
332 ParsedCharLiteral{ .success = 0x3041 },
333 parseCharLiteral("'\\u{3041}'"),
334 );
335 try std.testing.expectEqual(
336 ParsedCharLiteral{ .success = 0x7f },
337 parseCharLiteral("'\\u{7f}'"),
338 );
339 try std.testing.expectEqual(
340 ParsedCharLiteral{ .success = 0x7fff },
341 parseCharLiteral("'\\u{7FFF}'"),
342 );
283343
284 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\x0'", &bad_index));344 try std.testing.expectEqual(
285 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\x000'", &bad_index));345 ParsedCharLiteral{ .expected_hex_digit = 4 },
286 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\y'", &bad_index));346 parseCharLiteral("'\\x0'"),
287 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u'", &bad_index));347 );
288 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\uFFFF'", &bad_index));348 try std.testing.expectEqual(
289 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{}'", &bad_index));349 ParsedCharLiteral{ .expected_end = 5 },
290 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFFFF}'", &bad_index));350 parseCharLiteral("'\\x000'"),
291 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFF'", &bad_index));351 );
292 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFF}x'", &bad_index));352 try std.testing.expectEqual(
353 ParsedCharLiteral{ .invalid_escape_character = 2 },
354 parseCharLiteral("'\\y'"),
355 );
356 try std.testing.expectEqual(
357 ParsedCharLiteral{ .expected_lbrace = 3 },
358 parseCharLiteral("'\\u'"),
359 );
360 try std.testing.expectEqual(
361 ParsedCharLiteral{ .expected_lbrace = 3 },
362 parseCharLiteral("'\\uFFFF'"),
363 );
364 try std.testing.expectEqual(
365 ParsedCharLiteral{ .empty_unicode_escape_sequence = 4 },
366 parseCharLiteral("'\\u{}'"),
367 );
368 try std.testing.expectEqual(
369 ParsedCharLiteral{ .unicode_escape_overflow = 9 },
370 parseCharLiteral("'\\u{FFFFFF}'"),
371 );
372 try std.testing.expectEqual(
373 ParsedCharLiteral{ .expected_hex_digit_or_rbrace = 8 },
374 parseCharLiteral("'\\u{FFFF'"),
375 );
376 try std.testing.expectEqual(
377 ParsedCharLiteral{ .expected_end = 9 },
378 parseCharLiteral("'\\u{FFFF}x'"),
379 );
380 try std.testing.expectEqual(
381 ParsedCharLiteral{ .invalid_character = 1 },
382 parseCharLiteral("'\x00'"),
383 );
293}384}
294385
295test {386test {
lib/std/zig/ast.zig+4-2
...@@ -20,7 +20,7 @@ pub const NodeList = std.MultiArrayList(Node);...@@ -20,7 +20,7 @@ pub const NodeList = std.MultiArrayList(Node);
2020
21pub const Tree = struct {21pub const Tree = struct {
22 /// Reference to externally-owned data.22 /// Reference to externally-owned data.
23 source: []const u8,23 source: [:0]const u8,
2424
25 tokens: TokenList.Slice,25 tokens: TokenList.Slice,
26 /// The root AST node is assumed to be index 0. Since there can be no26 /// The root AST node is assumed to be index 0. Since there can be no
...@@ -135,6 +135,8 @@ pub const Tree = struct {...@@ -135,6 +135,8 @@ pub const Tree = struct {
135 const token_tags = tree.tokens.items(.tag);135 const token_tags = tree.tokens.items(.tag);
136 switch (parse_error.tag) {136 switch (parse_error.tag) {
137 .asterisk_after_ptr_deref => {137 .asterisk_after_ptr_deref => {
138 // Note that the token will point at the `.*` but ideally the source
139 // location would point to the `*` after the `.*`.
138 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");140 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
139 },141 },
140 .decl_between_fields => {142 .decl_between_fields => {
...@@ -284,7 +286,7 @@ pub const Tree = struct {...@@ -284,7 +286,7 @@ pub const Tree = struct {
284 return stream.writeAll("bit range not allowed on slices and arrays");286 return stream.writeAll("bit range not allowed on slices and arrays");
285 },287 },
286 .invalid_token => {288 .invalid_token => {
287 return stream.print("invalid token '{s}'", .{289 return stream.print("invalid token: '{s}'", .{
288 token_tags[parse_error.token].symbol(),290 token_tags[parse_error.token].symbol(),
289 });291 });
290 },292 },
lib/std/zig/parse.zig+1-1
...@@ -17,7 +17,7 @@ pub const Error = error{ParseError} || Allocator.Error;...@@ -17,7 +17,7 @@ pub const Error = error{ParseError} || Allocator.Error;
1717
18/// Result should be freed with tree.deinit() when there are18/// Result should be freed with tree.deinit() when there are
19/// no more references to any of the tokens or nodes.19/// no more references to any of the tokens or nodes.
20pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!Tree {20pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
21 var tokens = ast.TokenList{};21 var tokens = ast.TokenList{};
22 defer tokens.deinit(gpa);22 defer tokens.deinit(gpa);
2323
lib/std/zig/parser_test.zig+4-4
...@@ -5194,7 +5194,7 @@ const maxInt = std.math.maxInt;...@@ -5194,7 +5194,7 @@ const maxInt = std.math.maxInt;
51945194
5195var fixed_buffer_mem: [100 * 1024]u8 = undefined;5195var fixed_buffer_mem: [100 * 1024]u8 = undefined;
51965196
5197fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *bool) ![]u8 {5197fn testParse(source: [:0]const u8, allocator: *mem.Allocator, anything_changed: *bool) ![]u8 {
5198 const stderr = io.getStdErr().writer();5198 const stderr = io.getStdErr().writer();
51995199
5200 var tree = try std.zig.parse(allocator, source);5200 var tree = try std.zig.parse(allocator, source);
...@@ -5222,7 +5222,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b...@@ -5222,7 +5222,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
5222 anything_changed.* = !mem.eql(u8, formatted, source);5222 anything_changed.* = !mem.eql(u8, formatted, source);
5223 return formatted;5223 return formatted;
5224}5224}
5225fn testTransform(source: []const u8, expected_source: []const u8) !void {5225fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {
5226 const needed_alloc_count = x: {5226 const needed_alloc_count = x: {
5227 // Try it once with unlimited memory, make sure it works5227 // Try it once with unlimited memory, make sure it works
5228 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);5228 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
...@@ -5268,13 +5268,13 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {...@@ -5268,13 +5268,13 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
5268 }5268 }
5269 }5269 }
5270}5270}
5271fn testCanonical(source: []const u8) !void {5271fn testCanonical(source: [:0]const u8) !void {
5272 return testTransform(source, source);5272 return testTransform(source, source);
5273}5273}
52745274
5275const Error = std.zig.ast.Error.Tag;5275const Error = std.zig.ast.Error.Tag;
52765276
5277fn testError(source: []const u8, expected_errors: []const Error) !void {5277fn testError(source: [:0]const u8, expected_errors: []const Error) !void {
5278 var tree = try std.zig.parse(std.testing.allocator, source);5278 var tree = try std.zig.parse(std.testing.allocator, source);
5279 defer tree.deinit(std.testing.allocator);5279 defer tree.deinit(std.testing.allocator);
52805280
lib/std/zig/tokenizer.zig+78-189
...@@ -326,7 +326,7 @@ pub const Token = struct {...@@ -326,7 +326,7 @@ pub const Token = struct {
326};326};
327327
328pub const Tokenizer = struct {328pub const Tokenizer = struct {
329 buffer: []const u8,329 buffer: [:0]const u8,
330 index: usize,330 index: usize,
331 pending_invalid_token: ?Token,331 pending_invalid_token: ?Token,
332332
...@@ -335,7 +335,7 @@ pub const Tokenizer = struct {...@@ -335,7 +335,7 @@ pub const Tokenizer = struct {
335 std.debug.warn("{s} \"{s}\"\n", .{ @tagName(token.tag), self.buffer[token.start..token.end] });335 std.debug.warn("{s} \"{s}\"\n", .{ @tagName(token.tag), self.buffer[token.start..token.end] });
336 }336 }
337337
338 pub fn init(buffer: []const u8) Tokenizer {338 pub fn init(buffer: [:0]const u8) Tokenizer {
339 // Skip the UTF-8 BOM if present339 // Skip the UTF-8 BOM if present
340 const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else @as(usize, 0);340 const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else @as(usize, 0);
341 return Tokenizer{341 return Tokenizer{
...@@ -373,7 +373,6 @@ pub const Tokenizer = struct {...@@ -373,7 +373,6 @@ pub const Tokenizer = struct {
373 line_comment,373 line_comment,
374 doc_comment_start,374 doc_comment_start,
375 doc_comment,375 doc_comment,
376 container_doc_comment,
377 zero,376 zero,
378 int_literal_dec,377 int_literal_dec,
379 int_literal_dec_no_underscore,378 int_literal_dec_no_underscore,
...@@ -407,10 +406,6 @@ pub const Tokenizer = struct {...@@ -407,10 +406,6 @@ pub const Tokenizer = struct {
407 saw_at_sign,406 saw_at_sign,
408 };407 };
409408
410 fn isIdentifierChar(char: u8) bool {
411 return std.ascii.isAlNum(char) or char == '_';
412 }
413
414 pub fn next(self: *Tokenizer) Token {409 pub fn next(self: *Tokenizer) Token {
415 if (self.pending_invalid_token) |token| {410 if (self.pending_invalid_token) |token| {
416 self.pending_invalid_token = null;411 self.pending_invalid_token = null;
...@@ -426,10 +421,11 @@ pub const Tokenizer = struct {...@@ -426,10 +421,11 @@ pub const Tokenizer = struct {
426 };421 };
427 var seen_escape_digits: usize = undefined;422 var seen_escape_digits: usize = undefined;
428 var remaining_code_units: usize = undefined;423 var remaining_code_units: usize = undefined;
429 while (self.index < self.buffer.len) : (self.index += 1) {424 while (true) : (self.index += 1) {
430 const c = self.buffer[self.index];425 const c = self.buffer[self.index];
431 switch (state) {426 switch (state) {
432 .start => switch (c) {427 .start => switch (c) {
428 0 => break,
433 ' ', '\n', '\t', '\r' => {429 ' ', '\n', '\t', '\r' => {
434 result.loc.start = self.index + 1;430 result.loc.start = self.index + 1;
435 },431 },
...@@ -555,8 +551,9 @@ pub const Tokenizer = struct {...@@ -555,8 +551,9 @@ pub const Tokenizer = struct {
555 },551 },
556 else => {552 else => {
557 result.tag = .invalid;553 result.tag = .invalid;
554 result.loc.end = self.index;
558 self.index += 1;555 self.index += 1;
559 break;556 return result;
560 },557 },
561 },558 },
562559
...@@ -705,18 +702,35 @@ pub const Tokenizer = struct {...@@ -705,18 +702,35 @@ pub const Tokenizer = struct {
705 self.index += 1;702 self.index += 1;
706 break;703 break;
707 },704 },
708 '\n', '\r' => break, // Look for this error later.705 0 => {
706 if (self.index == self.buffer.len) {
707 break;
708 } else {
709 self.checkLiteralCharacter();
710 }
711 },
712 '\n' => {
713 result.tag = .invalid;
714 break;
715 },
709 else => self.checkLiteralCharacter(),716 else => self.checkLiteralCharacter(),
710 },717 },
711718
712 .string_literal_backslash => switch (c) {719 .string_literal_backslash => switch (c) {
713 '\n', '\r' => break, // Look for this error later.720 '\n' => {
721 result.tag = .invalid;
722 break;
723 },
714 else => {724 else => {
715 state = .string_literal;725 state = .string_literal;
716 },726 },
717 },727 },
718728
719 .char_literal => switch (c) {729 .char_literal => switch (c) {
730 0 => {
731 result.tag = .invalid;
732 break;
733 },
720 '\\' => {734 '\\' => {
721 state = .char_literal_backslash;735 state = .char_literal_backslash;
722 },736 },
...@@ -742,7 +756,7 @@ pub const Tokenizer = struct {...@@ -742,7 +756,7 @@ pub const Tokenizer = struct {
742 },756 },
743757
744 .char_literal_backslash => switch (c) {758 .char_literal_backslash => switch (c) {
745 '\n' => {759 0, '\n' => {
746 result.tag = .invalid;760 result.tag = .invalid;
747 break;761 break;
748 },762 },
...@@ -774,7 +788,6 @@ pub const Tokenizer = struct {...@@ -774,7 +788,6 @@ pub const Tokenizer = struct {
774 .char_literal_unicode_escape_saw_u => switch (c) {788 .char_literal_unicode_escape_saw_u => switch (c) {
775 '{' => {789 '{' => {
776 state = .char_literal_unicode_escape;790 state = .char_literal_unicode_escape;
777 seen_escape_digits = 0;
778 },791 },
779 else => {792 else => {
780 result.tag = .invalid;793 result.tag = .invalid;
...@@ -783,16 +796,9 @@ pub const Tokenizer = struct {...@@ -783,16 +796,9 @@ pub const Tokenizer = struct {
783 },796 },
784797
785 .char_literal_unicode_escape => switch (c) {798 .char_literal_unicode_escape => switch (c) {
786 '0'...'9', 'a'...'f', 'A'...'F' => {799 '0'...'9', 'a'...'f', 'A'...'F' => {},
787 seen_escape_digits += 1;
788 },
789 '}' => {800 '}' => {
790 if (seen_escape_digits == 0) {801 state = .char_literal_end; // too many/few digits handled later
791 result.tag = .invalid;
792 state = .char_literal_unicode_invalid;
793 } else {
794 state = .char_literal_end;
795 }
796 },802 },
797 else => {803 else => {
798 result.tag = .invalid;804 result.tag = .invalid;
...@@ -834,6 +840,7 @@ pub const Tokenizer = struct {...@@ -834,6 +840,7 @@ pub const Tokenizer = struct {
834 },840 },
835841
836 .multiline_string_literal_line => switch (c) {842 .multiline_string_literal_line => switch (c) {
843 0 => break,
837 '\n' => {844 '\n' => {
838 self.index += 1;845 self.index += 1;
839 break;846 break;
...@@ -1025,12 +1032,19 @@ pub const Tokenizer = struct {...@@ -1025,12 +1032,19 @@ pub const Tokenizer = struct {
1025 },1032 },
1026 },1033 },
1027 .line_comment_start => switch (c) {1034 .line_comment_start => switch (c) {
1035 0 => {
1036 if (self.index != self.buffer.len) {
1037 result.tag = .invalid;
1038 self.index += 1;
1039 }
1040 break;
1041 },
1028 '/' => {1042 '/' => {
1029 state = .doc_comment_start;1043 state = .doc_comment_start;
1030 },1044 },
1031 '!' => {1045 '!' => {
1032 result.tag = .container_doc_comment;1046 result.tag = .container_doc_comment;
1033 state = .container_doc_comment;1047 state = .doc_comment;
1034 },1048 },
1035 '\n' => {1049 '\n' => {
1036 state = .start;1050 state = .start;
...@@ -1046,7 +1060,7 @@ pub const Tokenizer = struct {...@@ -1046,7 +1060,7 @@ pub const Tokenizer = struct {
1046 '/' => {1060 '/' => {
1047 state = .line_comment;1061 state = .line_comment;
1048 },1062 },
1049 '\n' => {1063 0, '\n' => {
1050 result.tag = .doc_comment;1064 result.tag = .doc_comment;
1051 break;1065 break;
1052 },1066 },
...@@ -1061,6 +1075,7 @@ pub const Tokenizer = struct {...@@ -1061,6 +1075,7 @@ pub const Tokenizer = struct {
1061 },1075 },
1062 },1076 },
1063 .line_comment => switch (c) {1077 .line_comment => switch (c) {
1078 0 => break,
1064 '\n' => {1079 '\n' => {
1065 state = .start;1080 state = .start;
1066 result.loc.start = self.index + 1;1081 result.loc.start = self.index + 1;
...@@ -1068,8 +1083,8 @@ pub const Tokenizer = struct {...@@ -1068,8 +1083,8 @@ pub const Tokenizer = struct {
1068 '\t', '\r' => {},1083 '\t', '\r' => {},
1069 else => self.checkLiteralCharacter(),1084 else => self.checkLiteralCharacter(),
1070 },1085 },
1071 .doc_comment, .container_doc_comment => switch (c) {1086 .doc_comment => switch (c) {
1072 '\n' => break,1087 0, '\n' => break,
1073 '\t', '\r' => {},1088 '\t', '\r' => {},
1074 else => self.checkLiteralCharacter(),1089 else => self.checkLiteralCharacter(),
1075 },1090 },
...@@ -1088,12 +1103,11 @@ pub const Tokenizer = struct {...@@ -1088,12 +1103,11 @@ pub const Tokenizer = struct {
1088 self.index -= 1;1103 self.index -= 1;
1089 state = .int_literal_dec;1104 state = .int_literal_dec;
1090 },1105 },
1091 else => {1106 'a', 'c', 'd', 'f'...'n', 'p'...'w', 'y', 'z', 'A'...'D', 'F'...'Z' => {
1092 if (isIdentifierChar(c)) {1107 result.tag = .invalid;
1093 result.tag = .invalid;
1094 }
1095 break;1108 break;
1096 },1109 },
1110 else => break,
1097 },1111 },
1098 .int_literal_bin_no_underscore => switch (c) {1112 .int_literal_bin_no_underscore => switch (c) {
1099 '0'...'1' => {1113 '0'...'1' => {
...@@ -1109,12 +1123,11 @@ pub const Tokenizer = struct {...@@ -1109,12 +1123,11 @@ pub const Tokenizer = struct {
1109 state = .int_literal_bin_no_underscore;1123 state = .int_literal_bin_no_underscore;
1110 },1124 },
1111 '0'...'1' => {},1125 '0'...'1' => {},
1112 else => {1126 '2'...'9', 'a'...'z', 'A'...'Z' => {
1113 if (isIdentifierChar(c)) {1127 result.tag = .invalid;
1114 result.tag = .invalid;
1115 }
1116 break;1128 break;
1117 },1129 },
1130 else => break,
1118 },1131 },
1119 .int_literal_oct_no_underscore => switch (c) {1132 .int_literal_oct_no_underscore => switch (c) {
1120 '0'...'7' => {1133 '0'...'7' => {
...@@ -1130,12 +1143,11 @@ pub const Tokenizer = struct {...@@ -1130,12 +1143,11 @@ pub const Tokenizer = struct {
1130 state = .int_literal_oct_no_underscore;1143 state = .int_literal_oct_no_underscore;
1131 },1144 },
1132 '0'...'7' => {},1145 '0'...'7' => {},
1133 else => {1146 '8', '9', 'a'...'z', 'A'...'Z' => {
1134 if (isIdentifierChar(c)) {1147 result.tag = .invalid;
1135 result.tag = .invalid;
1136 }
1137 break;1148 break;
1138 },1149 },
1150 else => break,
1139 },1151 },
1140 .int_literal_dec_no_underscore => switch (c) {1152 .int_literal_dec_no_underscore => switch (c) {
1141 '0'...'9' => {1153 '0'...'9' => {
...@@ -1159,12 +1171,11 @@ pub const Tokenizer = struct {...@@ -1159,12 +1171,11 @@ pub const Tokenizer = struct {
1159 result.tag = .float_literal;1171 result.tag = .float_literal;
1160 },1172 },
1161 '0'...'9' => {},1173 '0'...'9' => {},
1162 else => {1174 'a'...'d', 'f'...'z', 'A'...'D', 'F'...'Z' => {
1163 if (isIdentifierChar(c)) {1175 result.tag = .invalid;
1164 result.tag = .invalid;
1165 }
1166 break;1176 break;
1167 },1177 },
1178 else => break,
1168 },1179 },
1169 .int_literal_hex_no_underscore => switch (c) {1180 .int_literal_hex_no_underscore => switch (c) {
1170 '0'...'9', 'a'...'f', 'A'...'F' => {1181 '0'...'9', 'a'...'f', 'A'...'F' => {
...@@ -1188,12 +1199,11 @@ pub const Tokenizer = struct {...@@ -1188,12 +1199,11 @@ pub const Tokenizer = struct {
1188 result.tag = .float_literal;1199 result.tag = .float_literal;
1189 },1200 },
1190 '0'...'9', 'a'...'f', 'A'...'F' => {},1201 '0'...'9', 'a'...'f', 'A'...'F' => {},
1191 else => {1202 'g'...'o', 'q'...'z', 'G'...'O', 'Q'...'Z' => {
1192 if (isIdentifierChar(c)) {1203 result.tag = .invalid;
1193 result.tag = .invalid;
1194 }
1195 break;1204 break;
1196 },1205 },
1206 else => break,
1197 },1207 },
1198 .num_dot_dec => switch (c) {1208 .num_dot_dec => switch (c) {
1199 '.' => {1209 '.' => {
...@@ -1206,12 +1216,11 @@ pub const Tokenizer = struct {...@@ -1206,12 +1216,11 @@ pub const Tokenizer = struct {
1206 result.tag = .float_literal;1216 result.tag = .float_literal;
1207 state = .float_fraction_dec;1217 state = .float_fraction_dec;
1208 },1218 },
1209 else => {1219 '_', 'a'...'z', 'A'...'Z' => {
1210 if (isIdentifierChar(c)) {1220 result.tag = .invalid;
1211 result.tag = .invalid;
1212 }
1213 break;1221 break;
1214 },1222 },
1223 else => break,
1215 },1224 },
1216 .num_dot_hex => switch (c) {1225 .num_dot_hex => switch (c) {
1217 '.' => {1226 '.' => {
...@@ -1224,12 +1233,11 @@ pub const Tokenizer = struct {...@@ -1224,12 +1233,11 @@ pub const Tokenizer = struct {
1224 result.tag = .float_literal;1233 result.tag = .float_literal;
1225 state = .float_fraction_hex;1234 state = .float_fraction_hex;
1226 },1235 },
1227 else => {1236 '_', 'g'...'z', 'G'...'Z' => {
1228 if (isIdentifierChar(c)) {1237 result.tag = .invalid;
1229 result.tag = .invalid;
1230 }
1231 break;1238 break;
1232 },1239 },
1240 else => break,
1233 },1241 },
1234 .float_fraction_dec_no_underscore => switch (c) {1242 .float_fraction_dec_no_underscore => switch (c) {
1235 '0'...'9' => {1243 '0'...'9' => {
...@@ -1248,12 +1256,11 @@ pub const Tokenizer = struct {...@@ -1248,12 +1256,11 @@ pub const Tokenizer = struct {
1248 state = .float_exponent_unsigned;1256 state = .float_exponent_unsigned;
1249 },1257 },
1250 '0'...'9' => {},1258 '0'...'9' => {},
1251 else => {1259 'a'...'d', 'f'...'z', 'A'...'D', 'F'...'Z' => {
1252 if (isIdentifierChar(c)) {1260 result.tag = .invalid;
1253 result.tag = .invalid;
1254 }
1255 break;1261 break;
1256 },1262 },
1263 else => break,
1257 },1264 },
1258 .float_fraction_hex_no_underscore => switch (c) {1265 .float_fraction_hex_no_underscore => switch (c) {
1259 '0'...'9', 'a'...'f', 'A'...'F' => {1266 '0'...'9', 'a'...'f', 'A'...'F' => {
...@@ -1272,12 +1279,11 @@ pub const Tokenizer = struct {...@@ -1272,12 +1279,11 @@ pub const Tokenizer = struct {
1272 state = .float_exponent_unsigned;1279 state = .float_exponent_unsigned;
1273 },1280 },
1274 '0'...'9', 'a'...'f', 'A'...'F' => {},1281 '0'...'9', 'a'...'f', 'A'...'F' => {},
1275 else => {1282 'g'...'o', 'q'...'z', 'G'...'O', 'Q'...'Z' => {
1276 if (isIdentifierChar(c)) {1283 result.tag = .invalid;
1277 result.tag = .invalid;
1278 }
1279 break;1284 break;
1280 },1285 },
1286 else => break,
1281 },1287 },
1282 .float_exponent_unsigned => switch (c) {1288 .float_exponent_unsigned => switch (c) {
1283 '+', '-' => {1289 '+', '-' => {
...@@ -1303,130 +1309,11 @@ pub const Tokenizer = struct {...@@ -1303,130 +1309,11 @@ pub const Tokenizer = struct {
1303 state = .float_exponent_num_no_underscore;1309 state = .float_exponent_num_no_underscore;
1304 },1310 },
1305 '0'...'9' => {},1311 '0'...'9' => {},
1306 else => {1312 'a'...'z', 'A'...'Z' => {
1307 if (isIdentifierChar(c)) {1313 result.tag = .invalid;
1308 result.tag = .invalid;
1309 }
1310 break;1314 break;
1311 },1315 },
1312 },1316 else => break,
1313 }
1314 } else if (self.index == self.buffer.len) {
1315 switch (state) {
1316 .start,
1317 .int_literal_dec,
1318 .int_literal_bin,
1319 .int_literal_oct,
1320 .int_literal_hex,
1321 .num_dot_dec,
1322 .num_dot_hex,
1323 .float_fraction_dec,
1324 .float_fraction_hex,
1325 .float_exponent_num,
1326 .string_literal, // find this error later
1327 .multiline_string_literal_line,
1328 .builtin,
1329 .line_comment,
1330 .line_comment_start,
1331 => {},
1332
1333 .identifier => {
1334 if (Token.getKeyword(self.buffer[result.loc.start..self.index])) |tag| {
1335 result.tag = tag;
1336 }
1337 },
1338 .doc_comment, .doc_comment_start => {
1339 result.tag = .doc_comment;
1340 },
1341 .container_doc_comment => {
1342 result.tag = .container_doc_comment;
1343 },
1344
1345 .int_literal_dec_no_underscore,
1346 .int_literal_bin_no_underscore,
1347 .int_literal_oct_no_underscore,
1348 .int_literal_hex_no_underscore,
1349 .float_fraction_dec_no_underscore,
1350 .float_fraction_hex_no_underscore,
1351 .float_exponent_num_no_underscore,
1352 .float_exponent_unsigned,
1353 .saw_at_sign,
1354 .backslash,
1355 .char_literal,
1356 .char_literal_backslash,
1357 .char_literal_hex_escape,
1358 .char_literal_unicode_escape_saw_u,
1359 .char_literal_unicode_escape,
1360 .char_literal_unicode_invalid,
1361 .char_literal_end,
1362 .char_literal_unicode,
1363 .string_literal_backslash,
1364 => {
1365 result.tag = .invalid;
1366 },
1367
1368 .equal => {
1369 result.tag = .equal;
1370 },
1371 .bang => {
1372 result.tag = .bang;
1373 },
1374 .minus => {
1375 result.tag = .minus;
1376 },
1377 .slash => {
1378 result.tag = .slash;
1379 },
1380 .zero => {
1381 result.tag = .integer_literal;
1382 },
1383 .ampersand => {
1384 result.tag = .ampersand;
1385 },
1386 .period => {
1387 result.tag = .period;
1388 },
1389 .period_2 => {
1390 result.tag = .ellipsis2;
1391 },
1392 .period_asterisk => {
1393 result.tag = .period_asterisk;
1394 },
1395 .pipe => {
1396 result.tag = .pipe;
1397 },
1398 .angle_bracket_angle_bracket_right => {
1399 result.tag = .angle_bracket_angle_bracket_right;
1400 },
1401 .angle_bracket_right => {
1402 result.tag = .angle_bracket_right;
1403 },
1404 .angle_bracket_angle_bracket_left => {
1405 result.tag = .angle_bracket_angle_bracket_left;
1406 },
1407 .angle_bracket_left => {
1408 result.tag = .angle_bracket_left;
1409 },
1410 .plus_percent => {
1411 result.tag = .plus_percent;
1412 },
1413 .plus => {
1414 result.tag = .plus;
1415 },
1416 .percent => {
1417 result.tag = .percent;
1418 },
1419 .caret => {
1420 result.tag = .caret;
1421 },
1422 .asterisk_percent => {
1423 result.tag = .asterisk_percent;
1424 },
1425 .asterisk => {
1426 result.tag = .asterisk;
1427 },
1428 .minus_percent => {
1429 result.tag = .minus_percent;
1430 },1317 },
1431 }1318 }
1432 }1319 }
...@@ -1566,7 +1453,7 @@ test "tokenizer - code point literal with unicode escapes" {...@@ -1566,7 +1453,7 @@ test "tokenizer - code point literal with unicode escapes" {
1566 , &.{ .invalid, .invalid });1453 , &.{ .invalid, .invalid });
1567 try testTokenize(1454 try testTokenize(
1568 \\'\u{}'1455 \\'\u{}'
1569 , &.{ .invalid, .invalid });1456 , &.{.char_literal});
1570 try testTokenize(1457 try testTokenize(
1571 \\'\u{s}'1458 \\'\u{s}'
1572 , &.{ .invalid, .invalid });1459 , &.{ .invalid, .invalid });
...@@ -2049,15 +1936,17 @@ test "tokenizer - invalid builtin identifiers" {...@@ -2049,15 +1936,17 @@ test "tokenizer - invalid builtin identifiers" {
2049 try testTokenize("@0()", &.{ .invalid, .integer_literal, .l_paren, .r_paren });1936 try testTokenize("@0()", &.{ .invalid, .integer_literal, .l_paren, .r_paren });
2050}1937}
20511938
2052fn testTokenize(source: []const u8, expected_tokens: []const Token.Tag) !void {1939fn testTokenize(source: [:0]const u8, expected_tokens: []const Token.Tag) !void {
2053 var tokenizer = Tokenizer.init(source);1940 var tokenizer = Tokenizer.init(source);
2054 for (expected_tokens) |expected_token_id| {1941 for (expected_tokens) |expected_token_id| {
2055 const token = tokenizer.next();1942 const token = tokenizer.next();
2056 if (token.tag != expected_token_id) {1943 if (token.tag != expected_token_id) {
2057 std.debug.panic("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.tag) });1944 std.debug.panic("expected {s}, found {s}\n", .{
1945 @tagName(expected_token_id), @tagName(token.tag),
1946 });
2058 }1947 }
2059 }1948 }
2060 const last_token = tokenizer.next();1949 const last_token = tokenizer.next();
2061 try std.testing.expect(last_token.tag == .eof);1950 try std.testing.expectEqual(Token.Tag.eof, last_token.tag);
2062 try std.testing.expect(last_token.loc.start == source.len);1951 try std.testing.expectEqual(source.len, last_token.loc.start);
2063}1952}
src/AstGen.zig+321-180
...@@ -34,8 +34,9 @@ string_table: std.StringHashMapUnmanaged(u32) = .{},...@@ -34,8 +34,9 @@ string_table: std.StringHashMapUnmanaged(u32) = .{},
34compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},34compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
35/// The topmost block of the current function.35/// The topmost block of the current function.
36fn_block: ?*GenZir = null,36fn_block: ?*GenZir = null,
37/// String table indexes, keeps track of all `@import` operands.37/// Maps string table indexes to the first `@import` ZIR instruction
38imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{},38/// that uses this string as the operand.
39imports: std.AutoArrayHashMapUnmanaged(u32, Zir.Inst.Index) = .{},
3940
40const InnerError = error{ OutOfMemory, AnalysisFail };41const InnerError = error{ OutOfMemory, AnalysisFail };
4142
...@@ -154,7 +155,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {...@@ -154,7 +155,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {
154 astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{155 astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{
155 .imports_len = @intCast(u32, astgen.imports.count()),156 .imports_len = @intCast(u32, astgen.imports.count()),
156 });157 });
157 astgen.extra.appendSliceAssumeCapacity(astgen.imports.keys());158 astgen.extra.appendSliceAssumeCapacity(astgen.imports.values());
158 }159 }
159160
160 return Zir{161 return Zir{
...@@ -261,6 +262,23 @@ fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zi...@@ -261,6 +262,23 @@ fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zi
261 return expr(gz, scope, .{ .ty = .type_type }, type_node);262 return expr(gz, scope, .{ .ty = .type_type }, type_node);
262}263}
263264
265/// Same as `expr` but fails with a compile error if the result type is `noreturn`.
266fn reachableExpr(
267 gz: *GenZir,
268 scope: *Scope,
269 rl: ResultLoc,
270 node: ast.Node.Index,
271 src_node: ast.Node.Index,
272) InnerError!Zir.Inst.Ref {
273 const result_inst = try expr(gz, scope, rl, node);
274 if (gz.refIsNoReturn(result_inst)) {
275 return gz.astgen.failNodeNotes(src_node, "unreachable code", .{}, &[_]u32{
276 try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}),
277 });
278 }
279 return result_inst;
280}
281
264fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {282fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
265 const astgen = gz.astgen;283 const astgen = gz.astgen;
266 const tree = astgen.tree;284 const tree = astgen.tree;
...@@ -1296,22 +1314,23 @@ fn structInitExpr(...@@ -1296,22 +1314,23 @@ fn structInitExpr(
1296 const astgen = gz.astgen;1314 const astgen = gz.astgen;
1297 const tree = astgen.tree;1315 const tree = astgen.tree;
12981316
1299 if (struct_init.ast.fields.len == 0) {1317 if (struct_init.ast.type_expr == 0) {
1300 if (struct_init.ast.type_expr == 0) {1318 if (struct_init.ast.fields.len == 0) {
1301 return rvalue(gz, rl, .empty_struct, node);1319 return rvalue(gz, rl, .empty_struct, node);
1302 }1320 }
1303 array: {1321 } else array: {
1304 const node_tags = tree.nodes.items(.tag);1322 const node_tags = tree.nodes.items(.tag);
1305 const main_tokens = tree.nodes.items(.main_token);1323 const main_tokens = tree.nodes.items(.main_token);
1306 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {1324 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1307 .array_type => tree.arrayType(struct_init.ast.type_expr),1325 .array_type => tree.arrayType(struct_init.ast.type_expr),
1308 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),1326 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1309 else => break :array,1327 else => break :array,
1310 };1328 };
1329 const is_inferred_array_len = node_tags[array_type.ast.elem_count] == .identifier and
1311 // This intentionally does not support `@"_"` syntax.1330 // This intentionally does not support `@"_"` syntax.
1312 if (node_tags[array_type.ast.elem_count] == .identifier and1331 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_");
1313 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))1332 if (struct_init.ast.fields.len == 0) {
1314 {1333 if (is_inferred_array_len) {
1315 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);1334 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
1316 const array_type_inst = if (array_type.ast.sentinel == 0) blk: {1335 const array_type_inst = if (array_type.ast.sentinel == 0) blk: {
1317 break :blk try gz.addBin(.array_type, .zero_usize, elem_type);1336 break :blk try gz.addBin(.array_type, .zero_usize, elem_type);
...@@ -1322,11 +1341,18 @@ fn structInitExpr(...@@ -1322,11 +1341,18 @@ fn structInitExpr(
1322 const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node);1341 const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node);
1323 return rvalue(gz, rl, result, node);1342 return rvalue(gz, rl, result, node);
1324 }1343 }
1344 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1345 const result = try gz.addUnNode(.struct_init_empty, ty_inst, node);
1346 return rvalue(gz, rl, result, node);
1347 } else {
1348 return astgen.failNode(
1349 struct_init.ast.type_expr,
1350 "initializing array with struct syntax",
1351 .{},
1352 );
1325 }1353 }
1326 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1327 const result = try gz.addUnNode(.struct_init_empty, ty_inst, node);
1328 return rvalue(gz, rl, result, node);
1329 }1354 }
1355
1330 switch (rl) {1356 switch (rl) {
1331 .discard => {1357 .discard => {
1332 if (struct_init.ast.type_expr != 0)1358 if (struct_init.ast.type_expr != 0)
...@@ -1570,7 +1596,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1570,7 +1596,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1570 const defer_scope = scope.cast(Scope.Defer).?;1596 const defer_scope = scope.cast(Scope.Defer).?;
1571 scope = defer_scope.parent;1597 scope = defer_scope.parent;
1572 const expr_node = node_datas[defer_scope.defer_node].rhs;1598 const expr_node = node_datas[defer_scope.defer_node].rhs;
1573 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);1599 _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1574 },1600 },
1575 .defer_error => scope = scope.cast(Scope.Defer).?.parent,1601 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1576 .top => unreachable,1602 .top => unreachable,
...@@ -1623,7 +1649,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)...@@ -1623,7 +1649,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
1623 const defer_scope = scope.cast(Scope.Defer).?;1649 const defer_scope = scope.cast(Scope.Defer).?;
1624 scope = defer_scope.parent;1650 scope = defer_scope.parent;
1625 const expr_node = node_datas[defer_scope.defer_node].rhs;1651 const expr_node = node_datas[defer_scope.defer_node].rhs;
1626 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);1652 _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1627 },1653 },
1628 .defer_error => scope = scope.cast(Scope.Defer).?.parent,1654 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1629 .namespace => break,1655 .namespace => break,
...@@ -1679,7 +1705,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke...@@ -1679,7 +1705,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke
1679 }, &[_]u32{1705 }, &[_]u32{
1680 try astgen.errNoteTok(1706 try astgen.errNoteTok(
1681 prev_label.token,1707 prev_label.token,
1682 "previous definition is here",1708 "previous definition here",
1683 .{},1709 .{},
1684 ),1710 ),
1685 });1711 });
...@@ -1785,8 +1811,23 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1785,8 +1811,23 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1785 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);1811 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
1786 defer block_arena.deinit();1812 defer block_arena.deinit();
17871813
1814 var noreturn_src_node: ast.Node.Index = 0;
1788 var scope = parent_scope;1815 var scope = parent_scope;
1789 for (statements) |statement| {1816 for (statements) |statement| {
1817 if (noreturn_src_node != 0) {
1818 return astgen.failNodeNotes(
1819 statement,
1820 "unreachable code",
1821 .{},
1822 &[_]u32{
1823 try astgen.errNoteNode(
1824 noreturn_src_node,
1825 "control flow is diverted here",
1826 .{},
1827 ),
1828 },
1829 );
1830 }
1790 switch (node_tags[statement]) {1831 switch (node_tags[statement]) {
1791 // zig fmt: off1832 // zig fmt: off
1792 .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)),1833 .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)),
...@@ -1814,7 +1855,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1814,7 +1855,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1814 .assign_mul => try assignOp(gz, scope, statement, .mul),1855 .assign_mul => try assignOp(gz, scope, statement, .mul),
1815 .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap),1856 .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap),
18161857
1817 else => try unusedResultExpr(gz, scope, statement),1858 else => noreturn_src_node = try unusedResultExpr(gz, scope, statement),
1818 // zig fmt: on1859 // zig fmt: on
1819 }1860 }
1820 }1861 }
...@@ -1823,11 +1864,14 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1823,11 +1864,14 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1823 try checkUsed(gz, parent_scope, scope);1864 try checkUsed(gz, parent_scope, scope);
1824}1865}
18251866
1826fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!void {1867/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
1868/// Otherwise returns 0.
1869fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!ast.Node.Index {
1827 try emitDbgNode(gz, statement);1870 try emitDbgNode(gz, statement);
1828 // We need to emit an error if the result is not `noreturn` or `void`, but1871 // We need to emit an error if the result is not `noreturn` or `void`, but
1829 // we want to avoid adding the ZIR instruction if possible for performance.1872 // we want to avoid adding the ZIR instruction if possible for performance.
1830 const maybe_unused_result = try expr(gz, scope, .none, statement);1873 const maybe_unused_result = try expr(gz, scope, .none, statement);
1874 var noreturn_src_node: ast.Node.Index = 0;
1831 const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: {1875 const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: {
1832 // Note that this array becomes invalid after appending more items to it1876 // Note that this array becomes invalid after appending more items to it
1833 // in the above while loop.1877 // in the above while loop.
...@@ -2061,15 +2105,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -2061,15 +2105,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
2061 .extended,2105 .extended,
2062 => break :b false,2106 => break :b false,
20632107
2064 // ZIR instructions that are always either `noreturn` or `void`.2108 // ZIR instructions that are always `noreturn`.
2065 .breakpoint,
2066 .fence,
2067 .dbg_stmt,
2068 .ensure_result_used,
2069 .ensure_result_non_error,
2070 .@"export",
2071 .set_eval_branch_quota,
2072 .ensure_err_payload_void,
2073 .@"break",2109 .@"break",
2074 .break_inline,2110 .break_inline,
2075 .condbr,2111 .condbr,
...@@ -2078,16 +2114,30 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -2078,16 +2114,30 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
2078 .ret_node,2114 .ret_node,
2079 .ret_coerce,2115 .ret_coerce,
2080 .@"unreachable",2116 .@"unreachable",
2117 .repeat,
2118 .repeat_inline,
2119 .panic,
2120 => {
2121 noreturn_src_node = statement;
2122 break :b true;
2123 },
2124
2125 // ZIR instructions that are always `void`.
2126 .breakpoint,
2127 .fence,
2128 .dbg_stmt,
2129 .ensure_result_used,
2130 .ensure_result_non_error,
2131 .@"export",
2132 .set_eval_branch_quota,
2133 .ensure_err_payload_void,
2081 .store,2134 .store,
2082 .store_node,2135 .store_node,
2083 .store_to_block_ptr,2136 .store_to_block_ptr,
2084 .store_to_inferred_ptr,2137 .store_to_inferred_ptr,
2085 .resolve_inferred_alloc,2138 .resolve_inferred_alloc,
2086 .repeat,
2087 .repeat_inline,
2088 .validate_struct_init_ptr,2139 .validate_struct_init_ptr,
2089 .validate_array_init_ptr,2140 .validate_array_init_ptr,
2090 .panic,
2091 .set_align_stack,2141 .set_align_stack,
2092 .set_cold,2142 .set_cold,
2093 .set_float_mode,2143 .set_float_mode,
...@@ -2097,15 +2147,19 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -2097,15 +2147,19 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
2097 } else switch (maybe_unused_result) {2147 } else switch (maybe_unused_result) {
2098 .none => unreachable,2148 .none => unreachable,
20992149
2100 .void_value,2150 .unreachable_value => b: {
2101 .unreachable_value,2151 noreturn_src_node = statement;
2102 => true,2152 break :b true;
2153 },
2154
2155 .void_value => true,
21032156
2104 else => false,2157 else => false,
2105 };2158 };
2106 if (!elide_check) {2159 if (!elide_check) {
2107 _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement);2160 _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement);
2108 }2161 }
2162 return noreturn_src_node;
2109}2163}
21102164
2111fn genDefers(2165fn genDefers(
...@@ -2132,7 +2186,7 @@ fn genDefers(...@@ -2132,7 +2186,7 @@ fn genDefers(
2132 const prev_in_defer = gz.in_defer;2186 const prev_in_defer = gz.in_defer;
2133 gz.in_defer = true;2187 gz.in_defer = true;
2134 defer gz.in_defer = prev_in_defer;2188 defer gz.in_defer = prev_in_defer;
2135 try unusedResultExpr(gz, defer_scope.parent, expr_node);2189 _ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
2136 },2190 },
2137 .defer_error => {2191 .defer_error => {
2138 const defer_scope = scope.cast(Scope.Defer).?;2192 const defer_scope = scope.cast(Scope.Defer).?;
...@@ -2142,7 +2196,7 @@ fn genDefers(...@@ -2142,7 +2196,7 @@ fn genDefers(
2142 const prev_in_defer = gz.in_defer;2196 const prev_in_defer = gz.in_defer;
2143 gz.in_defer = true;2197 gz.in_defer = true;
2144 defer gz.in_defer = prev_in_defer;2198 defer gz.in_defer = prev_in_defer;
2145 try unusedResultExpr(gz, defer_scope.parent, expr_node);2199 _ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
2146 },2200 },
2147 .namespace => unreachable,2201 .namespace => unreachable,
2148 .top => unreachable,2202 .top => unreachable,
...@@ -2163,25 +2217,15 @@ fn checkUsed(...@@ -2163,25 +2217,15 @@ fn checkUsed(
2163 .gen_zir => scope = scope.cast(GenZir).?.parent,2217 .gen_zir => scope = scope.cast(GenZir).?.parent,
2164 .local_val => {2218 .local_val => {
2165 const s = scope.cast(Scope.LocalVal).?;2219 const s = scope.cast(Scope.LocalVal).?;
2166 switch (s.used) {2220 if (!s.used) {
2167 .used => {},2221 return astgen.failTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
2168 .fn_param => return astgen.failTok(s.token_src, "unused function parameter", .{}),
2169 .constant => return astgen.failTok(s.token_src, "unused local constant", .{}),
2170 .variable => unreachable,
2171 .loop_index => unreachable,
2172 .capture => return astgen.failTok(s.token_src, "unused capture", .{}),
2173 }2222 }
2174 scope = s.parent;2223 scope = s.parent;
2175 },2224 },
2176 .local_ptr => {2225 .local_ptr => {
2177 const s = scope.cast(Scope.LocalPtr).?;2226 const s = scope.cast(Scope.LocalPtr).?;
2178 switch (s.used) {2227 if (!s.used) {
2179 .used => {},2228 return astgen.failTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
2180 .fn_param => unreachable,
2181 .constant => return astgen.failTok(s.token_src, "unused local constant", .{}),
2182 .variable => return astgen.failTok(s.token_src, "unused local variable", .{}),
2183 .loop_index => return astgen.failTok(s.token_src, "unused loop index capture", .{}),
2184 .capture => unreachable,
2185 }2229 }
2186 scope = s.parent;2230 scope = s.parent;
2187 },2231 },
...@@ -2221,65 +2265,13 @@ fn varDecl(...@@ -2221,65 +2265,13 @@ fn varDecl(
2221 const token_tags = tree.tokens.items(.tag);2265 const token_tags = tree.tokens.items(.tag);
22222266
2223 const name_token = var_decl.ast.mut_token + 1;2267 const name_token = var_decl.ast.mut_token + 1;
2268 const ident_name_raw = tree.tokenSlice(name_token);
2269 if (mem.eql(u8, ident_name_raw, "_")) {
2270 return astgen.failTok(name_token, "'_' used as an identifier without @\"_\" syntax", .{});
2271 }
2224 const ident_name = try astgen.identAsString(name_token);2272 const ident_name = try astgen.identAsString(name_token);
22252273
2226 // Local variables shadowing detection, including function parameters.2274 try astgen.detectLocalShadowing(scope, ident_name, name_token);
2227 {
2228 var s = scope;
2229 while (true) switch (s.tag) {
2230 .local_val => {
2231 const local_val = s.cast(Scope.LocalVal).?;
2232 if (local_val.name == ident_name) {
2233 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2234 defer gpa.free(name);
2235 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{
2236 name,
2237 }, &[_]u32{
2238 try astgen.errNoteTok(
2239 local_val.token_src,
2240 "previously declared here",
2241 .{},
2242 ),
2243 });
2244 }
2245 s = local_val.parent;
2246 },
2247 .local_ptr => {
2248 const local_ptr = s.cast(Scope.LocalPtr).?;
2249 if (local_ptr.name == ident_name) {
2250 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2251 defer gpa.free(name);
2252 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{
2253 name,
2254 }, &[_]u32{
2255 try astgen.errNoteTok(
2256 local_ptr.token_src,
2257 "previously declared here",
2258 .{},
2259 ),
2260 });
2261 }
2262 s = local_ptr.parent;
2263 },
2264 .namespace => {
2265 const ns = s.cast(Scope.Namespace).?;
2266 const decl_node = ns.decls.get(ident_name) orelse {
2267 s = ns.parent;
2268 continue;
2269 };
2270 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2271 defer gpa.free(name);
2272 return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{
2273 name,
2274 }, &[_]u32{
2275 try astgen.errNoteNode(decl_node, "declared here", .{}),
2276 });
2277 },
2278 .gen_zir => s = s.cast(GenZir).?.parent,
2279 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
2280 .top => break,
2281 };
2282 }
22832275
2284 if (var_decl.ast.init_node == 0) {2276 if (var_decl.ast.init_node == 0) {
2285 return astgen.failNode(node, "variables must be initialized", .{});2277 return astgen.failNode(node, "variables must be initialized", .{});
...@@ -2303,7 +2295,8 @@ fn varDecl(...@@ -2303,7 +2295,8 @@ fn varDecl(
2303 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0) .{2295 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0) .{
2304 .ty = try typeExpr(gz, scope, var_decl.ast.type_node),2296 .ty = try typeExpr(gz, scope, var_decl.ast.type_node),
2305 } else .none;2297 } else .none;
2306 const init_inst = try expr(gz, scope, result_loc, var_decl.ast.init_node);2298 const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);
2299
2307 const sub_scope = try block_arena.create(Scope.LocalVal);2300 const sub_scope = try block_arena.create(Scope.LocalVal);
2308 sub_scope.* = .{2301 sub_scope.* = .{
2309 .parent = scope,2302 .parent = scope,
...@@ -2311,7 +2304,7 @@ fn varDecl(...@@ -2311,7 +2304,7 @@ fn varDecl(
2311 .name = ident_name,2304 .name = ident_name,
2312 .inst = init_inst,2305 .inst = init_inst,
2313 .token_src = name_token,2306 .token_src = name_token,
2314 .used = .constant,2307 .id_cat = .@"local constant",
2315 };2308 };
2316 return &sub_scope.base;2309 return &sub_scope.base;
2317 }2310 }
...@@ -2353,7 +2346,8 @@ fn varDecl(...@@ -2353,7 +2346,8 @@ fn varDecl(
2353 init_scope.rl_ptr = alloc;2346 init_scope.rl_ptr = alloc;
2354 }2347 }
2355 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };2348 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };
2356 const init_inst = try expr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node);2349 const init_inst = try reachableExpr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node, node);
2350
2357 const zir_tags = astgen.instructions.items(.tag);2351 const zir_tags = astgen.instructions.items(.tag);
2358 const zir_datas = astgen.instructions.items(.data);2352 const zir_datas = astgen.instructions.items(.data);
23592353
...@@ -2379,7 +2373,7 @@ fn varDecl(...@@ -2379,7 +2373,7 @@ fn varDecl(
2379 .name = ident_name,2373 .name = ident_name,
2380 .inst = init_inst,2374 .inst = init_inst,
2381 .token_src = name_token,2375 .token_src = name_token,
2382 .used = .constant,2376 .id_cat = .@"local constant",
2383 };2377 };
2384 return &sub_scope.base;2378 return &sub_scope.base;
2385 }2379 }
...@@ -2409,7 +2403,7 @@ fn varDecl(...@@ -2409,7 +2403,7 @@ fn varDecl(
2409 .ptr = init_scope.rl_ptr,2403 .ptr = init_scope.rl_ptr,
2410 .token_src = name_token,2404 .token_src = name_token,
2411 .maybe_comptime = true,2405 .maybe_comptime = true,
2412 .used = .constant,2406 .id_cat = .@"local constant",
2413 };2407 };
2414 return &sub_scope.base;2408 return &sub_scope.base;
2415 },2409 },
...@@ -2454,7 +2448,7 @@ fn varDecl(...@@ -2454,7 +2448,7 @@ fn varDecl(
2454 resolve_inferred_alloc = alloc;2448 resolve_inferred_alloc = alloc;
2455 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };2449 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };
2456 };2450 };
2457 _ = try expr(gz, scope, var_data.result_loc, var_decl.ast.init_node);2451 _ = try reachableExpr(gz, scope, var_data.result_loc, var_decl.ast.init_node, node);
2458 if (resolve_inferred_alloc != .none) {2452 if (resolve_inferred_alloc != .none) {
2459 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);2453 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
2460 }2454 }
...@@ -2466,7 +2460,7 @@ fn varDecl(...@@ -2466,7 +2460,7 @@ fn varDecl(
2466 .ptr = var_data.alloc,2460 .ptr = var_data.alloc,
2467 .token_src = name_token,2461 .token_src = name_token,
2468 .maybe_comptime = is_comptime,2462 .maybe_comptime = is_comptime,
2469 .used = .variable,2463 .id_cat = .@"local variable",
2470 };2464 };
2471 return &sub_scope.base;2465 return &sub_scope.base;
2472 },2466 },
...@@ -2956,7 +2950,11 @@ fn fnDecl(...@@ -2956,7 +2950,11 @@ fn fnDecl(
2956 var it = fn_proto.iterate(tree.*);2950 var it = fn_proto.iterate(tree.*);
2957 while (it.next()) |param| : (i += 1) {2951 while (it.next()) |param| : (i += 1) {
2958 const name_token = param.name_token orelse {2952 const name_token = param.name_token orelse {
2959 return astgen.failNode(param.type_expr, "missing parameter name", .{});2953 if (param.anytype_ellipsis3) |tok| {
2954 return astgen.failTok(tok, "missing parameter name", .{});
2955 } else {
2956 return astgen.failNode(param.type_expr, "missing parameter name", .{});
2957 }
2960 };2958 };
2961 if (param.type_expr != 0)2959 if (param.type_expr != 0)
2962 _ = try typeExpr(&fn_gz, params_scope, param.type_expr);2960 _ = try typeExpr(&fn_gz, params_scope, param.type_expr);
...@@ -2965,7 +2963,7 @@ fn fnDecl(...@@ -2965,7 +2963,7 @@ fn fnDecl(
2965 const param_name = try astgen.identAsString(name_token);2963 const param_name = try astgen.identAsString(name_token);
2966 // Create an arg instruction. This is needed to emit a semantic analysis2964 // Create an arg instruction. This is needed to emit a semantic analysis
2967 // error for shadowing decls.2965 // error for shadowing decls.
2968 // TODO emit a compile error here for shadowing locals.2966 try astgen.detectLocalShadowing(params_scope, param_name, name_token);
2969 const arg_inst = try fn_gz.addStrTok(.arg, param_name, name_token);2967 const arg_inst = try fn_gz.addStrTok(.arg, param_name, name_token);
2970 const sub_scope = try astgen.arena.create(Scope.LocalVal);2968 const sub_scope = try astgen.arena.create(Scope.LocalVal);
2971 sub_scope.* = .{2969 sub_scope.* = .{
...@@ -2974,7 +2972,7 @@ fn fnDecl(...@@ -2974,7 +2972,7 @@ fn fnDecl(
2974 .name = param_name,2972 .name = param_name,
2975 .inst = arg_inst,2973 .inst = arg_inst,
2976 .token_src = name_token,2974 .token_src = name_token,
2977 .used = .fn_param,2975 .id_cat = .@"function parameter",
2978 };2976 };
2979 params_scope = &sub_scope.base;2977 params_scope = &sub_scope.base;
29802978
...@@ -4005,7 +4003,18 @@ fn containerDecl(...@@ -4005,7 +4003,18 @@ fn containerDecl(
4005 return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{});4003 return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{});
4006 }4004 }
4007 if (member.ast.type_expr != 0) {4005 if (member.ast.type_expr != 0) {
4008 return astgen.failNode(member.ast.type_expr, "enum fields do not have types", .{});4006 return astgen.failNodeNotes(
4007 member.ast.type_expr,
4008 "enum fields do not have types",
4009 .{},
4010 &[_]u32{
4011 try astgen.errNoteNode(
4012 node,
4013 "consider 'union(enum)' here to make it a tagged union",
4014 .{},
4015 ),
4016 },
4017 );
4009 }4018 }
4010 // Alignment expressions in enums are caught by the parser.4019 // Alignment expressions in enums are caught by the parser.
4011 assert(member.ast.align_expr == 0);4020 assert(member.ast.align_expr == 0);
...@@ -4523,7 +4532,7 @@ fn tryExpr(...@@ -4523,7 +4532,7 @@ fn tryExpr(
4523 return astgen.failNode(node, "invalid 'try' outside function scope", .{});4532 return astgen.failNode(node, "invalid 'try' outside function scope", .{});
4524 };4533 };
45254534
4526 if (parent_gz.in_defer) return astgen.failNode(node, "try is not allowed inside defer expression", .{});4535 if (parent_gz.in_defer) return astgen.failNode(node, "'try' not allowed inside defer expression", .{});
45274536
4528 var block_scope = parent_gz.makeSubBlock(scope);4537 var block_scope = parent_gz.makeSubBlock(scope);
4529 block_scope.setBreakResultLoc(rl);4538 block_scope.setBreakResultLoc(rl);
...@@ -4638,7 +4647,7 @@ fn orelseCatchExpr(...@@ -4638,7 +4647,7 @@ fn orelseCatchExpr(
4638 .name = err_name,4647 .name = err_name,
4639 .inst = try then_scope.addUnNode(unwrap_code_op, operand, node),4648 .inst = try then_scope.addUnNode(unwrap_code_op, operand, node),
4640 .token_src = payload,4649 .token_src = payload,
4641 .used = .capture,4650 .id_cat = .@"capture",
4642 };4651 };
4643 break :blk &err_val_scope.base;4652 break :blk &err_val_scope.base;
4644 };4653 };
...@@ -4930,7 +4939,7 @@ fn ifExpr(...@@ -4930,7 +4939,7 @@ fn ifExpr(
4930 .name = ident_name,4939 .name = ident_name,
4931 .inst = payload_inst,4940 .inst = payload_inst,
4932 .token_src = payload_token,4941 .token_src = payload_token,
4933 .used = .capture,4942 .id_cat = .@"capture",
4934 };4943 };
4935 break :s &payload_val_scope.base;4944 break :s &payload_val_scope.base;
4936 } else {4945 } else {
...@@ -4952,7 +4961,7 @@ fn ifExpr(...@@ -4952,7 +4961,7 @@ fn ifExpr(
4952 .name = ident_name,4961 .name = ident_name,
4953 .inst = payload_inst,4962 .inst = payload_inst,
4954 .token_src = ident_token,4963 .token_src = ident_token,
4955 .used = .capture,4964 .id_cat = .@"capture",
4956 };4965 };
4957 break :s &payload_val_scope.base;4966 break :s &payload_val_scope.base;
4958 } else {4967 } else {
...@@ -4993,7 +5002,7 @@ fn ifExpr(...@@ -4993,7 +5002,7 @@ fn ifExpr(
4993 .name = ident_name,5002 .name = ident_name,
4994 .inst = payload_inst,5003 .inst = payload_inst,
4995 .token_src = error_token,5004 .token_src = error_token,
4996 .used = .capture,5005 .id_cat = .@"capture",
4997 };5006 };
4998 break :s &payload_val_scope.base;5007 break :s &payload_val_scope.base;
4999 } else {5008 } else {
...@@ -5187,7 +5196,7 @@ fn whileExpr(...@@ -5187,7 +5196,7 @@ fn whileExpr(
5187 .name = ident_name,5196 .name = ident_name,
5188 .inst = payload_inst,5197 .inst = payload_inst,
5189 .token_src = payload_token,5198 .token_src = payload_token,
5190 .used = .capture,5199 .id_cat = .@"capture",
5191 };5200 };
5192 break :s &payload_val_scope.base;5201 break :s &payload_val_scope.base;
5193 } else {5202 } else {
...@@ -5209,7 +5218,7 @@ fn whileExpr(...@@ -5209,7 +5218,7 @@ fn whileExpr(
5209 .name = ident_name,5218 .name = ident_name,
5210 .inst = payload_inst,5219 .inst = payload_inst,
5211 .token_src = ident_token,5220 .token_src = ident_token,
5212 .used = .capture,5221 .id_cat = .@"capture",
5213 };5222 };
5214 break :s &payload_val_scope.base;5223 break :s &payload_val_scope.base;
5215 } else {5224 } else {
...@@ -5266,7 +5275,7 @@ fn whileExpr(...@@ -5266,7 +5275,7 @@ fn whileExpr(
5266 .name = ident_name,5275 .name = ident_name,
5267 .inst = payload_inst,5276 .inst = payload_inst,
5268 .token_src = error_token,5277 .token_src = error_token,
5269 .used = .capture,5278 .id_cat = .@"capture",
5270 };5279 };
5271 break :s &payload_val_scope.base;5280 break :s &payload_val_scope.base;
5272 } else {5281 } else {
...@@ -5405,7 +5414,7 @@ fn forExpr(...@@ -5405,7 +5414,7 @@ fn forExpr(
5405 .name = name_str_index,5414 .name = name_str_index,
5406 .inst = payload_inst,5415 .inst = payload_inst,
5407 .token_src = ident,5416 .token_src = ident,
5408 .used = .capture,5417 .id_cat = .@"capture",
5409 };5418 };
5410 payload_sub_scope = &payload_val_scope.base;5419 payload_sub_scope = &payload_val_scope.base;
5411 } else if (is_ptr) {5420 } else if (is_ptr) {
...@@ -5429,7 +5438,7 @@ fn forExpr(...@@ -5429,7 +5438,7 @@ fn forExpr(
5429 .ptr = index_ptr,5438 .ptr = index_ptr,
5430 .token_src = index_token,5439 .token_src = index_token,
5431 .maybe_comptime = is_inline,5440 .maybe_comptime = is_inline,
5432 .used = .loop_index,5441 .id_cat = .@"loop index capture",
5433 };5442 };
5434 break :blk &index_scope.base;5443 break :blk &index_scope.base;
5435 };5444 };
...@@ -5529,7 +5538,7 @@ fn switchExpr(...@@ -5529,7 +5538,7 @@ fn switchExpr(
5529 &[_]u32{5538 &[_]u32{
5530 try astgen.errNoteTok(5539 try astgen.errNoteTok(
5531 src,5540 src,
5532 "previous else prong is here",5541 "previous else prong here",
5533 .{},5542 .{},
5534 ),5543 ),
5535 },5544 },
...@@ -5542,12 +5551,12 @@ fn switchExpr(...@@ -5542,12 +5551,12 @@ fn switchExpr(
5542 &[_]u32{5551 &[_]u32{
5543 try astgen.errNoteTok(5552 try astgen.errNoteTok(
5544 case_src,5553 case_src,
5545 "else prong is here",5554 "else prong here",
5546 .{},5555 .{},
5547 ),5556 ),
5548 try astgen.errNoteTok(5557 try astgen.errNoteTok(
5549 some_underscore,5558 some_underscore,
5550 "'_' prong is here",5559 "'_' prong here",
5551 .{},5560 .{},
5552 ),5561 ),
5553 },5562 },
...@@ -5570,7 +5579,7 @@ fn switchExpr(...@@ -5570,7 +5579,7 @@ fn switchExpr(
5570 &[_]u32{5579 &[_]u32{
5571 try astgen.errNoteTok(5580 try astgen.errNoteTok(
5572 src,5581 src,
5573 "previous '_' prong is here",5582 "previous '_' prong here",
5574 .{},5583 .{},
5575 ),5584 ),
5576 },5585 },
...@@ -5583,12 +5592,12 @@ fn switchExpr(...@@ -5583,12 +5592,12 @@ fn switchExpr(
5583 &[_]u32{5592 &[_]u32{
5584 try astgen.errNoteTok(5593 try astgen.errNoteTok(
5585 some_else,5594 some_else,
5586 "else prong is here",5595 "else prong here",
5587 .{},5596 .{},
5588 ),5597 ),
5589 try astgen.errNoteTok(5598 try astgen.errNoteTok(
5590 case_src,5599 case_src,
5591 "'_' prong is here",5600 "'_' prong here",
5592 .{},5601 .{},
5593 ),5602 ),
5594 },5603 },
...@@ -5674,7 +5683,7 @@ fn switchExpr(...@@ -5674,7 +5683,7 @@ fn switchExpr(
5674 .name = capture_name,5683 .name = capture_name,
5675 .inst = capture,5684 .inst = capture,
5676 .token_src = payload_token,5685 .token_src = payload_token,
5677 .used = .capture,5686 .id_cat = .@"capture",
5678 };5687 };
5679 break :blk &capture_val_scope.base;5688 break :blk &capture_val_scope.base;
5680 };5689 };
...@@ -5768,7 +5777,7 @@ fn switchExpr(...@@ -5768,7 +5777,7 @@ fn switchExpr(
5768 .name = capture_name,5777 .name = capture_name,
5769 .inst = capture,5778 .inst = capture,
5770 .token_src = payload_token,5779 .token_src = payload_token,
5771 .used = .capture,5780 .id_cat = .@"capture",
5772 };5781 };
5773 break :blk &capture_val_scope.base;5782 break :blk &capture_val_scope.base;
5774 };5783 };
...@@ -6150,10 +6159,11 @@ fn identifier(...@@ -6150,10 +6159,11 @@ fn identifier(
6150 const main_tokens = tree.nodes.items(.main_token);6159 const main_tokens = tree.nodes.items(.main_token);
61516160
6152 const ident_token = main_tokens[ident];6161 const ident_token = main_tokens[ident];
6153 const ident_name = try astgen.identifierTokenString(ident_token);6162 const ident_name_raw = tree.tokenSlice(ident_token);
6154 if (mem.eql(u8, ident_name, "_")) {6163 if (mem.eql(u8, ident_name_raw, "_")) {
6155 return astgen.failNode(ident, "'_' may not be used as an identifier", .{});6164 return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{});
6156 }6165 }
6166 const ident_name = try astgen.identifierTokenString(ident_token);
61576167
6158 if (simple_types.get(ident_name)) |zir_const_ref| {6168 if (simple_types.get(ident_name)) |zir_const_ref| {
6159 return rvalue(gz, rl, zir_const_ref, ident);6169 return rvalue(gz, rl, zir_const_ref, ident);
...@@ -6197,7 +6207,7 @@ fn identifier(...@@ -6197,7 +6207,7 @@ fn identifier(
6197 const local_val = s.cast(Scope.LocalVal).?;6207 const local_val = s.cast(Scope.LocalVal).?;
61986208
6199 if (local_val.name == name_str_index) {6209 if (local_val.name == name_str_index) {
6200 local_val.used = .used;6210 local_val.used = true;
6201 // Captures of non-locals need to be emitted as decl_val or decl_ref.6211 // Captures of non-locals need to be emitted as decl_val or decl_ref.
6202 // This *might* be capturable depending on if it is comptime known.6212 // This *might* be capturable depending on if it is comptime known.
6203 if (!hit_namespace) {6213 if (!hit_namespace) {
...@@ -6209,7 +6219,7 @@ fn identifier(...@@ -6209,7 +6219,7 @@ fn identifier(
6209 .local_ptr => {6219 .local_ptr => {
6210 const local_ptr = s.cast(Scope.LocalPtr).?;6220 const local_ptr = s.cast(Scope.LocalPtr).?;
6211 if (local_ptr.name == name_str_index) {6221 if (local_ptr.name == name_str_index) {
6212 local_ptr.used = .used;6222 local_ptr.used = true;
6213 if (hit_namespace) {6223 if (hit_namespace) {
6214 if (local_ptr.maybe_comptime)6224 if (local_ptr.maybe_comptime)
6215 break6225 break
...@@ -6333,20 +6343,76 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {...@@ -6333,20 +6343,76 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
6333 const main_token = main_tokens[node];6343 const main_token = main_tokens[node];
6334 const slice = tree.tokenSlice(main_token);6344 const slice = tree.tokenSlice(main_token);
63356345
6336 var bad_index: usize = undefined;6346 switch (std.zig.parseCharLiteral(slice)) {
6337 const value = std.zig.parseCharLiteral(slice, &bad_index) catch |err| switch (err) {6347 .success => |codepoint| {
6338 error.InvalidCharacter => {6348 const result = try gz.addInt(codepoint);
6339 const bad_byte = slice[bad_index];6349 return rvalue(gz, rl, result, node);
6350 },
6351 .invalid_escape_character => |bad_index| {
6340 return astgen.failOff(6352 return astgen.failOff(
6341 main_token,6353 main_token,
6342 @intCast(u32, bad_index),6354 @intCast(u32, bad_index),
6343 "invalid character: '{c}'\n",6355 "invalid escape character: '{c}'",
6344 .{bad_byte},6356 .{slice[bad_index]},
6345 );6357 );
6346 },6358 },
6347 };6359 .expected_hex_digit => |bad_index| {
6348 const result = try gz.addInt(value);6360 return astgen.failOff(
6349 return rvalue(gz, rl, result, node);6361 main_token,
6362 @intCast(u32, bad_index),
6363 "expected hex digit, found '{c}'",
6364 .{slice[bad_index]},
6365 );
6366 },
6367 .empty_unicode_escape_sequence => |bad_index| {
6368 return astgen.failOff(
6369 main_token,
6370 @intCast(u32, bad_index),
6371 "empty unicode escape sequence",
6372 .{},
6373 );
6374 },
6375 .expected_hex_digit_or_rbrace => |bad_index| {
6376 return astgen.failOff(
6377 main_token,
6378 @intCast(u32, bad_index),
6379 "expected hex digit or '}}', found '{c}'",
6380 .{slice[bad_index]},
6381 );
6382 },
6383 .unicode_escape_overflow => |bad_index| {
6384 return astgen.failOff(
6385 main_token,
6386 @intCast(u32, bad_index),
6387 "unicode escape too large to be a valid codepoint",
6388 .{},
6389 );
6390 },
6391 .expected_lbrace => |bad_index| {
6392 return astgen.failOff(
6393 main_token,
6394 @intCast(u32, bad_index),
6395 "expected '{{', found '{c}",
6396 .{slice[bad_index]},
6397 );
6398 },
6399 .expected_end => |bad_index| {
6400 return astgen.failOff(
6401 main_token,
6402 @intCast(u32, bad_index),
6403 "expected ending single quote ('), found '{c}",
6404 .{slice[bad_index]},
6405 );
6406 },
6407 .invalid_character => |bad_index| {
6408 return astgen.failOff(
6409 main_token,
6410 @intCast(u32, bad_index),
6411 "invalid byte in character literal: '{c}'",
6412 .{slice[bad_index]},
6413 );
6414 },
6415 }
6350}6416}
63516417
6352fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {6418fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
...@@ -6489,7 +6555,7 @@ fn asmExpr(...@@ -6489,7 +6555,7 @@ fn asmExpr(
6489 .local_val => {6555 .local_val => {
6490 const local_val = s.cast(Scope.LocalVal).?;6556 const local_val = s.cast(Scope.LocalVal).?;
6491 if (local_val.name == str_index) {6557 if (local_val.name == str_index) {
6492 local_val.used = .used;6558 local_val.used = true;
6493 break;6559 break;
6494 }6560 }
6495 s = local_val.parent;6561 s = local_val.parent;
...@@ -6497,7 +6563,7 @@ fn asmExpr(...@@ -6497,7 +6563,7 @@ fn asmExpr(
6497 .local_ptr => {6563 .local_ptr => {
6498 const local_ptr = s.cast(Scope.LocalPtr).?;6564 const local_ptr = s.cast(Scope.LocalPtr).?;
6499 if (local_ptr.name == str_index) {6565 if (local_ptr.name == str_index) {
6500 local_ptr.used = .used;6566 local_ptr.used = true;
6501 break;6567 break;
6502 }6568 }
6503 s = local_ptr.parent;6569 s = local_ptr.parent;
...@@ -6585,14 +6651,14 @@ fn as(...@@ -6585,14 +6651,14 @@ fn as(
6585 const dest_type = try typeExpr(gz, scope, lhs);6651 const dest_type = try typeExpr(gz, scope, lhs);
6586 switch (rl) {6652 switch (rl) {
6587 .none, .none_or_ref, .discard, .ref, .ty => {6653 .none, .none_or_ref, .discard, .ref, .ty => {
6588 const result = try expr(gz, scope, .{ .ty = dest_type }, rhs);6654 const result = try reachableExpr(gz, scope, .{ .ty = dest_type }, rhs, node);
6589 return rvalue(gz, rl, result, node);6655 return rvalue(gz, rl, result, node);
6590 },6656 },
6591 .ptr, .inferred_ptr => |result_ptr| {6657 .ptr, .inferred_ptr => |result_ptr| {
6592 return asRlPtr(gz, scope, rl, result_ptr, rhs, dest_type);6658 return asRlPtr(gz, scope, rl, node, result_ptr, rhs, dest_type);
6593 },6659 },
6594 .block_ptr => |block_scope| {6660 .block_ptr => |block_scope| {
6595 return asRlPtr(gz, scope, rl, block_scope.rl_ptr, rhs, dest_type);6661 return asRlPtr(gz, scope, rl, node, block_scope.rl_ptr, rhs, dest_type);
6596 },6662 },
6597 }6663 }
6598}6664}
...@@ -6646,6 +6712,7 @@ fn asRlPtr(...@@ -6646,6 +6712,7 @@ fn asRlPtr(
6646 parent_gz: *GenZir,6712 parent_gz: *GenZir,
6647 scope: *Scope,6713 scope: *Scope,
6648 rl: ResultLoc,6714 rl: ResultLoc,
6715 src_node: ast.Node.Index,
6649 result_ptr: Zir.Inst.Ref,6716 result_ptr: Zir.Inst.Ref,
6650 operand_node: ast.Node.Index,6717 operand_node: ast.Node.Index,
6651 dest_type: Zir.Inst.Ref,6718 dest_type: Zir.Inst.Ref,
...@@ -6659,7 +6726,7 @@ fn asRlPtr(...@@ -6659,7 +6726,7 @@ fn asRlPtr(
6659 defer as_scope.instructions.deinit(astgen.gpa);6726 defer as_scope.instructions.deinit(astgen.gpa);
66606727
6661 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);6728 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);
6662 const result = try expr(&as_scope, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node);6729 const result = try reachableExpr(&as_scope, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node, src_node);
6663 const parent_zir = &parent_gz.instructions;6730 const parent_zir = &parent_gz.instructions;
6664 if (as_scope.rvalue_rl_count == 1) {6731 if (as_scope.rvalue_rl_count == 1) {
6665 // Busted! This expression didn't actually need a pointer.6732 // Busted! This expression didn't actually need a pointer.
...@@ -6738,13 +6805,14 @@ fn typeOf(...@@ -6738,13 +6805,14 @@ fn typeOf(
6738 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});6805 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});
6739 }6806 }
6740 if (params.len == 1) {6807 if (params.len == 1) {
6741 const result = try gz.addUnNode(.typeof, try expr(gz, scope, .none, params[0]), node);6808 const expr_result = try reachableExpr(gz, scope, .none, params[0], node);
6809 const result = try gz.addUnNode(.typeof, expr_result, node);
6742 return rvalue(gz, rl, result, node);6810 return rvalue(gz, rl, result, node);
6743 }6811 }
6744 const arena = gz.astgen.arena;6812 const arena = gz.astgen.arena;
6745 var items = try arena.alloc(Zir.Inst.Ref, params.len);6813 var items = try arena.alloc(Zir.Inst.Ref, params.len);
6746 for (params) |param, param_i| {6814 for (params) |param, param_i| {
6747 items[param_i] = try expr(gz, scope, .none, param);6815 items[param_i] = try reachableExpr(gz, scope, .none, param, node);
6748 }6816 }
67496817
6750 const result = try gz.addExtendedMultiOp(.typeof_peer, node, items);6818 const result = try gz.addExtendedMultiOp(.typeof_peer, node, items);
...@@ -6778,7 +6846,7 @@ fn builtinCall(...@@ -6778,7 +6846,7 @@ fn builtinCall(
6778 if (info.param_count) |expected| {6846 if (info.param_count) |expected| {
6779 if (expected != params.len) {6847 if (expected != params.len) {
6780 const s = if (expected == 1) "" else "s";6848 const s = if (expected == 1) "" else "s";
6781 return astgen.failNode(node, "expected {d} parameter{s}, found {d}", .{6849 return astgen.failNode(node, "expected {d} argument{s}, found {d}", .{
6782 expected, s, params.len,6850 expected, s, params.len,
6783 });6851 });
6784 }6852 }
...@@ -6796,8 +6864,13 @@ fn builtinCall(...@@ -6796,8 +6864,13 @@ fn builtinCall(
6796 }6864 }
6797 const str_lit_token = main_tokens[operand_node];6865 const str_lit_token = main_tokens[operand_node];
6798 const str = try astgen.strLitAsString(str_lit_token);6866 const str = try astgen.strLitAsString(str_lit_token);
6799 try astgen.imports.put(astgen.gpa, str.index, {});
6800 const result = try gz.addStrTok(.import, str.index, str_lit_token);6867 const result = try gz.addStrTok(.import, str.index, str_lit_token);
6868 if (gz.refToIndex(result)) |import_inst_index| {
6869 const gop = try astgen.imports.getOrPut(astgen.gpa, str.index);
6870 if (!gop.found_existing) {
6871 gop.value_ptr.* = import_inst_index;
6872 }
6873 }
6801 return rvalue(gz, rl, result, node);6874 return rvalue(gz, rl, result, node);
6802 },6875 },
6803 .compile_log => {6876 .compile_log => {
...@@ -6846,7 +6919,7 @@ fn builtinCall(...@@ -6846,7 +6919,7 @@ fn builtinCall(
6846 .local_val => {6919 .local_val => {
6847 const local_val = s.cast(Scope.LocalVal).?;6920 const local_val = s.cast(Scope.LocalVal).?;
6848 if (local_val.name == decl_name) {6921 if (local_val.name == decl_name) {
6849 local_val.used = .used;6922 local_val.used = true;
6850 break;6923 break;
6851 }6924 }
6852 s = local_val.parent;6925 s = local_val.parent;
...@@ -6856,7 +6929,7 @@ fn builtinCall(...@@ -6856,7 +6929,7 @@ fn builtinCall(
6856 if (local_ptr.name == decl_name) {6929 if (local_ptr.name == decl_name) {
6857 if (!local_ptr.maybe_comptime)6930 if (!local_ptr.maybe_comptime)
6858 return astgen.failNode(params[0], "unable to export runtime-known value", .{});6931 return astgen.failNode(params[0], "unable to export runtime-known value", .{});
6859 local_ptr.used = .used;6932 local_ptr.used = true;
6860 break;6933 break;
6861 }6934 }
6862 s = local_ptr.parent;6935 s = local_ptr.parent;
...@@ -8423,15 +8496,15 @@ const Scope = struct {...@@ -8423,15 +8496,15 @@ const Scope = struct {
8423 top,8496 top,
8424 };8497 };
84258498
8426 // either .used or the type of the var/constant8499 /// The category of identifier. These tag names are user-visible in compile errors.
8427 const Used = enum {8500 const IdCat = enum {
8428 fn_param,8501 @"function parameter",
8429 constant,8502 @"local constant",
8430 variable,8503 @"local variable",
8431 loop_index,8504 @"loop index capture",
8432 capture,8505 @"capture",
8433 used,
8434 };8506 };
8507
8435 /// This is always a `const` local and importantly the `inst` is a value type, not a pointer.8508 /// This is always a `const` local and importantly the `inst` is a value type, not a pointer.
8436 /// This structure lives as long as the AST generation of the Block8509 /// This structure lives as long as the AST generation of the Block
8437 /// node that contains the variable.8510 /// node that contains the variable.
...@@ -8446,8 +8519,9 @@ const Scope = struct {...@@ -8446,8 +8519,9 @@ const Scope = struct {
8446 token_src: ast.TokenIndex,8519 token_src: ast.TokenIndex,
8447 /// String table index.8520 /// String table index.
8448 name: u32,8521 name: u32,
8449 /// has this variable been referenced?8522 id_cat: IdCat,
8450 used: Used,8523 /// Track whether the name has been referenced.
8524 used: bool = false,
8451 };8525 };
84528526
8453 /// This could be a `const` or `var` local. It has a pointer instead of a value.8527 /// This could be a `const` or `var` local. It has a pointer instead of a value.
...@@ -8464,10 +8538,12 @@ const Scope = struct {...@@ -8464,10 +8538,12 @@ const Scope = struct {
8464 token_src: ast.TokenIndex,8538 token_src: ast.TokenIndex,
8465 /// String table index.8539 /// String table index.
8466 name: u32,8540 name: u32,
8467 /// true means we find out during Sema whether the value is comptime. false means it is already known at AstGen the value is runtime-known.8541 id_cat: IdCat,
8542 /// true means we find out during Sema whether the value is comptime.
8543 /// false means it is already known at AstGen the value is runtime-known.
8468 maybe_comptime: bool,8544 maybe_comptime: bool,
8469 /// has this variable been referenced?8545 /// Track whether the name has been referenced.
8470 used: Used,8546 used: bool = false,
8471 };8547 };
84728548
8473 const Defer = struct {8549 const Defer = struct {
...@@ -9558,6 +9634,71 @@ fn declareNewName(...@@ -9558,6 +9634,71 @@ fn declareNewName(
9558 }9634 }
9559}9635}
95609636
9637/// Local variables shadowing detection, including function parameters.
9638fn detectLocalShadowing(
9639 astgen: *AstGen,
9640 scope: *Scope,
9641 ident_name: u32,
9642 name_token: ast.TokenIndex,
9643) !void {
9644 const gpa = astgen.gpa;
9645
9646 var s = scope;
9647 while (true) switch (s.tag) {
9648 .local_val => {
9649 const local_val = s.cast(Scope.LocalVal).?;
9650 if (local_val.name == ident_name) {
9651 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
9652 defer gpa.free(name);
9653 return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
9654 @tagName(local_val.id_cat), name,
9655 }, &[_]u32{
9656 try astgen.errNoteTok(
9657 local_val.token_src,
9658 "previous declaration here",
9659 .{},
9660 ),
9661 });
9662 }
9663 s = local_val.parent;
9664 },
9665 .local_ptr => {
9666 const local_ptr = s.cast(Scope.LocalPtr).?;
9667 if (local_ptr.name == ident_name) {
9668 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
9669 defer gpa.free(name);
9670 return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
9671 @tagName(local_ptr.id_cat), name,
9672 }, &[_]u32{
9673 try astgen.errNoteTok(
9674 local_ptr.token_src,
9675 "previous declaration here",
9676 .{},
9677 ),
9678 });
9679 }
9680 s = local_ptr.parent;
9681 },
9682 .namespace => {
9683 const ns = s.cast(Scope.Namespace).?;
9684 const decl_node = ns.decls.get(ident_name) orelse {
9685 s = ns.parent;
9686 continue;
9687 };
9688 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
9689 defer gpa.free(name);
9690 return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{
9691 name,
9692 }, &[_]u32{
9693 try astgen.errNoteNode(decl_node, "declared here", .{}),
9694 });
9695 },
9696 .gen_zir => s = s.cast(GenZir).?.parent,
9697 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
9698 .top => break,
9699 };
9700}
9701
9561fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {9702fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {
9562 var i = astgen.source_offset;9703 var i = astgen.source_offset;
9563 var line = astgen.source_line;9704 var line = astgen.source_line;
src/Compilation.zig+87-31
...@@ -670,6 +670,7 @@ pub const InitOptions = struct {...@@ -670,6 +670,7 @@ pub const InitOptions = struct {
670 use_llvm: ?bool = null,670 use_llvm: ?bool = null,
671 use_lld: ?bool = null,671 use_lld: ?bool = null,
672 use_clang: ?bool = null,672 use_clang: ?bool = null,
673 use_stage1: ?bool = null,
673 rdynamic: bool = false,674 rdynamic: bool = false,
674 strip: bool = false,675 strip: bool = false,
675 single_threaded: bool = false,676 single_threaded: bool = false,
...@@ -807,8 +808,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -807,8 +808,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
807808
808 const ofmt = options.object_format orelse options.target.getObjectFormat();809 const ofmt = options.object_format orelse options.target.getObjectFormat();
809810
811 const use_stage1 = options.use_stage1 orelse blk: {
812 if (build_options.omit_stage2)
813 break :blk true;
814 if (options.use_llvm) |use_llvm| {
815 if (!use_llvm) {
816 break :blk false;
817 }
818 }
819 break :blk build_options.is_stage1;
820 };
821
810 // Make a decision on whether to use LLVM or our own backend.822 // Make a decision on whether to use LLVM or our own backend.
811 const use_llvm = if (options.use_llvm) |explicit| explicit else blk: {823 const use_llvm = build_options.have_llvm and blk: {
824 if (options.use_llvm) |explicit|
825 break :blk explicit;
826
812 // If we have no zig code to compile, no need for LLVM.827 // If we have no zig code to compile, no need for LLVM.
813 if (options.root_pkg == null)828 if (options.root_pkg == null)
814 break :blk false;829 break :blk false;
...@@ -817,18 +832,24 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -817,18 +832,24 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
817 if (ofmt == .c)832 if (ofmt == .c)
818 break :blk false;833 break :blk false;
819834
820 // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend835 // The stage1 compiler depends on the stage1 C++ LLVM backend
821 // to compile zig code.836 // to compile zig code.
822 if (build_options.is_stage1)837 if (use_stage1)
838 break :blk true;
839
840 // Prefer LLVM for release builds as long as it supports the target architecture.
841 if (options.optimize_mode != .Debug and target_util.hasLlvmSupport(options.target))
823 break :blk true;842 break :blk true;
824843
825 // We would want to prefer LLVM for release builds when it is available, however
826 // we don't have an LLVM backend yet :)
827 // We would also want to prefer LLVM for architectures that we don't have self-hosted support for too.
828 break :blk false;844 break :blk false;
829 };845 };
830 if (!use_llvm and options.machine_code_model != .default) {846 if (!use_llvm) {
831 return error.MachineCodeModelNotSupported;847 if (options.use_llvm == true) {
848 return error.ZigCompilerNotBuiltWithLLVMExtensions;
849 }
850 if (options.machine_code_model != .default) {
851 return error.MachineCodeModelNotSupportedWithoutLlvm;
852 }
832 }853 }
833854
834 const tsan = options.want_tsan orelse false;855 const tsan = options.want_tsan orelse false;
...@@ -1344,6 +1365,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1344,6 +1365,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1344 .subsystem = options.subsystem,1365 .subsystem = options.subsystem,
1345 .is_test = options.is_test,1366 .is_test = options.is_test,
1346 .wasi_exec_model = wasi_exec_model,1367 .wasi_exec_model = wasi_exec_model,
1368 .use_stage1 = use_stage1,
1347 });1369 });
1348 errdefer bin_file.destroy();1370 errdefer bin_file.destroy();
1349 comp.* = .{1371 comp.* = .{
...@@ -1486,9 +1508,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1486,9 +1508,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1486 try comp.work_queue.writeItem(.libtsan);1508 try comp.work_queue.writeItem(.libtsan);
1487 }1509 }
14881510
1489 // The `is_stage1` condition is here only because stage2 cannot yet build compiler-rt.1511 // The `use_stage1` condition is here only because stage2 cannot yet build compiler-rt.
1490 // Once it is capable this condition should be removed.1512 // Once it is capable this condition should be removed.
1491 if (build_options.is_stage1) {1513 if (comp.bin_file.options.use_stage1) {
1492 if (comp.bin_file.options.include_compiler_rt) {1514 if (comp.bin_file.options.include_compiler_rt) {
1493 if (is_exe_or_dyn_lib) {1515 if (is_exe_or_dyn_lib) {
1494 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });1516 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
...@@ -1519,7 +1541,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1519,7 +1541,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1519 }1541 }
1520 }1542 }
15211543
1522 if (build_options.is_stage1 and comp.bin_file.options.use_llvm) {1544 if (comp.bin_file.options.use_stage1 and comp.bin_file.options.module != null) {
1523 try comp.work_queue.writeItem(.{ .stage1_module = {} });1545 try comp.work_queue.writeItem(.{ .stage1_module = {} });
1524 }1546 }
15251547
...@@ -1625,8 +1647,7 @@ pub fn update(self: *Compilation) !void {...@@ -1625,8 +1647,7 @@ pub fn update(self: *Compilation) !void {
1625 self.c_object_work_queue.writeItemAssumeCapacity(key);1647 self.c_object_work_queue.writeItemAssumeCapacity(key);
1626 }1648 }
16271649
1628 const use_stage1 = build_options.omit_stage2 or1650 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;
1629 (build_options.is_stage1 and self.bin_file.options.use_llvm);
1630 if (self.bin_file.options.module) |module| {1651 if (self.bin_file.options.module) |module| {
1631 module.compile_log_text.shrinkAndFree(module.gpa, 0);1652 module.compile_log_text.shrinkAndFree(module.gpa, 0);
1632 module.generation += 1;1653 module.generation += 1;
...@@ -1921,7 +1942,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -1921,7 +1942,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
1921 // (at least for now) single-threaded main work queue. However, C object compilation1942 // (at least for now) single-threaded main work queue. However, C object compilation
1922 // only needs to be finished by the end of this function.1943 // only needs to be finished by the end of this function.
19231944
1924 var zir_prog_node = main_progress_node.start("AST Lowering", self.astgen_work_queue.count);1945 var zir_prog_node = main_progress_node.start("AST Lowering", 0);
1925 defer zir_prog_node.end();1946 defer zir_prog_node.end();
19261947
1927 var c_obj_prog_node = main_progress_node.start("Compile C Objects", self.c_source_files.len);1948 var c_obj_prog_node = main_progress_node.start("Compile C Objects", self.c_source_files.len);
...@@ -1937,7 +1958,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -1937,7 +1958,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
1937 while (self.astgen_work_queue.readItem()) |file| {1958 while (self.astgen_work_queue.readItem()) |file| {
1938 self.astgen_wait_group.start();1959 self.astgen_wait_group.start();
1939 try self.thread_pool.spawn(workerAstGenFile, .{1960 try self.thread_pool.spawn(workerAstGenFile, .{
1940 self, file, &zir_prog_node, &self.astgen_wait_group,1961 self, file, &zir_prog_node, &self.astgen_wait_group, .root,
1941 });1962 });
1942 }1963 }
19431964
...@@ -1949,13 +1970,18 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -1949,13 +1970,18 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
1949 }1970 }
1950 }1971 }
19511972
1952 const use_stage1 = build_options.omit_stage2 or1973 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;
1953 (build_options.is_stage1 and self.bin_file.options.use_llvm);
1954 if (!use_stage1) {1974 if (!use_stage1) {
1955 // Iterate over all the files and look for outdated and deleted declarations.1975 // Iterate over all the files and look for outdated and deleted declarations.
1956 if (self.bin_file.options.module) |mod| {1976 if (self.bin_file.options.module) |mod| {
1957 try mod.processOutdatedAndDeletedDecls();1977 try mod.processOutdatedAndDeletedDecls();
1958 }1978 }
1979 } else if (self.bin_file.options.module) |mod| {
1980 // If there are any AstGen compile errors, report them now to avoid
1981 // hitting stage1 bugs.
1982 if (mod.failed_files.count() != 0) {
1983 return;
1984 }
1959 }1985 }
19601986
1961 while (self.work_queue.readItem()) |work_item| switch (work_item) {1987 while (self.work_queue.readItem()) |work_item| switch (work_item) {
...@@ -2284,11 +2310,20 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -2284,11 +2310,20 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
2284 };2310 };
2285}2311}
22862312
2313const AstGenSrc = union(enum) {
2314 root,
2315 import: struct {
2316 importing_file: *Module.Scope.File,
2317 import_inst: Zir.Inst.Index,
2318 },
2319};
2320
2287fn workerAstGenFile(2321fn workerAstGenFile(
2288 comp: *Compilation,2322 comp: *Compilation,
2289 file: *Module.Scope.File,2323 file: *Module.Scope.File,
2290 prog_node: *std.Progress.Node,2324 prog_node: *std.Progress.Node,
2291 wg: *WaitGroup,2325 wg: *WaitGroup,
2326 src: AstGenSrc,
2292) void {2327) void {
2293 defer wg.finish();2328 defer wg.finish();
22942329
...@@ -2301,7 +2336,7 @@ fn workerAstGenFile(...@@ -2301,7 +2336,7 @@ fn workerAstGenFile(
2301 error.AnalysisFail => return,2336 error.AnalysisFail => return,
2302 else => {2337 else => {
2303 file.status = .retryable_failure;2338 file.status = .retryable_failure;
2304 comp.reportRetryableAstGenError(file, err) catch |oom| switch (oom) {2339 comp.reportRetryableAstGenError(src, file, err) catch |oom| switch (oom) {
2305 // Swallowing this error is OK because it's implied to be OOM when2340 // Swallowing this error is OK because it's implied to be OOM when
2306 // there is a missing `failed_files` error message.2341 // there is a missing `failed_files` error message.
2307 error.OutOfMemory => {},2342 error.OutOfMemory => {},
...@@ -2318,8 +2353,9 @@ fn workerAstGenFile(...@@ -2318,8 +2353,9 @@ fn workerAstGenFile(
2318 if (imports_index != 0) {2353 if (imports_index != 0) {
2319 const imports_len = file.zir.extra[imports_index];2354 const imports_len = file.zir.extra[imports_index];
23202355
2321 for (file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| {2356 for (file.zir.extra[imports_index + 1 ..][0..imports_len]) |import_inst| {
2322 const import_path = file.zir.nullTerminatedString(str_index);2357 const inst_data = file.zir.instructions.items(.data)[import_inst].str_tok;
2358 const import_path = inst_data.get(file.zir);
23232359
2324 const import_result = blk: {2360 const import_result = blk: {
2325 const lock = comp.mutex.acquire();2361 const lock = comp.mutex.acquire();
...@@ -2331,9 +2367,13 @@ fn workerAstGenFile(...@@ -2331,9 +2367,13 @@ fn workerAstGenFile(
2331 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{2367 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
2332 file.sub_file_path, import_path, import_result.file.sub_file_path,2368 file.sub_file_path, import_path, import_result.file.sub_file_path,
2333 });2369 });
2370 const sub_src: AstGenSrc = .{ .import = .{
2371 .importing_file = file,
2372 .import_inst = import_inst,
2373 } };
2334 wg.start();2374 wg.start();
2335 comp.thread_pool.spawn(workerAstGenFile, .{2375 comp.thread_pool.spawn(workerAstGenFile, .{
2336 comp, import_result.file, prog_node, wg,2376 comp, import_result.file, prog_node, wg, sub_src,
2337 }) catch {2377 }) catch {
2338 wg.finish();2378 wg.finish();
2339 continue;2379 continue;
...@@ -2544,6 +2584,7 @@ fn reportRetryableCObjectError(...@@ -2544,6 +2584,7 @@ fn reportRetryableCObjectError(
25442584
2545fn reportRetryableAstGenError(2585fn reportRetryableAstGenError(
2546 comp: *Compilation,2586 comp: *Compilation,
2587 src: AstGenSrc,
2547 file: *Module.Scope.File,2588 file: *Module.Scope.File,
2548 err: anyerror,2589 err: anyerror,
2549) error{OutOfMemory}!void {2590) error{OutOfMemory}!void {
...@@ -2552,22 +2593,38 @@ fn reportRetryableAstGenError(...@@ -2552,22 +2593,38 @@ fn reportRetryableAstGenError(
25522593
2553 file.status = .retryable_failure;2594 file.status = .retryable_failure;
25542595
2555 const src_loc: Module.SrcLoc = .{2596 const src_loc: Module.SrcLoc = switch (src) {
2556 .file_scope = file,2597 .root => .{
2557 .parent_decl_node = 0,2598 .file_scope = file,
2558 .lazy = .entire_file,2599 .parent_decl_node = 0,
2600 .lazy = .entire_file,
2601 },
2602 .import => |info| blk: {
2603 const importing_file = info.importing_file;
2604 const import_inst = info.import_inst;
2605 const inst_data = importing_file.zir.instructions.items(.data)[import_inst].str_tok;
2606 break :blk .{
2607 .file_scope = importing_file,
2608 .parent_decl_node = 0,
2609 .lazy = .{ .token_offset = inst_data.src_tok },
2610 };
2611 },
2559 };2612 };
25602613
2561 const err_msg = if (file.pkg.root_src_directory.path) |dir_path|2614 const err_msg = if (file.pkg.root_src_directory.path) |dir_path|
2562 try Module.ErrorMsg.create(2615 try Module.ErrorMsg.create(
2563 gpa,2616 gpa,
2564 src_loc,2617 src_loc,
2565 "unable to load {s}" ++ std.fs.path.sep_str ++ "{s}: {s}",2618 "unable to load '{'}" ++ std.fs.path.sep_str ++ "{'}': {s}",
2566 .{ dir_path, file.sub_file_path, @errorName(err) },2619 .{
2620 std.zig.fmtEscapes(dir_path),
2621 std.zig.fmtEscapes(file.sub_file_path),
2622 @errorName(err),
2623 },
2567 )2624 )
2568 else2625 else
2569 try Module.ErrorMsg.create(gpa, src_loc, "unable to load {s}: {s}", .{2626 try Module.ErrorMsg.create(gpa, src_loc, "unable to load '{'}': {s}", .{
2570 file.sub_file_path, @errorName(err),2627 std.zig.fmtEscapes(file.sub_file_path), @errorName(err),
2571 });2628 });
2572 errdefer err_msg.destroy(gpa);2629 errdefer err_msg.destroy(gpa);
25732630
...@@ -3486,8 +3543,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc...@@ -3486,8 +3543,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
34863543
3487 const target = comp.getTarget();3544 const target = comp.getTarget();
3488 const generic_arch_name = target.cpu.arch.genericName();3545 const generic_arch_name = target.cpu.arch.genericName();
3489 const use_stage1 = build_options.omit_stage2 or3546 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
3490 (build_options.is_stage1 and comp.bin_file.options.use_llvm);
34913547
3492 @setEvalBranchQuota(4000);3548 @setEvalBranchQuota(4000);
3493 try buffer.writer().print(3549 try buffer.writer().print(
src/Module.zig+10
...@@ -2466,6 +2466,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {...@@ -2466,6 +2466,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
2466 defer msg.deinit();2466 defer msg.deinit();
24672467
2468 const token_starts = file.tree.tokens.items(.start);2468 const token_starts = file.tree.tokens.items(.start);
2469 const token_tags = file.tree.tokens.items(.tag);
24692470
2470 try file.tree.renderError(parse_err, msg.writer());2471 try file.tree.renderError(parse_err, msg.writer());
2471 const err_msg = try gpa.create(ErrorMsg);2472 const err_msg = try gpa.create(ErrorMsg);
...@@ -2477,6 +2478,15 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {...@@ -2477,6 +2478,15 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
2477 },2478 },
2478 .msg = msg.toOwnedSlice(),2479 .msg = msg.toOwnedSlice(),
2479 };2480 };
2481 if (token_tags[parse_err.token] == .invalid) {
2482 const bad_off = @intCast(u32, file.tree.tokenSlice(parse_err.token).len);
2483 const byte_abs = token_starts[parse_err.token] + bad_off;
2484 try mod.errNoteNonLazy(.{
2485 .file_scope = file,
2486 .parent_decl_node = 0,
2487 .lazy = .{ .byte_abs = byte_abs },
2488 }, err_msg, "invalid byte: '{'}'", .{std.zig.fmtEscapes(source[byte_abs..][0..1])});
2489 }
24802490
2481 {2491 {
2482 const lock = comp.mutex.acquire();2492 const lock = comp.mutex.acquire();
src/Zir.zig+12-5
...@@ -139,9 +139,15 @@ pub fn renderAsTextToFile(...@@ -139,9 +139,15 @@ pub fn renderAsTextToFile(
139 if (imports_index != 0) {139 if (imports_index != 0) {
140 try fs_file.writeAll("Imports:\n");140 try fs_file.writeAll("Imports:\n");
141 const imports_len = scope_file.zir.extra[imports_index];141 const imports_len = scope_file.zir.extra[imports_index];
142 for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| {142 for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |import_inst| {
143 const import_path = scope_file.zir.nullTerminatedString(str_index);143 const inst_data = writer.code.instructions.items(.data)[import_inst].str_tok;
144 try fs_file.writer().print(" {s}\n", .{import_path});144 const src = inst_data.src();
145 const import_path = inst_data.get(writer.code);
146 try fs_file.writer().print(" @import(\"{}\") ", .{
147 std.zig.fmtEscapes(import_path),
148 });
149 try writer.writeSrc(fs_file.writer(), src);
150 try fs_file.writer().writeAll("\n");
145 }151 }
146 }152 }
147}153}
...@@ -2767,9 +2773,10 @@ pub const Inst = struct {...@@ -2767,9 +2773,10 @@ pub const Inst = struct {
2767 };2773 };
2768 };2774 };
27692775
2770 /// Trailing: for each `imports_len` there is a string table index.2776 /// Trailing: for each `imports_len` there is an instruction index
2777 /// to an import instruction.
2771 pub const Imports = struct {2778 pub const Imports = struct {
2772 imports_len: u32,2779 imports_len: Zir.Inst.Index,
2773 };2780 };
2774};2781};
27752782
src/link.zig+3-2
...@@ -92,6 +92,7 @@ pub const Options = struct {...@@ -92,6 +92,7 @@ pub const Options = struct {
92 each_lib_rpath: bool,92 each_lib_rpath: bool,
93 disable_lld_caching: bool,93 disable_lld_caching: bool,
94 is_test: bool,94 is_test: bool,
95 use_stage1: bool,
95 major_subsystem_version: ?u32,96 major_subsystem_version: ?u32,
96 minor_subsystem_version: ?u32,97 minor_subsystem_version: ?u32,
97 gc_sections: ?bool = null,98 gc_sections: ?bool = null,
...@@ -181,7 +182,7 @@ pub const File = struct {...@@ -181,7 +182,7 @@ pub const File = struct {
181 /// rewriting it. A malicious file is detected as incremental link failure182 /// rewriting it. A malicious file is detected as incremental link failure
182 /// and does not cause Illegal Behavior. This operation is not atomic.183 /// and does not cause Illegal Behavior. This operation is not atomic.
183 pub fn openPath(allocator: *Allocator, options: Options) !*File {184 pub fn openPath(allocator: *Allocator, options: Options) !*File {
184 const use_stage1 = build_options.is_stage1 and options.use_llvm;185 const use_stage1 = build_options.is_stage1 and options.use_stage1;
185 if (use_stage1 or options.emit == null) {186 if (use_stage1 or options.emit == null) {
186 return switch (options.object_format) {187 return switch (options.object_format) {
187 .coff, .pe => &(try Coff.createEmpty(allocator, options)).base,188 .coff, .pe => &(try Coff.createEmpty(allocator, options)).base,
...@@ -507,7 +508,7 @@ pub const File = struct {...@@ -507,7 +508,7 @@ pub const File = struct {
507 // If there is no Zig code to compile, then we should skip flushing the output file because it508 // If there is no Zig code to compile, then we should skip flushing the output file because it
508 // will not be part of the linker line anyway.509 // will not be part of the linker line anyway.
509 const module_obj_path: ?[]const u8 = if (base.options.module) |module| blk: {510 const module_obj_path: ?[]const u8 = if (base.options.module) |module| blk: {
510 const use_stage1 = build_options.is_stage1 and base.options.use_llvm;511 const use_stage1 = build_options.is_stage1 and base.options.use_stage1;
511 if (use_stage1) {512 if (use_stage1) {
512 const obj_basename = try std.zig.binNameAlloc(arena, .{513 const obj_basename = try std.zig.binNameAlloc(arena, .{
513 .root_name = base.options.root_name,514 .root_name = base.options.root_name,
src/link/MachO.zig+1-1
...@@ -606,7 +606,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -606,7 +606,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
606 // If there is no Zig code to compile, then we should skip flushing the output file because it606 // If there is no Zig code to compile, then we should skip flushing the output file because it
607 // will not be part of the linker line anyway.607 // will not be part of the linker line anyway.
608 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {608 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
609 const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm;609 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
610 if (use_stage1) {610 if (use_stage1) {
611 const obj_basename = try std.zig.binNameAlloc(arena, .{611 const obj_basename = try std.zig.binNameAlloc(arena, .{
612 .root_name = self.base.options.root_name,612 .root_name = self.base.options.root_name,
src/link/Wasm.zig+1-1
...@@ -556,7 +556,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {...@@ -556,7 +556,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
556 // If there is no Zig code to compile, then we should skip flushing the output file because it556 // If there is no Zig code to compile, then we should skip flushing the output file because it
557 // will not be part of the linker line anyway.557 // will not be part of the linker line anyway.
558 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {558 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
559 const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm;559 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
560 if (use_stage1) {560 if (use_stage1) {
561 const obj_basename = try std.zig.binNameAlloc(arena, .{561 const obj_basename = try std.zig.binNameAlloc(arena, .{
562 .root_name = self.base.options.root_name,562 .root_name = self.base.options.root_name,
src/main.zig+42-8
...@@ -233,7 +233,7 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v...@@ -233,7 +233,7 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
233 } else if (mem.eql(u8, cmd, "build")) {233 } else if (mem.eql(u8, cmd, "build")) {
234 return cmdBuild(gpa, arena, cmd_args);234 return cmdBuild(gpa, arena, cmd_args);
235 } else if (mem.eql(u8, cmd, "fmt")) {235 } else if (mem.eql(u8, cmd, "fmt")) {
236 return cmdFmt(gpa, cmd_args);236 return cmdFmt(gpa, arena, cmd_args);
237 } else if (mem.eql(u8, cmd, "libc")) {237 } else if (mem.eql(u8, cmd, "libc")) {
238 return cmdLibC(gpa, cmd_args);238 return cmdLibC(gpa, cmd_args);
239 } else if (mem.eql(u8, cmd, "init-exe")) {239 } else if (mem.eql(u8, cmd, "init-exe")) {
...@@ -350,9 +350,11 @@ const usage_build_generic =...@@ -350,9 +350,11 @@ const usage_build_generic =
350 \\ -funwind-tables Always produce unwind table entries for all functions350 \\ -funwind-tables Always produce unwind table entries for all functions
351 \\ -fno-unwind-tables Never produce unwind table entries351 \\ -fno-unwind-tables Never produce unwind table entries
352 \\ -fLLVM Force using LLVM as the codegen backend352 \\ -fLLVM Force using LLVM as the codegen backend
353 \\ -fno-LLVM Prevent using LLVM as a codegen backend353 \\ -fno-LLVM Prevent using LLVM as the codegen backend
354 \\ -fClang Force using Clang as the C/C++ compilation backend354 \\ -fClang Force using Clang as the C/C++ compilation backend
355 \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend355 \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend
356 \\ -fstage1 Force using bootstrap compiler as the codegen backend
357 \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend
356 \\ --strip Omit debug symbols358 \\ --strip Omit debug symbols
357 \\ --single-threaded Code assumes it is only used single-threaded359 \\ --single-threaded Code assumes it is only used single-threaded
358 \\ -ofmt=[mode] Override target object format360 \\ -ofmt=[mode] Override target object format
...@@ -602,6 +604,7 @@ fn buildOutputType(...@@ -602,6 +604,7 @@ fn buildOutputType(
602 var use_llvm: ?bool = null;604 var use_llvm: ?bool = null;
603 var use_lld: ?bool = null;605 var use_lld: ?bool = null;
604 var use_clang: ?bool = null;606 var use_clang: ?bool = null;
607 var use_stage1: ?bool = null;
605 var link_eh_frame_hdr = false;608 var link_eh_frame_hdr = false;
606 var link_emit_relocs = false;609 var link_emit_relocs = false;
607 var each_lib_rpath: ?bool = null;610 var each_lib_rpath: ?bool = null;
...@@ -975,6 +978,10 @@ fn buildOutputType(...@@ -975,6 +978,10 @@ fn buildOutputType(
975 use_clang = true;978 use_clang = true;
976 } else if (mem.eql(u8, arg, "-fno-Clang")) {979 } else if (mem.eql(u8, arg, "-fno-Clang")) {
977 use_clang = false;980 use_clang = false;
981 } else if (mem.eql(u8, arg, "-fstage1")) {
982 use_stage1 = true;
983 } else if (mem.eql(u8, arg, "-fno-stage1")) {
984 use_stage1 = false;
978 } else if (mem.eql(u8, arg, "-rdynamic")) {985 } else if (mem.eql(u8, arg, "-rdynamic")) {
979 rdynamic = true;986 rdynamic = true;
980 } else if (mem.eql(u8, arg, "-fsoname")) {987 } else if (mem.eql(u8, arg, "-fsoname")) {
...@@ -2020,6 +2027,7 @@ fn buildOutputType(...@@ -2020,6 +2027,7 @@ fn buildOutputType(
2020 .use_llvm = use_llvm,2027 .use_llvm = use_llvm,
2021 .use_lld = use_lld,2028 .use_lld = use_lld,
2022 .use_clang = use_clang,2029 .use_clang = use_clang,
2030 .use_stage1 = use_stage1,
2023 .rdynamic = rdynamic,2031 .rdynamic = rdynamic,
2024 .linker_script = linker_script,2032 .linker_script = linker_script,
2025 .version_script = version_script,2033 .version_script = version_script,
...@@ -3031,12 +3039,13 @@ const Fmt = struct {...@@ -3031,12 +3039,13 @@ const Fmt = struct {
3031 check_ast: bool,3039 check_ast: bool,
3032 color: Color,3040 color: Color,
3033 gpa: *Allocator,3041 gpa: *Allocator,
3042 arena: *Allocator,
3034 out_buffer: std.ArrayList(u8),3043 out_buffer: std.ArrayList(u8),
30353044
3036 const SeenMap = std.AutoHashMap(fs.File.INode, void);3045 const SeenMap = std.AutoHashMap(fs.File.INode, void);
3037};3046};
30383047
3039pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {3048pub fn cmdFmt(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void {
3040 var color: Color = .auto;3049 var color: Color = .auto;
3041 var stdin_flag: bool = false;3050 var stdin_flag: bool = false;
3042 var check_flag: bool = false;3051 var check_flag: bool = false;
...@@ -3094,7 +3103,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {...@@ -3094,7 +3103,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
3094 defer tree.deinit(gpa);3103 defer tree.deinit(gpa);
30953104
3096 for (tree.errors) |parse_error| {3105 for (tree.errors) |parse_error| {
3097 try printErrMsgToStdErr(gpa, parse_error, tree, "<stdin>", color);3106 try printErrMsgToStdErr(gpa, arena, parse_error, tree, "<stdin>", color);
3098 }3107 }
3099 var has_ast_error = false;3108 var has_ast_error = false;
3100 if (check_ast_flag) {3109 if (check_ast_flag) {
...@@ -3162,6 +3171,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {...@@ -3162,6 +3171,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
31623171
3163 var fmt = Fmt{3172 var fmt = Fmt{
3164 .gpa = gpa,3173 .gpa = gpa,
3174 .arena = arena,
3165 .seen = Fmt.SeenMap.init(gpa),3175 .seen = Fmt.SeenMap.init(gpa),
3166 .any_error = false,3176 .any_error = false,
3167 .check_ast = check_ast_flag,3177 .check_ast = check_ast_flag,
...@@ -3285,7 +3295,7 @@ fn fmtPathFile(...@@ -3285,7 +3295,7 @@ fn fmtPathFile(
3285 defer tree.deinit(fmt.gpa);3295 defer tree.deinit(fmt.gpa);
32863296
3287 for (tree.errors) |parse_error| {3297 for (tree.errors) |parse_error| {
3288 try printErrMsgToStdErr(fmt.gpa, parse_error, tree, file_path, fmt.color);3298 try printErrMsgToStdErr(fmt.gpa, fmt.arena, parse_error, tree, file_path, fmt.color);
3289 }3299 }
3290 if (tree.errors.len != 0) {3300 if (tree.errors.len != 0) {
3291 fmt.any_error = true;3301 fmt.any_error = true;
...@@ -3366,12 +3376,14 @@ fn fmtPathFile(...@@ -3366,12 +3376,14 @@ fn fmtPathFile(
33663376
3367fn printErrMsgToStdErr(3377fn printErrMsgToStdErr(
3368 gpa: *mem.Allocator,3378 gpa: *mem.Allocator,
3379 arena: *mem.Allocator,
3369 parse_error: ast.Error,3380 parse_error: ast.Error,
3370 tree: ast.Tree,3381 tree: ast.Tree,
3371 path: []const u8,3382 path: []const u8,
3372 color: Color,3383 color: Color,
3373) !void {3384) !void {
3374 const lok_token = parse_error.token;3385 const lok_token = parse_error.token;
3386 const token_tags = tree.tokens.items(.tag);
3375 const start_loc = tree.tokenLocation(0, lok_token);3387 const start_loc = tree.tokenLocation(0, lok_token);
3376 const source_line = tree.source[start_loc.line_start..start_loc.line_end];3388 const source_line = tree.source[start_loc.line_start..start_loc.line_end];
33773389
...@@ -3381,6 +3393,27 @@ fn printErrMsgToStdErr(...@@ -3381,6 +3393,27 @@ fn printErrMsgToStdErr(
3381 try tree.renderError(parse_error, writer);3393 try tree.renderError(parse_error, writer);
3382 const text = text_buf.items;3394 const text = text_buf.items;
33833395
3396 var notes_buffer: [1]Compilation.AllErrors.Message = undefined;
3397 var notes_len: usize = 0;
3398
3399 if (token_tags[parse_error.token] == .invalid) {
3400 const bad_off = @intCast(u32, tree.tokenSlice(parse_error.token).len);
3401 const byte_offset = @intCast(u32, start_loc.line_start) + bad_off;
3402 notes_buffer[notes_len] = .{
3403 .src = .{
3404 .src_path = path,
3405 .msg = try std.fmt.allocPrint(arena, "invalid byte: '{'}'", .{
3406 std.zig.fmtEscapes(tree.source[byte_offset..][0..1]),
3407 }),
3408 .byte_offset = byte_offset,
3409 .line = @intCast(u32, start_loc.line),
3410 .column = @intCast(u32, start_loc.column) + bad_off,
3411 .source_line = source_line,
3412 },
3413 };
3414 notes_len += 1;
3415 }
3416
3384 const message: Compilation.AllErrors.Message = .{3417 const message: Compilation.AllErrors.Message = .{
3385 .src = .{3418 .src = .{
3386 .src_path = path,3419 .src_path = path,
...@@ -3389,6 +3422,7 @@ fn printErrMsgToStdErr(...@@ -3389,6 +3422,7 @@ fn printErrMsgToStdErr(
3389 .line = @intCast(u32, start_loc.line),3422 .line = @intCast(u32, start_loc.line),
3390 .column = @intCast(u32, start_loc.column),3423 .column = @intCast(u32, start_loc.column),
3391 .source_line = source_line,3424 .source_line = source_line,
3425 .notes = notes_buffer[0..notes_len],
3392 },3426 },
3393 };3427 };
33943428
...@@ -3915,7 +3949,7 @@ pub fn cmdAstCheck(...@@ -3915,7 +3949,7 @@ pub fn cmdAstCheck(
3915 defer file.tree.deinit(gpa);3949 defer file.tree.deinit(gpa);
39163950
3917 for (file.tree.errors) |parse_error| {3951 for (file.tree.errors) |parse_error| {
3918 try printErrMsgToStdErr(gpa, parse_error, file.tree, file.sub_file_path, color);3952 try printErrMsgToStdErr(gpa, arena, parse_error, file.tree, file.sub_file_path, color);
3919 }3953 }
3920 if (file.tree.errors.len != 0) {3954 if (file.tree.errors.len != 0) {
3921 process.exit(1);3955 process.exit(1);
...@@ -4041,7 +4075,7 @@ pub fn cmdChangelist(...@@ -4041,7 +4075,7 @@ pub fn cmdChangelist(
4041 defer file.tree.deinit(gpa);4075 defer file.tree.deinit(gpa);
40424076
4043 for (file.tree.errors) |parse_error| {4077 for (file.tree.errors) |parse_error| {
4044 try printErrMsgToStdErr(gpa, parse_error, file.tree, old_source_file, .auto);4078 try printErrMsgToStdErr(gpa, arena, parse_error, file.tree, old_source_file, .auto);
4045 }4079 }
4046 if (file.tree.errors.len != 0) {4080 if (file.tree.errors.len != 0) {
4047 process.exit(1);4081 process.exit(1);
...@@ -4080,7 +4114,7 @@ pub fn cmdChangelist(...@@ -4080,7 +4114,7 @@ pub fn cmdChangelist(
4080 defer new_tree.deinit(gpa);4114 defer new_tree.deinit(gpa);
40814115
4082 for (new_tree.errors) |parse_error| {4116 for (new_tree.errors) |parse_error| {
4083 try printErrMsgToStdErr(gpa, parse_error, new_tree, new_source_file, .auto);4117 try printErrMsgToStdErr(gpa, arena, parse_error, new_tree, new_source_file, .auto);
4084 }4118 }
4085 if (new_tree.errors.len != 0) {4119 if (new_tree.errors.len != 0) {
4086 process.exit(1);4120 process.exit(1);
src/stage1.zig+9-4
...@@ -7,6 +7,7 @@ const assert = std.debug.assert;...@@ -7,6 +7,7 @@ const assert = std.debug.assert;
7const mem = std.mem;7const mem = std.mem;
8const CrossTarget = std.zig.CrossTarget;8const CrossTarget = std.zig.CrossTarget;
9const Target = std.Target;9const Target = std.Target;
10const builtin = @import("builtin");
1011
11const build_options = @import("build_options");12const build_options = @import("build_options");
12const stage2 = @import("main.zig");13const stage2 = @import("main.zig");
...@@ -16,16 +17,19 @@ const translate_c = @import("translate_c.zig");...@@ -16,16 +17,19 @@ const translate_c = @import("translate_c.zig");
16const target_util = @import("target.zig");17const target_util = @import("target.zig");
1718
18comptime {19comptime {
19 assert(std.builtin.link_libc);20 assert(builtin.link_libc);
20 assert(build_options.is_stage1);21 assert(build_options.is_stage1);
21 assert(build_options.have_llvm);22 assert(build_options.have_llvm);
22 _ = @import("compiler_rt");23 if (!builtin.is_test) {
24 _ = @import("compiler_rt");
25 @export(main, .{ .name = "main" });
26 }
23}27}
2428
25pub const log = stage2.log;29pub const log = stage2.log;
26pub const log_level = stage2.log_level;30pub const log_level = stage2.log_level;
2731
28pub export fn main(argc: c_int, argv: [*][*:0]u8) c_int {32pub fn main(argc: c_int, argv: [*][*:0]u8) callconv(.C) c_int {
29 std.os.argv = argv[0..@intCast(usize, argc)];33 std.os.argv = argv[0..@intCast(usize, argc)];
3034
31 std.debug.maybeEnableSegfaultHandler();35 std.debug.maybeEnableSegfaultHandler();
...@@ -41,7 +45,7 @@ pub export fn main(argc: c_int, argv: [*][*:0]u8) c_int {...@@ -41,7 +45,7 @@ pub export fn main(argc: c_int, argv: [*][*:0]u8) c_int {
41 for (args) |*arg, i| {45 for (args) |*arg, i| {
42 arg.* = mem.spanZ(argv[i]);46 arg.* = mem.spanZ(argv[i]);
43 }47 }
44 if (std.builtin.mode == .Debug) {48 if (builtin.mode == .Debug) {
45 stage2.mainArgs(gpa, arena, args) catch unreachable;49 stage2.mainArgs(gpa, arena, args) catch unreachable;
46 } else {50 } else {
47 stage2.mainArgs(gpa, arena, args) catch |err| fatal("{s}", .{@errorName(err)});51 stage2.mainArgs(gpa, arena, args) catch |err| fatal("{s}", .{@errorName(err)});
...@@ -147,6 +151,7 @@ pub const Module = extern struct {...@@ -147,6 +151,7 @@ pub const Module = extern struct {
147 }151 }
148};152};
149153
154pub const os_init = zig_stage1_os_init;
150extern fn zig_stage1_os_init() void;155extern fn zig_stage1_os_init() void;
151156
152pub const create = zig_stage1_create;157pub const create = zig_stage1_create;
src/stage1/all_types.hpp-4
...@@ -2733,10 +2733,6 @@ struct IrInstSrc {...@@ -2733,10 +2733,6 @@ struct IrInstSrc {
2733 IrInst base;2733 IrInst base;
27342734
2735 IrInstSrcId id;2735 IrInstSrcId id;
2736 // true if this instruction was generated by zig and not from user code
2737 // this matters for the "unreachable code" compile error
2738 bool is_gen;
2739 bool is_noreturn;
27402736
2741 // When analyzing IR, instructions that point to this instruction in the "old ir"2737 // When analyzing IR, instructions that point to this instruction in the "old ir"
2742 // can find the instruction that corresponds to this value in the "new ir"2738 // can find the instruction that corresponds to this value in the "new ir"
src/stage1/analyze.cpp+3-3
...@@ -3915,7 +3915,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {...@@ -3915,7 +3915,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
3915 }3915 }
3916 }3916 }
3917 ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name)));3917 ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name)));
3918 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));3918 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition here"));
3919 return;3919 return;
3920 }3920 }
39213921
...@@ -4176,7 +4176,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf...@@ -4176,7 +4176,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
4176 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {4176 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
4177 ErrorMsg *msg = add_node_error(g, source_node,4177 ErrorMsg *msg = add_node_error(g, source_node,
4178 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));4178 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
4179 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));4179 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration here"));
4180 }4180 }
4181 variable_entry->var_type = g->builtin_types.entry_invalid;4181 variable_entry->var_type = g->builtin_types.entry_invalid;
4182 } else {4182 } else {
...@@ -4205,7 +4205,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf...@@ -4205,7 +4205,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
4205 if (want_err_msg) {4205 if (want_err_msg) {
4206 ErrorMsg *msg = add_node_error(g, source_node,4206 ErrorMsg *msg = add_node_error(g, source_node,
4207 buf_sprintf("redefinition of '%s'", buf_ptr(name)));4207 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
4208 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));4208 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition here"));
4209 }4209 }
4210 variable_entry->var_type = g->builtin_types.entry_invalid;4210 variable_entry->var_type = g->builtin_types.entry_invalid;
4211 }4211 }
src/stage1/astgen.cpp+74-81
...@@ -55,7 +55,17 @@ static ErrorMsg *exec_add_error_node(CodeGen *codegen, Stage1Zir *exec, AstNode...@@ -55,7 +55,17 @@ static ErrorMsg *exec_add_error_node(CodeGen *codegen, Stage1Zir *exec, AstNode
5555
5656
57static bool instr_is_unreachable(IrInstSrc *instruction) {57static bool instr_is_unreachable(IrInstSrc *instruction) {
58 return instruction->is_noreturn;58 switch (instruction->id) {
59 case IrInstSrcIdCondBr:
60 case IrInstSrcIdReturn:
61 case IrInstSrcIdBr:
62 case IrInstSrcIdUnreachable:
63 case IrInstSrcIdSwitchBr:
64 case IrInstSrcIdPanic:
65 return true;
66 default:
67 return false;
68 }
59}69}
6070
61void destroy_instruction_src(IrInstSrc *inst) {71void destroy_instruction_src(IrInstSrc *inst) {
...@@ -947,7 +957,6 @@ static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *sour...@@ -947,7 +957,6 @@ static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *sour
947 Stage1ZirBasicBlock *then_block, Stage1ZirBasicBlock *else_block, IrInstSrc *is_comptime)957 Stage1ZirBasicBlock *then_block, Stage1ZirBasicBlock *else_block, IrInstSrc *is_comptime)
948{958{
949 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(ag, scope, source_node);959 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(ag, scope, source_node);
950 inst->base.is_noreturn = true;
951 inst->condition = condition;960 inst->condition = condition;
952 inst->then_block = then_block;961 inst->then_block = then_block;
953 inst->else_block = else_block;962 inst->else_block = else_block;
...@@ -963,7 +972,6 @@ static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *sour...@@ -963,7 +972,6 @@ static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *sour
963972
964static IrInstSrc *ir_build_return_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *operand) {973static IrInstSrc *ir_build_return_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *operand) {
965 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(ag, scope, source_node);974 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(ag, scope, source_node);
966 inst->base.is_noreturn = true;
967 inst->operand = operand;975 inst->operand = operand;
968976
969 if (operand != nullptr) ir_ref_instruction(operand, ag->current_basic_block);977 if (operand != nullptr) ir_ref_instruction(operand, ag->current_basic_block);
...@@ -1303,7 +1311,6 @@ static IrInstSrc *ir_build_br(Stage1AstGen *ag, Scope *scope, AstNode *source_no...@@ -1303,7 +1311,6 @@ static IrInstSrc *ir_build_br(Stage1AstGen *ag, Scope *scope, AstNode *source_no
1303 Stage1ZirBasicBlock *dest_block, IrInstSrc *is_comptime)1311 Stage1ZirBasicBlock *dest_block, IrInstSrc *is_comptime)
1304{1312{
1305 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(ag, scope, source_node);1313 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(ag, scope, source_node);
1306 inst->base.is_noreturn = true;
1307 inst->dest_block = dest_block;1314 inst->dest_block = dest_block;
1308 inst->is_comptime = is_comptime;1315 inst->is_comptime = is_comptime;
13091316
...@@ -1418,7 +1425,6 @@ static IrInstSrc *ir_build_container_init_fields(Stage1AstGen *ag, Scope *scope,...@@ -1418,7 +1425,6 @@ static IrInstSrc *ir_build_container_init_fields(Stage1AstGen *ag, Scope *scope,
14181425
1419static IrInstSrc *ir_build_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {1426static IrInstSrc *ir_build_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1420 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(ag, scope, source_node);1427 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(ag, scope, source_node);
1421 inst->base.is_noreturn = true;
1422 return &inst->base;1428 return &inst->base;
1423}1429}
14241430
...@@ -1718,7 +1724,6 @@ static IrInstSrcSwitchBr *ir_build_switch_br_src(Stage1AstGen *ag, Scope *scope,...@@ -1718,7 +1724,6 @@ static IrInstSrcSwitchBr *ir_build_switch_br_src(Stage1AstGen *ag, Scope *scope,
1718 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void)1724 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void)
1719{1725{
1720 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(ag, scope, source_node);1726 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(ag, scope, source_node);
1721 instruction->base.is_noreturn = true;
1722 instruction->target_value = target_value;1727 instruction->target_value = target_value;
1723 instruction->else_block = else_block;1728 instruction->else_block = else_block;
1724 instruction->case_count = case_count;1729 instruction->case_count = case_count;
...@@ -2439,7 +2444,6 @@ static IrInstSrc *ir_build_decl_ref(Stage1AstGen *ag, Scope *scope, AstNode *sou...@@ -2439,7 +2444,6 @@ static IrInstSrc *ir_build_decl_ref(Stage1AstGen *ag, Scope *scope, AstNode *sou
24392444
2440static IrInstSrc *ir_build_panic_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *msg) {2445static IrInstSrc *ir_build_panic_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *msg) {
2441 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(ag, scope, source_node);2446 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(ag, scope, source_node);
2442 instruction->base.is_noreturn = true;
2443 instruction->msg = msg;2447 instruction->msg = msg;
24442448
2445 ir_ref_instruction(msg, ag->current_basic_block);2449 ir_ref_instruction(msg, ag->current_basic_block);
...@@ -2557,7 +2561,6 @@ static IrInstSrc *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode...@@ -2557,7 +2561,6 @@ static IrInstSrc *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode
2557{2561{
2558 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(ag, scope, source_node);2562 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(ag, scope, source_node);
2559 instruction->result_loc = result_loc;2563 instruction->result_loc = result_loc;
2560 instruction->base.is_gen = true;
25612564
2562 return &instruction->base;2565 return &instruction->base;
2563}2566}
...@@ -2737,7 +2740,6 @@ static IrInstSrc *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *s...@@ -2737,7 +2740,6 @@ static IrInstSrc *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *s
2737 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)2740 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)
2738{2741{
2739 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(ag, scope, source_node);2742 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(ag, scope, source_node);
2740 instruction->base.is_gen = true;
2741 instruction->align = align;2743 instruction->align = align;
2742 instruction->name_hint = name_hint;2744 instruction->name_hint = name_hint;
2743 instruction->is_comptime = is_comptime;2745 instruction->is_comptime = is_comptime;
...@@ -2752,7 +2754,6 @@ static IrInstSrc *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *sou...@@ -2752,7 +2754,6 @@ static IrInstSrc *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *sou
2752 IrInstSrc *value, ResultLoc *result_loc)2754 IrInstSrc *value, ResultLoc *result_loc)
2753{2755{
2754 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(ag, scope, source_node);2756 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(ag, scope, source_node);
2755 instruction->base.is_gen = true;
2756 instruction->value = value;2757 instruction->value = value;
2757 instruction->result_loc = result_loc;2758 instruction->result_loc = result_loc;
27582759
...@@ -2885,11 +2886,6 @@ static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_s...@@ -2885,11 +2886,6 @@ static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_s
2885 }2886 }
2886}2887}
28872888
2888static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) {
2889 instruction->is_gen = true;
2890 return instruction;
2891}
2892
2893static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {2889static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {
2894 Scope *scope = inner_scope;2890 Scope *scope = inner_scope;
2895 if (is_noreturn != nullptr) *is_noreturn = false;2891 if (is_noreturn != nullptr) *is_noreturn = false;
...@@ -2945,11 +2941,11 @@ static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope...@@ -2945,11 +2941,11 @@ static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope
2945 if (defer_expr_value == ag->codegen->invalid_inst_src)2941 if (defer_expr_value == ag->codegen->invalid_inst_src)
2946 return ag->codegen->invalid_inst_src;2942 return ag->codegen->invalid_inst_src;
29472943
2948 if (defer_expr_value->is_noreturn) {2944 if (instr_is_unreachable(defer_expr_value)) {
2949 if (is_noreturn != nullptr) *is_noreturn = true;2945 if (is_noreturn != nullptr) *is_noreturn = true;
2950 } else {2946 } else {
2951 ir_mark_gen(ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,2947 ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,
2952 defer_expr_value));2948 defer_expr_value);
2953 }2949 }
2954 scope = scope->parent;2950 scope = scope->parent;
2955 continue;2951 continue;
...@@ -3047,7 +3043,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L...@@ -3047,7 +3043,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
3047 ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);3043 ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);
3048 }3044 }
30493045
3050 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, node, return_value, result_loc_ret));3046 ir_build_add_implicit_return_type(ag, scope, node, return_value, result_loc_ret);
30513047
3052 size_t defer_counts[2];3048 size_t defer_counts[2];
3053 ir_count_defers(ag, scope, outer_scope, defer_counts);3049 ir_count_defers(ag, scope, outer_scope, defer_counts);
...@@ -3074,7 +3070,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L...@@ -3074,7 +3070,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
3074 is_comptime = ir_build_test_comptime(ag, scope, node, is_err);3070 is_comptime = ir_build_test_comptime(ag, scope, node, is_err);
3075 }3071 }
30763072
3077 ir_mark_gen(ir_build_cond_br(ag, scope, node, is_err, err_block, ok_block, is_comptime));3073 ir_build_cond_br(ag, scope, node, is_err, err_block, ok_block, is_comptime);
3078 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");3074 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");
30793075
3080 ir_set_cursor_at_end_and_append_block(ag, err_block);3076 ir_set_cursor_at_end_and_append_block(ag, err_block);
...@@ -3112,12 +3108,12 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L...@@ -3112,12 +3108,12 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
3112 } else {3108 } else {
3113 is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);3109 is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);
3114 }3110 }
3115 ir_mark_gen(ir_build_cond_br(ag, scope, node, is_err_val, return_block, continue_block, is_comptime));3111 ir_build_cond_br(ag, scope, node, is_err_val, return_block, continue_block, is_comptime);
31163112
3117 ir_set_cursor_at_end_and_append_block(ag, return_block);3113 ir_set_cursor_at_end_and_append_block(ag, return_block);
3118 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);3114 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);
3119 IrInstSrc *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);3115 IrInstSrc *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);
3120 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, node, err_val, nullptr));3116 ir_build_add_implicit_return_type(ag, scope, node, err_val, nullptr);
3121 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,3117 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,
3122 SpillIdRetErrCode);3118 SpillIdRetErrCode);
3123 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();3119 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
...@@ -3173,7 +3169,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,...@@ -3173,7 +3169,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
3173 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {3169 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
3174 ErrorMsg *msg = add_node_error(codegen, node,3170 ErrorMsg *msg = add_node_error(codegen, node,
3175 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));3171 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3176 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));3172 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration here"));
3177 }3173 }
3178 variable_entry->var_type = codegen->builtin_types.entry_invalid;3174 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3179 } else {3175 } else {
...@@ -3195,7 +3191,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,...@@ -3195,7 +3191,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
3195 if (want_err_msg) {3191 if (want_err_msg) {
3196 ErrorMsg *msg = add_node_error(codegen, node,3192 ErrorMsg *msg = add_node_error(codegen, node,
3197 buf_sprintf("redefinition of '%s'", buf_ptr(name)));3193 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
3198 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));3194 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition here"));
3199 }3195 }
3200 variable_entry->var_type = codegen->builtin_types.entry_invalid;3196 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3201 }3197 }
...@@ -3251,7 +3247,7 @@ static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *nam...@@ -3251,7 +3247,7 @@ static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *nam
3251 Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;3247 Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
3252 if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {3248 if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
3253 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));3249 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));
3254 add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration is here"));3250 add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration here"));
3255 return true;3251 return true;
3256 }3252 }
3257 }3253 }
...@@ -3338,7 +3334,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3338,7 +3334,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
3338 child_scope = decl_var_instruction->var->child_scope;3334 child_scope = decl_var_instruction->var->child_scope;
3339 } else if (!is_continuation_unreachable) {3335 } else if (!is_continuation_unreachable) {
3340 // this statement's value must be void3336 // this statement's value must be void
3341 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, statement_node, statement_value));3337 ir_build_check_statement_is_void(ag, child_scope, statement_node, statement_value);
3342 }3338 }
3343 }3339 }
33443340
...@@ -3364,7 +3360,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3364,7 +3360,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
3364 return ir_expr_wrap(ag, parent_scope, phi, result_loc);3360 return ir_expr_wrap(ag, parent_scope, phi, result_loc);
3365 } else {3361 } else {
3366 incoming_blocks.append(ag->current_basic_block);3362 incoming_blocks.append(ag->current_basic_block);
3367 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(ag, parent_scope, block_node));3363 IrInstSrc *else_expr_result = ir_build_const_void(ag, parent_scope, block_node);
33683364
3369 if (scope_block->peer_parent != nullptr) {3365 if (scope_block->peer_parent != nullptr) {
3370 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);3366 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);
...@@ -3387,13 +3383,13 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3387,13 +3383,13 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
33873383
3388 IrInstSrc *result;3384 IrInstSrc *result;
3389 if (block_node->data.block.name != nullptr) {3385 if (block_node->data.block.name != nullptr) {
3390 ir_mark_gen(ir_build_br(ag, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));3386 ir_build_br(ag, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime);
3391 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);3387 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
3392 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,3388 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
3393 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);3389 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3394 result = ir_expr_wrap(ag, parent_scope, phi, result_loc);3390 result = ir_expr_wrap(ag, parent_scope, phi, result_loc);
3395 } else {3391 } else {
3396 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(ag, child_scope, block_node));3392 IrInstSrc *void_inst = ir_build_const_void(ag, child_scope, block_node);
3397 result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);3393 result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);
3398 }3394 }
3399 if (!is_return_from_fn)3395 if (!is_return_from_fn)
...@@ -3402,14 +3398,14 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3402,14 +3398,14 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
3402 // no need for save_err_ret_addr because this cannot return error3398 // no need for save_err_ret_addr because this cannot return error
3403 // only generate unconditional defers3399 // only generate unconditional defers
34043400
3405 ir_mark_gen(ir_build_add_implicit_return_type(ag, child_scope, block_node, result, nullptr));3401 ir_build_add_implicit_return_type(ag, child_scope, block_node, result, nullptr);
3406 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();3402 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3407 result_loc_ret->base.id = ResultLocIdReturn;3403 result_loc_ret->base.id = ResultLocIdReturn;
3408 ir_build_reset_result(ag, parent_scope, block_node, &result_loc_ret->base);3404 ir_build_reset_result(ag, parent_scope, block_node, &result_loc_ret->base);
3409 ir_mark_gen(ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base));3405 ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base);
3410 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))3406 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
3411 return ag->codegen->invalid_inst_src;3407 return ag->codegen->invalid_inst_src;
3412 return ir_mark_gen(ir_build_return_src(ag, child_scope, result->base.source_node, result));3408 return ir_build_return_src(ag, child_scope, result->base.source_node, result);
3413}3409}
34143410
3415static IrInstSrc *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {3411static IrInstSrc *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
...@@ -3628,7 +3624,7 @@ static IrInstSrc *astgen_orelse(Stage1AstGen *ag, Scope *parent_scope, AstNode *...@@ -3628,7 +3624,7 @@ static IrInstSrc *astgen_orelse(Stage1AstGen *ag, Scope *parent_scope, AstNode *
3628 return ag->codegen->invalid_inst_src;3624 return ag->codegen->invalid_inst_src;
3629 Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;3625 Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;
3630 if (!instr_is_unreachable(null_result))3626 if (!instr_is_unreachable(null_result))
3631 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));3627 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
36323628
3633 ir_set_cursor_at_end_and_append_block(ag, ok_block);3629 ir_set_cursor_at_end_and_append_block(ag, ok_block);
3634 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, parent_scope, node, maybe_ptr, false);3630 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, parent_scope, node, maybe_ptr, false);
...@@ -5395,7 +5391,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n...@@ -5395,7 +5391,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n
5395 return ag->codegen->invalid_inst_src;5391 return ag->codegen->invalid_inst_src;
5396 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;5392 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
5397 if (!instr_is_unreachable(then_expr_result))5393 if (!instr_is_unreachable(then_expr_result))
5398 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));5394 ir_build_br(ag, scope, node, endif_block, is_comptime);
53995395
5400 ir_set_cursor_at_end_and_append_block(ag, else_block);5396 ir_set_cursor_at_end_and_append_block(ag, else_block);
5401 IrInstSrc *else_expr_result;5397 IrInstSrc *else_expr_result;
...@@ -5409,7 +5405,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n...@@ -5409,7 +5405,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n
5409 }5405 }
5410 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;5406 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
5411 if (!instr_is_unreachable(else_expr_result))5407 if (!instr_is_unreachable(else_expr_result))
5412 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));5408 ir_build_br(ag, scope, node, endif_block, is_comptime);
54135409
5414 ir_set_cursor_at_end_and_append_block(ag, endif_block);5410 ir_set_cursor_at_end_and_append_block(ag, endif_block);
5415 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);5411 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
...@@ -5954,12 +5950,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -5954,12 +5950,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
5954 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,5950 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,
5955 true, false);5951 true, false);
5956 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;5952 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
5957 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));5953 IrInstSrc *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
5958 IrInstSrc *cond_br_inst;5954 IrInstSrc *cond_br_inst;
5959 if (!instr_is_unreachable(is_err)) {5955 if (!instr_is_unreachable(is_err)) {
5960 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,5956 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,
5961 else_block, body_block, is_comptime);5957 else_block, body_block, is_comptime);
5962 cond_br_inst->is_gen = true;
5963 } else {5958 } else {
5964 // for the purposes of the source instruction to ir_build_result_peers5959 // for the purposes of the source instruction to ir_build_result_peers
5965 cond_br_inst = ag->current_basic_block->instruction_list.last();5960 cond_br_inst = ag->current_basic_block->instruction_list.last();
...@@ -6005,8 +6000,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6005,8 +6000,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6005 }6000 }
60066001
6007 if (!instr_is_unreachable(body_result)) {6002 if (!instr_is_unreachable(body_result)) {
6008 ir_mark_gen(ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result));6003 ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result);
6009 ir_mark_gen(ir_build_br(ag, payload_scope, node, continue_block, is_comptime));6004 ir_build_br(ag, payload_scope, node, continue_block, is_comptime);
6010 }6005 }
60116006
6012 if (continue_expr_node) {6007 if (continue_expr_node) {
...@@ -6015,8 +6010,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6015,8 +6010,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6015 if (expr_result == ag->codegen->invalid_inst_src)6010 if (expr_result == ag->codegen->invalid_inst_src)
6016 return expr_result;6011 return expr_result;
6017 if (!instr_is_unreachable(expr_result)) {6012 if (!instr_is_unreachable(expr_result)) {
6018 ir_mark_gen(ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result));6013 ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result);
6019 ir_mark_gen(ir_build_br(ag, payload_scope, node, cond_block, is_comptime));6014 ir_build_br(ag, payload_scope, node, cond_block, is_comptime);
6020 }6015 }
6021 }6016 }
60226017
...@@ -6041,7 +6036,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6041,7 +6036,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6041 if (else_result == ag->codegen->invalid_inst_src)6036 if (else_result == ag->codegen->invalid_inst_src)
6042 return else_result;6037 return else_result;
6043 if (!instr_is_unreachable(else_result))6038 if (!instr_is_unreachable(else_result))
6044 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));6039 ir_build_br(ag, scope, node, end_block, is_comptime);
6045 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6040 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6046 ir_set_cursor_at_end_and_append_block(ag, end_block);6041 ir_set_cursor_at_end_and_append_block(ag, end_block);
6047 if (else_result) {6042 if (else_result) {
...@@ -6075,12 +6070,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6075,12 +6070,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6075 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);6070 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);
6076 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);6071 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);
6077 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;6072 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6078 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));6073 IrInstSrc *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6079 IrInstSrc *cond_br_inst;6074 IrInstSrc *cond_br_inst;
6080 if (!instr_is_unreachable(is_non_null)) {6075 if (!instr_is_unreachable(is_non_null)) {
6081 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,6076 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,
6082 body_block, else_block, is_comptime);6077 body_block, else_block, is_comptime);
6083 cond_br_inst->is_gen = true;
6084 } else {6078 } else {
6085 // for the purposes of the source instruction to ir_build_result_peers6079 // for the purposes of the source instruction to ir_build_result_peers
6086 cond_br_inst = ag->current_basic_block->instruction_list.last();6080 cond_br_inst = ag->current_basic_block->instruction_list.last();
...@@ -6123,8 +6117,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6123,8 +6117,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6123 }6117 }
61246118
6125 if (!instr_is_unreachable(body_result)) {6119 if (!instr_is_unreachable(body_result)) {
6126 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result));6120 ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result);
6127 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));6121 ir_build_br(ag, child_scope, node, continue_block, is_comptime);
6128 }6122 }
61296123
6130 if (continue_expr_node) {6124 if (continue_expr_node) {
...@@ -6133,8 +6127,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6133,8 +6127,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6133 if (expr_result == ag->codegen->invalid_inst_src)6127 if (expr_result == ag->codegen->invalid_inst_src)
6134 return expr_result;6128 return expr_result;
6135 if (!instr_is_unreachable(expr_result)) {6129 if (!instr_is_unreachable(expr_result)) {
6136 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result));6130 ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result);
6137 ir_mark_gen(ir_build_br(ag, child_scope, node, cond_block, is_comptime));6131 ir_build_br(ag, child_scope, node, cond_block, is_comptime);
6138 }6132 }
6139 }6133 }
61406134
...@@ -6151,7 +6145,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6151,7 +6145,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6151 if (else_result == ag->codegen->invalid_inst_src)6145 if (else_result == ag->codegen->invalid_inst_src)
6152 return else_result;6146 return else_result;
6153 if (!instr_is_unreachable(else_result))6147 if (!instr_is_unreachable(else_result))
6154 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));6148 ir_build_br(ag, scope, node, end_block, is_comptime);
6155 }6149 }
6156 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6150 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6157 ir_set_cursor_at_end_and_append_block(ag, end_block);6151 ir_set_cursor_at_end_and_append_block(ag, end_block);
...@@ -6175,12 +6169,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6175,12 +6169,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6175 if (cond_val == ag->codegen->invalid_inst_src)6169 if (cond_val == ag->codegen->invalid_inst_src)
6176 return cond_val;6170 return cond_val;
6177 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;6171 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6178 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));6172 IrInstSrc *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6179 IrInstSrc *cond_br_inst;6173 IrInstSrc *cond_br_inst;
6180 if (!instr_is_unreachable(cond_val)) {6174 if (!instr_is_unreachable(cond_val)) {
6181 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,6175 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,
6182 body_block, else_block, is_comptime);6176 body_block, else_block, is_comptime);
6183 cond_br_inst->is_gen = true;
6184 } else {6177 } else {
6185 // for the purposes of the source instruction to ir_build_result_peers6178 // for the purposes of the source instruction to ir_build_result_peers
6186 cond_br_inst = ag->current_basic_block->instruction_list.last();6179 cond_br_inst = ag->current_basic_block->instruction_list.last();
...@@ -6219,8 +6212,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6219,8 +6212,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6219 }6212 }
62206213
6221 if (!instr_is_unreachable(body_result)) {6214 if (!instr_is_unreachable(body_result)) {
6222 ir_mark_gen(ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result));6215 ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result);
6223 ir_mark_gen(ir_build_br(ag, scope, node, continue_block, is_comptime));6216 ir_build_br(ag, scope, node, continue_block, is_comptime);
6224 }6217 }
62256218
6226 if (continue_expr_node) {6219 if (continue_expr_node) {
...@@ -6229,8 +6222,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6229,8 +6222,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6229 if (expr_result == ag->codegen->invalid_inst_src)6222 if (expr_result == ag->codegen->invalid_inst_src)
6230 return expr_result;6223 return expr_result;
6231 if (!instr_is_unreachable(expr_result)) {6224 if (!instr_is_unreachable(expr_result)) {
6232 ir_mark_gen(ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result));6225 ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result);
6233 ir_mark_gen(ir_build_br(ag, scope, node, cond_block, is_comptime));6226 ir_build_br(ag, scope, node, cond_block, is_comptime);
6234 }6227 }
6235 }6228 }
62366229
...@@ -6248,7 +6241,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6248,7 +6241,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6248 if (else_result == ag->codegen->invalid_inst_src)6241 if (else_result == ag->codegen->invalid_inst_src)
6249 return else_result;6242 return else_result;
6250 if (!instr_is_unreachable(else_result))6243 if (!instr_is_unreachable(else_result))
6251 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));6244 ir_build_br(ag, scope, node, end_block, is_comptime);
6252 }6245 }
6253 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6246 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6254 ir_set_cursor_at_end_and_append_block(ag, end_block);6247 ir_set_cursor_at_end_and_append_block(ag, end_block);
...@@ -6332,9 +6325,9 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -6332,9 +6325,9 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode
6332 IrInstSrc *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);6325 IrInstSrc *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);
6333 IrInstSrc *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);6326 IrInstSrc *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
6334 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;6327 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6335 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, parent_scope, node));6328 IrInstSrc *void_else_value = else_node ? nullptr : ir_build_const_void(ag, parent_scope, node);
6336 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(ag, parent_scope, node, cond,6329 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, cond,
6337 body_block, else_block, is_comptime));6330 body_block, else_block, is_comptime);
63386331
6339 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc, is_comptime);6332 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc, is_comptime);
63406333
...@@ -6377,8 +6370,8 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -6377,8 +6370,8 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode
6377 }6370 }
63786371
6379 if (!instr_is_unreachable(body_result)) {6372 if (!instr_is_unreachable(body_result)) {
6380 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result));6373 ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result);
6381 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));6374 ir_build_br(ag, child_scope, node, continue_block, is_comptime);
6382 }6375 }
63836376
6384 ir_set_cursor_at_end_and_append_block(ag, continue_block);6377 ir_set_cursor_at_end_and_append_block(ag, continue_block);
...@@ -6399,7 +6392,7 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -6399,7 +6392,7 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode
6399 if (else_result == ag->codegen->invalid_inst_src)6392 if (else_result == ag->codegen->invalid_inst_src)
6400 return else_result;6393 return else_result;
6401 if (!instr_is_unreachable(else_result))6394 if (!instr_is_unreachable(else_result))
6402 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));6395 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
6403 }6396 }
6404 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6397 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6405 ir_set_cursor_at_end_and_append_block(ag, end_block);6398 ir_set_cursor_at_end_and_append_block(ag, end_block);
...@@ -6719,7 +6712,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod...@@ -6719,7 +6712,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod
6719 return then_expr_result;6712 return then_expr_result;
6720 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;6713 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6721 if (!instr_is_unreachable(then_expr_result))6714 if (!instr_is_unreachable(then_expr_result))
6722 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6715 ir_build_br(ag, scope, node, endif_block, is_comptime);
67236716
6724 ir_set_cursor_at_end_and_append_block(ag, else_block);6717 ir_set_cursor_at_end_and_append_block(ag, else_block);
6725 IrInstSrc *else_expr_result;6718 IrInstSrc *else_expr_result;
...@@ -6733,7 +6726,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod...@@ -6733,7 +6726,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod
6733 }6726 }
6734 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6727 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6735 if (!instr_is_unreachable(else_expr_result))6728 if (!instr_is_unreachable(else_expr_result))
6736 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6729 ir_build_br(ag, scope, node, endif_block, is_comptime);
67376730
6738 ir_set_cursor_at_end_and_append_block(ag, endif_block);6731 ir_set_cursor_at_end_and_append_block(ag, endif_block);
6739 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);6732 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
...@@ -6802,7 +6795,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -6802,7 +6795,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
6802 return then_expr_result;6795 return then_expr_result;
6803 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;6796 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6804 if (!instr_is_unreachable(then_expr_result))6797 if (!instr_is_unreachable(then_expr_result))
6805 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6798 ir_build_br(ag, scope, node, endif_block, is_comptime);
68066799
6807 ir_set_cursor_at_end_and_append_block(ag, else_block);6800 ir_set_cursor_at_end_and_append_block(ag, else_block);
68086801
...@@ -6831,7 +6824,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -6831,7 +6824,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
6831 }6824 }
6832 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6825 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6833 if (!instr_is_unreachable(else_expr_result))6826 if (!instr_is_unreachable(else_expr_result))
6834 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6827 ir_build_br(ag, scope, node, endif_block, is_comptime);
68356828
6836 ir_set_cursor_at_end_and_append_block(ag, endif_block);6829 ir_set_cursor_at_end_and_append_block(ag, endif_block);
6837 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);6830 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
...@@ -6893,7 +6886,7 @@ static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *sw...@@ -6893,7 +6886,7 @@ static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *sw
6893 if (expr_result == ag->codegen->invalid_inst_src)6886 if (expr_result == ag->codegen->invalid_inst_src)
6894 return false;6887 return false;
6895 if (!instr_is_unreachable(expr_result))6888 if (!instr_is_unreachable(expr_result))
6896 ir_mark_gen(ir_build_br(ag, scope, switch_node, end_block, is_comptime));6889 ir_build_br(ag, scope, switch_node, end_block, is_comptime);
6897 incoming_blocks->append(ag->current_basic_block);6890 incoming_blocks->append(ag->current_basic_block);
6898 incoming_values->append(expr_result);6891 incoming_values->append(expr_result);
6899 return true;6892 return true;
...@@ -7008,8 +7001,8 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -7008,8 +7001,8 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
70087001
7009 assert(ok_bit);7002 assert(ok_bit);
7010 assert(last_item_node);7003 assert(last_item_node);
7011 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(ag, scope, last_item_node, ok_bit,7004 IrInstSrc *br_inst = ir_build_cond_br(ag, scope, last_item_node, ok_bit,
7012 range_block_yes, range_block_no, is_comptime));7005 range_block_yes, range_block_no, is_comptime);
7013 if (peer_parent->base.source_instruction == nullptr) {7006 if (peer_parent->base.source_instruction == nullptr) {
7014 peer_parent->base.source_instruction = br_inst;7007 peer_parent->base.source_instruction = br_inst;
7015 }7008 }
...@@ -7033,7 +7026,7 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -7033,7 +7026,7 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
7033 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,7026 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7034 buf_sprintf("multiple else prongs in switch expression"));7027 buf_sprintf("multiple else prongs in switch expression"));
7035 add_error_note(ag->codegen, msg, else_prong,7028 add_error_note(ag->codegen, msg, else_prong,
7036 buf_sprintf("previous else prong is here"));7029 buf_sprintf("previous else prong here"));
7037 return ag->codegen->invalid_inst_src;7030 return ag->codegen->invalid_inst_src;
7038 }7031 }
7039 else_prong = prong_node;7032 else_prong = prong_node;
...@@ -7044,7 +7037,7 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -7044,7 +7037,7 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
7044 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,7037 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7045 buf_sprintf("multiple '_' prongs in switch expression"));7038 buf_sprintf("multiple '_' prongs in switch expression"));
7046 add_error_note(ag->codegen, msg, underscore_prong,7039 add_error_note(ag->codegen, msg, underscore_prong,
7047 buf_sprintf("previous '_' prong is here"));7040 buf_sprintf("previous '_' prong here"));
7048 return ag->codegen->invalid_inst_src;7041 return ag->codegen->invalid_inst_src;
7049 }7042 }
7050 underscore_prong = prong_node;7043 underscore_prong = prong_node;
...@@ -7056,10 +7049,10 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -7056,10 +7049,10 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
7056 buf_sprintf("else and '_' prong in switch expression"));7049 buf_sprintf("else and '_' prong in switch expression"));
7057 if (underscore_prong == prong_node)7050 if (underscore_prong == prong_node)
7058 add_error_note(ag->codegen, msg, else_prong,7051 add_error_note(ag->codegen, msg, else_prong,
7059 buf_sprintf("else prong is here"));7052 buf_sprintf("else prong here"));
7060 else7053 else
7061 add_error_note(ag->codegen, msg, underscore_prong,7054 add_error_note(ag->codegen, msg, underscore_prong,
7062 buf_sprintf("'_' prong is here"));7055 buf_sprintf("'_' prong here"));
7063 return ag->codegen->invalid_inst_src;7056 return ag->codegen->invalid_inst_src;
7064 }7057 }
7065 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);7058 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
...@@ -7349,14 +7342,14 @@ static IrInstSrc *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNo...@@ -7349,14 +7342,14 @@ static IrInstSrc *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNo
73497342
7350 for (size_t i = 0; i < runtime_scopes.length; i += 1) {7343 for (size_t i = 0; i < runtime_scopes.length; i += 1) {
7351 ScopeRuntime *scope_runtime = runtime_scopes.at(i);7344 ScopeRuntime *scope_runtime = runtime_scopes.at(i);
7352 ir_mark_gen(ir_build_check_runtime_scope(ag, continue_scope, node, scope_runtime->is_comptime, is_comptime));7345 ir_build_check_runtime_scope(ag, continue_scope, node, scope_runtime->is_comptime, is_comptime);
7353 }7346 }
7354 runtime_scopes.deinit();7347 runtime_scopes.deinit();
73557348
7356 Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;7349 Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;
7357 if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))7350 if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))
7358 return ag->codegen->invalid_inst_src;7351 return ag->codegen->invalid_inst_src;
7359 return ir_mark_gen(ir_build_br(ag, continue_scope, node, dest_block, is_comptime));7352 return ir_build_br(ag, continue_scope, node, dest_block, is_comptime);
7360}7353}
73617354
7362static IrInstSrc *astgen_error_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {7355static IrInstSrc *astgen_error_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
...@@ -7482,7 +7475,7 @@ static IrInstSrc *astgen_catch(Stage1AstGen *ag, Scope *parent_scope, AstNode *n...@@ -7482,7 +7475,7 @@ static IrInstSrc *astgen_catch(Stage1AstGen *ag, Scope *parent_scope, AstNode *n
7482 return ag->codegen->invalid_inst_src;7475 return ag->codegen->invalid_inst_src;
7483 Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;7476 Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;
7484 if (!instr_is_unreachable(err_result))7477 if (!instr_is_unreachable(err_result))
7485 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));7478 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
74867479
7487 ir_set_cursor_at_end_and_append_block(ag, ok_block);7480 ir_set_cursor_at_end_and_append_block(ag, ok_block);
7488 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, parent_scope, node, err_union_ptr, false, false);7481 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, parent_scope, node, err_union_ptr, false, false);
...@@ -7757,9 +7750,9 @@ static IrInstSrc *astgen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -7757,9 +7750,9 @@ static IrInstSrc *astgen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode
7757 IrInstSrc *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);7750 IrInstSrc *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);
7758 if (susp_res == ag->codegen->invalid_inst_src)7751 if (susp_res == ag->codegen->invalid_inst_src)
7759 return ag->codegen->invalid_inst_src;7752 return ag->codegen->invalid_inst_src;
7760 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.suspend.block, susp_res));7753 ir_build_check_statement_is_void(ag, child_scope, node->data.suspend.block, susp_res);
77617754
7762 return ir_mark_gen(ir_build_suspend_finish_src(ag, parent_scope, node, begin));7755 return ir_build_suspend_finish_src(ag, parent_scope, node, begin);
7763}7756}
77647757
7765static IrInstSrc *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *scope,7758static IrInstSrc *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *scope,
...@@ -8073,13 +8066,13 @@ bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *sta...@@ -8073,13 +8066,13 @@ bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *sta
8073 }8066 }
80748067
8075 if (!instr_is_unreachable(result)) {8068 if (!instr_is_unreachable(result)) {
8076 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, result->base.source_node, result, nullptr));8069 ir_build_add_implicit_return_type(ag, scope, result->base.source_node, result, nullptr);
8077 // no need for save_err_ret_addr because this cannot return error8070 // no need for save_err_ret_addr because this cannot return error
8078 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();8071 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
8079 result_loc_ret->base.id = ResultLocIdReturn;8072 result_loc_ret->base.id = ResultLocIdReturn;
8080 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);8073 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
8081 ir_mark_gen(ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base));8074 ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base);
8082 ir_mark_gen(ir_build_return_src(ag, scope, result->base.source_node, result));8075 ir_build_return_src(ag, scope, result->base.source_node, result);
8083 }8076 }
80848077
8085 return true;8078 return true;
src/stage1/ir.cpp+9-19
...@@ -5407,16 +5407,6 @@ static void ir_finish_bb(IrAnalyze *ira) {...@@ -5407,16 +5407,6 @@ static void ir_finish_bb(IrAnalyze *ira) {
5407 ira->new_irb.current_basic_block->debug_id);5407 ira->new_irb.current_basic_block->debug_id);
5408 }5408 }
5409 }5409 }
5410 ira->instruction_index += 1;
5411 while (ira->instruction_index < ira->zir_current_basic_block->instruction_list.length) {
5412 IrInstSrc *next_instruction = ira->zir_current_basic_block->instruction_list.at(ira->instruction_index);
5413 if (!next_instruction->is_gen) {
5414 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code"));
5415 break;
5416 }
5417 ira->instruction_index += 1;
5418 }
5419
5420 ir_start_next_bb(ira);5410 ir_start_next_bb(ira);
5421}5411}
54225412
...@@ -11107,7 +11097,7 @@ static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport...@@ -11107,7 +11097,7 @@ static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport
11107 AstNode *other_export_node = entry->value->source_node;11097 AstNode *other_export_node = entry->value->source_node;
11108 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,11098 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
11109 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name)));11099 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name)));
11110 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here"));11100 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol here"));
11111 return ira->codegen->invalid_inst_gen;11101 return ira->codegen->invalid_inst_gen;
11112 }11102 }
1111311103
...@@ -11413,7 +11403,7 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern...@@ -11413,7 +11403,7 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern
11413 AstNode *other_extern_node = entry->value->source_node;11403 AstNode *other_extern_node = entry->value->source_node;
11414 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,11404 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
11415 buf_sprintf("extern symbol collision: '%s'", buf_ptr(symbol_name)));11405 buf_sprintf("extern symbol collision: '%s'", buf_ptr(symbol_name)));
11416 add_error_note(ira->codegen, msg, other_extern_node, buf_sprintf("other symbol is here"));11406 add_error_note(ira->codegen, msg, other_extern_node, buf_sprintf("other symbol here"));
11417 return ira->codegen->invalid_inst_gen;11407 return ira->codegen->invalid_inst_gen;
11418 }11408 }
1141911409
...@@ -15934,7 +15924,7 @@ static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopC...@@ -15934,7 +15924,7 @@ static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopC
15934 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op);15924 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op);
15935}15925}
1593615926
15937static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, bool is_gen) {15927static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value) {
15938 if (type_is_invalid(value->value->type))15928 if (type_is_invalid(value->value->type))
15939 return ira->codegen->invalid_inst_gen;15929 return ira->codegen->invalid_inst_gen;
1594015930
...@@ -15943,7 +15933,7 @@ static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrI...@@ -15943,7 +15933,7 @@ static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrI
15943 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name)));15933 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name)));
15944 return ira->codegen->invalid_inst_gen;15934 return ira->codegen->invalid_inst_gen;
15945 }15935 }
15946 if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) {15936 if (!value->value->type->data.unionation.have_explicit_tag_type) {
15947 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum"));15937 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum"));
15948 if (value->value->type->data.unionation.decl_node != nullptr) {15938 if (value->value->type->data.unionation.decl_node != nullptr) {
15949 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node,15939 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node,
...@@ -16906,7 +16896,7 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc...@@ -16906,7 +16896,7 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
16906 }16896 }
1690716897
16908 if (target_type->id == ZigTypeIdUnion) {16898 if (target_type->id == ZigTypeIdUnion) {
16909 target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen);16899 target = ir_analyze_union_tag(ira, &instruction->base.base, target);
16910 if (type_is_invalid(target->value->type))16900 if (type_is_invalid(target->value->type))
16911 return ira->codegen->invalid_inst_gen;16901 return ira->codegen->invalid_inst_gen;
16912 target_type = target->value->type;16902 target_type = target->value->type;
...@@ -21742,7 +21732,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,...@@ -21742,7 +21732,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
21742 ErrorMsg *msg = ir_add_error(ira, &start_value->base,21732 ErrorMsg *msg = ir_add_error(ira, &start_value->base,
21743 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name),21733 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name),
21744 buf_ptr(enum_field->name)));21734 buf_ptr(enum_field->name)));
21745 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here"));21735 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value here"));
21746 }21736 }
21747 bigint_incr(&field_index);21737 bigint_incr(&field_index);
21748 }21738 }
...@@ -21828,7 +21818,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,...@@ -21828,7 +21818,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
21828 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name;21818 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name;
21829 ErrorMsg *msg = ir_add_error(ira, &start_value->base,21819 ErrorMsg *msg = ir_add_error(ira, &start_value->base,
21830 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name)));21820 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name)));
21831 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here"));21821 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value here"));
21832 }21822 }
21833 field_prev_uses[start_index] = start_value->base.source_node;21823 field_prev_uses[start_index] = start_value->base.source_node;
21834 }21824 }
...@@ -21890,7 +21880,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,...@@ -21890,7 +21880,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
21890 start_value->base.source_node);21880 start_value->base.source_node);
21891 if (prev_node != nullptr) {21881 if (prev_node != nullptr) {
21892 ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value"));21882 ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value"));
21893 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here"));21883 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value here"));
21894 return ira->codegen->invalid_inst_gen;21884 return ira->codegen->invalid_inst_gen;
21895 }21885 }
21896 }21886 }
...@@ -21975,7 +21965,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,...@@ -21975,7 +21965,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
21975 auto entry = prevs.put_unique(const_expr_val->data.x_type, value);21965 auto entry = prevs.put_unique(const_expr_val->data.x_type, value);
21976 if(entry != nullptr) {21966 if(entry != nullptr) {
21977 ErrorMsg *msg = ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value"));21967 ErrorMsg *msg = ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value"));
21978 add_error_note(ira->codegen, msg, entry->value->base.source_node, buf_sprintf("previous value is here"));21968 add_error_note(ira->codegen, msg, entry->value->base.source_node, buf_sprintf("previous value here"));
21979 prevs.deinit();21969 prevs.deinit();
21980 return ira->codegen->invalid_inst_gen;21970 return ira->codegen->invalid_inst_gen;
21981 }21971 }
src/stage1/ir_print.cpp-2
...@@ -577,8 +577,6 @@ static void ir_print_prefix_src(IrPrintSrc *irp, IrInstSrc *instruction, bool tr...@@ -577,8 +577,6 @@ static void ir_print_prefix_src(IrPrintSrc *irp, IrInstSrc *instruction, bool tr
577 const char *type_name;577 const char *type_name;
578 if (instruction->id == IrInstSrcIdConst) {578 if (instruction->id == IrInstSrcIdConst) {
579 type_name = buf_ptr(&reinterpret_cast<IrInstSrcConst *>(instruction)->value->type->name);579 type_name = buf_ptr(&reinterpret_cast<IrInstSrcConst *>(instruction)->value->type->name);
580 } else if (instruction->is_noreturn) {
581 type_name = "noreturn";
582 } else {580 } else {
583 type_name = "(unknown)";581 type_name = "(unknown)";
584 }582 }
src/target.zig+67
...@@ -170,6 +170,73 @@ pub fn hasValgrindSupport(target: std.Target) bool {...@@ -170,6 +170,73 @@ pub fn hasValgrindSupport(target: std.Target) bool {
170 }170 }
171}171}
172172
173/// The set of targets that LLVM has non-experimental support for.
174/// Used to select between LLVM backend and self-hosted backend when compiling in
175/// release modes.
176pub fn hasLlvmSupport(target: std.Target) bool {
177 return switch (target.cpu.arch) {
178 .arm,
179 .armeb,
180 .aarch64,
181 .aarch64_be,
182 .aarch64_32,
183 .arc,
184 .avr,
185 .bpfel,
186 .bpfeb,
187 .csky,
188 .hexagon,
189 .mips,
190 .mipsel,
191 .mips64,
192 .mips64el,
193 .msp430,
194 .powerpc,
195 .powerpcle,
196 .powerpc64,
197 .powerpc64le,
198 .r600,
199 .amdgcn,
200 .riscv32,
201 .riscv64,
202 .sparc,
203 .sparcv9,
204 .sparcel,
205 .s390x,
206 .tce,
207 .tcele,
208 .thumb,
209 .thumbeb,
210 .i386,
211 .x86_64,
212 .xcore,
213 .nvptx,
214 .nvptx64,
215 .le32,
216 .le64,
217 .amdil,
218 .amdil64,
219 .hsail,
220 .hsail64,
221 .spir,
222 .spir64,
223 .kalimba,
224 .shave,
225 .lanai,
226 .wasm32,
227 .wasm64,
228 .renderscript32,
229 .renderscript64,
230 .ve,
231 => true,
232
233 .spu_2,
234 .spirv32,
235 .spirv64,
236 => false,
237 };
238}
239
173pub fn supportsStackProbing(target: std.Target) bool {240pub fn supportsStackProbing(target: std.Target) bool {
174 return target.os.tag != .windows and target.os.tag != .uefi and241 return target.os.tag != .windows and target.os.tag != .uefi and
175 (target.cpu.arch == .i386 or target.cpu.arch == .x86_64);242 (target.cpu.arch == .i386 or target.cpu.arch == .x86_64);
src/test.zig+328-74
...@@ -10,18 +10,25 @@ const enable_wine: bool = build_options.enable_wine;...@@ -10,18 +10,25 @@ const enable_wine: bool = build_options.enable_wine;
10const enable_wasmtime: bool = build_options.enable_wasmtime;10const enable_wasmtime: bool = build_options.enable_wasmtime;
11const enable_darling: bool = build_options.enable_darling;11const enable_darling: bool = build_options.enable_darling;
12const glibc_multi_install_dir: ?[]const u8 = build_options.glibc_multi_install_dir;12const glibc_multi_install_dir: ?[]const u8 = build_options.glibc_multi_install_dir;
13const skip_compile_errors = build_options.skip_compile_errors;
13const ThreadPool = @import("ThreadPool.zig");14const ThreadPool = @import("ThreadPool.zig");
14const CrossTarget = std.zig.CrossTarget;15const CrossTarget = std.zig.CrossTarget;
16const print = std.debug.print;
17const assert = std.debug.assert;
1518
16const zig_h = link.File.C.zig_h;19const zig_h = link.File.C.zig_h;
1720
18const hr = "=" ** 80;21const hr = "=" ** 80;
1922
20test "self-hosted" {23test {
24 if (build_options.is_stage1) {
25 @import("stage1.zig").os_init();
26 }
27
21 var ctx = TestContext.init();28 var ctx = TestContext.init();
22 defer ctx.deinit();29 defer ctx.deinit();
2330
24 try @import("stage2_tests").addCases(&ctx);31 try @import("test_cases").addCases(&ctx);
2532
26 try ctx.run();33 try ctx.run();
27}34}
...@@ -30,7 +37,11 @@ const ErrorMsg = union(enum) {...@@ -30,7 +37,11 @@ const ErrorMsg = union(enum) {
30 src: struct {37 src: struct {
31 src_path: []const u8,38 src_path: []const u8,
32 msg: []const u8,39 msg: []const u8,
40 // maxint means match anything
41 // this is a workaround for stage1 compiler bug I ran into when making it ?u32
33 line: u32,42 line: u32,
43 // maxint means match anything
44 // this is a workaround for stage1 compiler bug I ran into when making it ?u32
34 column: u32,45 column: u32,
35 kind: Kind,46 kind: Kind,
36 },47 },
...@@ -74,23 +85,32 @@ const ErrorMsg = union(enum) {...@@ -74,23 +85,32 @@ const ErrorMsg = union(enum) {
74 _ = options;85 _ = options;
75 switch (self) {86 switch (self) {
76 .src => |src| {87 .src => |src| {
77 return writer.print("{s}:{d}:{d}: {s}: {s}", .{88 if (!std.mem.eql(u8, src.src_path, "?") or
78 src.src_path,89 src.line != std.math.maxInt(u32) or
79 src.line + 1,90 src.column != std.math.maxInt(u32))
80 src.column + 1,91 {
81 @tagName(src.kind),92 try writer.print("{s}:", .{src.src_path});
82 src.msg,93 if (src.line != std.math.maxInt(u32)) {
83 });94 try writer.print("{d}:", .{src.line + 1});
95 } else {
96 try writer.writeAll("?:");
97 }
98 if (src.column != std.math.maxInt(u32)) {
99 try writer.print("{d}: ", .{src.column + 1});
100 } else {
101 try writer.writeAll("?: ");
102 }
103 }
104 return writer.print("{s}: {s}", .{ @tagName(src.kind), src.msg });
84 },105 },
85 .plain => |plain| {106 .plain => |plain| {
86 return writer.print("{s}: {s}", .{ plain.msg, @tagName(plain.kind) });107 return writer.print("{s}: {s}", .{ @tagName(plain.kind), plain.msg });
87 },108 },
88 }109 }
89 }110 }
90};111};
91112
92pub const TestContext = struct {113pub const TestContext = struct {
93 /// TODO: find a way to treat cases as individual tests (shouldn't show "1 test passed" if there are 200 cases)
94 cases: std.ArrayList(Case),114 cases: std.ArrayList(Case),
95115
96 pub const Update = struct {116 pub const Update = struct {
...@@ -127,6 +147,12 @@ pub const TestContext = struct {...@@ -127,6 +147,12 @@ pub const TestContext = struct {
127 path: []const u8,147 path: []const u8,
128 };148 };
129149
150 pub const Backend = enum {
151 stage1,
152 stage2,
153 llvm,
154 };
155
130 /// A `Case` consists of a list of `Update`. The same `Compilation` is used for each156 /// A `Case` consists of a list of `Update`. The same `Compilation` is used for each
131 /// update, so each update's source is treated as a single file being157 /// update, so each update's source is treated as a single file being
132 /// updated by the test harness and incrementally compiled.158 /// updated by the test harness and incrementally compiled.
...@@ -140,13 +166,20 @@ pub const TestContext = struct {...@@ -140,13 +166,20 @@ pub const TestContext = struct {
140 /// In order to be able to run e.g. Execution updates, this must be set166 /// In order to be able to run e.g. Execution updates, this must be set
141 /// to Executable.167 /// to Executable.
142 output_mode: std.builtin.OutputMode,168 output_mode: std.builtin.OutputMode,
169 optimize_mode: std.builtin.Mode = .Debug,
143 updates: std.ArrayList(Update),170 updates: std.ArrayList(Update),
144 object_format: ?std.Target.ObjectFormat = null,171 object_format: ?std.Target.ObjectFormat = null,
145 emit_h: bool = false,172 emit_h: bool = false,
146 llvm_backend: bool = false,173 is_test: bool = false,
174 expect_exact: bool = false,
175 backend: Backend = .stage2,
147176
148 files: std.ArrayList(File),177 files: std.ArrayList(File),
149178
179 pub fn addSourceFile(case: *Case, name: []const u8, src: [:0]const u8) void {
180 case.files.append(.{ .path = name, .src = src }) catch @panic("out of memory");
181 }
182
150 /// Adds a subcase in which the module is updated with `src`, and a C183 /// Adds a subcase in which the module is updated with `src`, and a C
151 /// header is generated.184 /// header is generated.
152 pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {185 pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {
...@@ -201,8 +234,14 @@ pub const TestContext = struct {...@@ -201,8 +234,14 @@ pub const TestContext = struct {
201 const kind_text = it.next() orelse @panic("missing 'error'/'note'");234 const kind_text = it.next() orelse @panic("missing 'error'/'note'");
202 const msg = it.rest()[1..]; // skip over the space at end of "error: "235 const msg = it.rest()[1..]; // skip over the space at end of "error: "
203236
204 const line = std.fmt.parseInt(u32, line_text, 10) catch @panic("bad line number");237 const line: ?u32 = if (std.mem.eql(u8, line_text, "?"))
205 const column = std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number");238 null
239 else
240 std.fmt.parseInt(u32, line_text, 10) catch @panic("bad line number");
241 const column: ?u32 = if (std.mem.eql(u8, line_text, "?"))
242 null
243 else
244 std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number");
206 const kind: ErrorMsg.Kind = if (std.mem.eql(u8, kind_text, " error"))245 const kind: ErrorMsg.Kind = if (std.mem.eql(u8, kind_text, " error"))
207 .@"error"246 .@"error"
208 else if (std.mem.eql(u8, kind_text, " note"))247 else if (std.mem.eql(u8, kind_text, " note"))
...@@ -210,16 +249,28 @@ pub const TestContext = struct {...@@ -210,16 +249,28 @@ pub const TestContext = struct {
210 else249 else
211 @panic("expected 'error'/'note'");250 @panic("expected 'error'/'note'");
212251
213 if (line == 0 or column == 0) {252 const line_0based: u32 = if (line) |n| blk: {
214 @panic("line and column must be specified starting at one");253 if (n == 0) {
215 }254 print("{s}: line must be specified starting at one\n", .{self.name});
255 return;
256 }
257 break :blk n - 1;
258 } else std.math.maxInt(u32);
259
260 const column_0based: u32 = if (column) |n| blk: {
261 if (n == 0) {
262 print("{s}: line must be specified starting at one\n", .{self.name});
263 return;
264 }
265 break :blk n - 1;
266 } else std.math.maxInt(u32);
216267
217 array[i] = .{268 array[i] = .{
218 .src = .{269 .src = .{
219 .src_path = src_path,270 .src_path = src_path,
220 .msg = msg,271 .msg = msg,
221 .line = line - 1,272 .line = line_0based,
222 .column = column - 1,273 .column = column_0based,
223 .kind = kind,274 .kind = kind,
224 },275 },
225 };276 };
...@@ -254,11 +305,6 @@ pub const TestContext = struct {...@@ -254,11 +305,6 @@ pub const TestContext = struct {
254 return ctx.addExe(name, target);305 return ctx.addExe(name, target);
255 }306 }
256307
257 /// Adds a test case for ZIR input, producing an executable
258 pub fn exeZIR(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {
259 return ctx.addExe(name, target, .ZIR);
260 }
261
262 pub fn exeFromCompiledC(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {308 pub fn exeFromCompiledC(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {
263 const prefixed_name = std.fmt.allocPrint(ctx.cases.allocator, "CBE: {s}", .{name}) catch309 const prefixed_name = std.fmt.allocPrint(ctx.cases.allocator, "CBE: {s}", .{name}) catch
264 @panic("out of memory");310 @panic("out of memory");
...@@ -282,7 +328,7 @@ pub const TestContext = struct {...@@ -282,7 +328,7 @@ pub const TestContext = struct {
282 .updates = std.ArrayList(Update).init(ctx.cases.allocator),328 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
283 .output_mode = .Exe,329 .output_mode = .Exe,
284 .files = std.ArrayList(File).init(ctx.cases.allocator),330 .files = std.ArrayList(File).init(ctx.cases.allocator),
285 .llvm_backend = true,331 .backend = .llvm,
286 }) catch @panic("out of memory");332 }) catch @panic("out of memory");
287 return &ctx.cases.items[ctx.cases.items.len - 1];333 return &ctx.cases.items[ctx.cases.items.len - 1];
288 }334 }
...@@ -302,6 +348,22 @@ pub const TestContext = struct {...@@ -302,6 +348,22 @@ pub const TestContext = struct {
302 return &ctx.cases.items[ctx.cases.items.len - 1];348 return &ctx.cases.items[ctx.cases.items.len - 1];
303 }349 }
304350
351 pub fn addTest(
352 ctx: *TestContext,
353 name: []const u8,
354 target: CrossTarget,
355 ) *Case {
356 ctx.cases.append(Case{
357 .name = name,
358 .target = target,
359 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
360 .output_mode = .Exe,
361 .is_test = true,
362 .files = std.ArrayList(File).init(ctx.cases.allocator),
363 }) catch @panic("out of memory");
364 return &ctx.cases.items[ctx.cases.items.len - 1];
365 }
366
305 /// Adds a test case for Zig input, producing an object file.367 /// Adds a test case for Zig input, producing an object file.
306 pub fn obj(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {368 pub fn obj(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {
307 return ctx.addObj(name, target);369 return ctx.addObj(name, target);
...@@ -333,6 +395,45 @@ pub const TestContext = struct {...@@ -333,6 +395,45 @@ pub const TestContext = struct {
333 ctx.addC(name, target).addHeader(src, zig_h ++ out);395 ctx.addC(name, target).addHeader(src, zig_h ++ out);
334 }396 }
335397
398 pub fn objErrStage1(
399 ctx: *TestContext,
400 name: []const u8,
401 src: [:0]const u8,
402 expected_errors: []const []const u8,
403 ) void {
404 if (skip_compile_errors) return;
405
406 const case = ctx.addObj(name, .{});
407 case.backend = .stage1;
408 case.addError(src, expected_errors);
409 }
410
411 pub fn testErrStage1(
412 ctx: *TestContext,
413 name: []const u8,
414 src: [:0]const u8,
415 expected_errors: []const []const u8,
416 ) void {
417 if (skip_compile_errors) return;
418
419 const case = ctx.addTest(name, .{});
420 case.backend = .stage1;
421 case.addError(src, expected_errors);
422 }
423
424 pub fn exeErrStage1(
425 ctx: *TestContext,
426 name: []const u8,
427 src: [:0]const u8,
428 expected_errors: []const []const u8,
429 ) void {
430 if (skip_compile_errors) return;
431
432 const case = ctx.addExe(name, .{});
433 case.backend = .stage1;
434 case.addError(src, expected_errors);
435 }
436
336 pub fn addCompareOutput(437 pub fn addCompareOutput(
337 ctx: *TestContext,438 ctx: *TestContext,
338 name: []const u8,439 name: []const u8,
...@@ -386,18 +487,6 @@ pub const TestContext = struct {...@@ -386,18 +487,6 @@ pub const TestContext = struct {
386 ctx.addTransform(name, target, src, result);487 ctx.addTransform(name, target, src, result);
387 }488 }
388489
389 /// Adds a test case that cleans up the ZIR source given in `src`, and
390 /// tests the resulting ZIR against `result`
391 pub fn transformZIR(
392 ctx: *TestContext,
393 name: []const u8,
394 target: CrossTarget,
395 src: [:0]const u8,
396 result: [:0]const u8,
397 ) void {
398 ctx.addTransform(name, target, .ZIR, src, result);
399 }
400
401 pub fn addError(490 pub fn addError(
402 ctx: *TestContext,491 ctx: *TestContext,
403 name: []const u8,492 name: []const u8,
...@@ -555,7 +644,7 @@ pub const TestContext = struct {...@@ -555,7 +644,7 @@ pub const TestContext = struct {
555 continue;644 continue;
556645
557 // Skip tests that require LLVM backend when it is not available646 // Skip tests that require LLVM backend when it is not available
558 if (!build_options.have_llvm and case.llvm_backend)647 if (!build_options.have_llvm and case.backend == .llvm)
559 continue;648 continue;
560649
561 var prg_node = root_node.start(case.name, case.updates.items.len);650 var prg_node = root_node.start(case.name, case.updates.items.len);
...@@ -567,7 +656,7 @@ pub const TestContext = struct {...@@ -567,7 +656,7 @@ pub const TestContext = struct {
567 progress.initial_delay_ns = 0;656 progress.initial_delay_ns = 0;
568 progress.refresh_rate_ns = 0;657 progress.refresh_rate_ns = 0;
569658
570 self.runOneCase(659 runOneCase(
571 std.testing.allocator,660 std.testing.allocator,
572 &prg_node,661 &prg_node,
573 case,662 case,
...@@ -576,17 +665,16 @@ pub const TestContext = struct {...@@ -576,17 +665,16 @@ pub const TestContext = struct {
576 global_cache_directory,665 global_cache_directory,
577 ) catch |err| {666 ) catch |err| {
578 fail_count += 1;667 fail_count += 1;
579 std.debug.print("test '{s}' failed: {s}\n\n", .{ case.name, @errorName(err) });668 print("test '{s}' failed: {s}\n\n", .{ case.name, @errorName(err) });
580 };669 };
581 }670 }
582 if (fail_count != 0) {671 if (fail_count != 0) {
583 std.debug.print("{d} tests failed\n", .{fail_count});672 print("{d} tests failed\n", .{fail_count});
584 return error.TestFailed;673 return error.TestFailed;
585 }674 }
586 }675 }
587676
588 fn runOneCase(677 fn runOneCase(
589 self: *TestContext,
590 allocator: *Allocator,678 allocator: *Allocator,
591 root_node: *std.Progress.Node,679 root_node: *std.Progress.Node,
592 case: Case,680 case: Case,
...@@ -594,7 +682,6 @@ pub const TestContext = struct {...@@ -594,7 +682,6 @@ pub const TestContext = struct {
594 thread_pool: *ThreadPool,682 thread_pool: *ThreadPool,
595 global_cache_directory: Compilation.Directory,683 global_cache_directory: Compilation.Directory,
596 ) !void {684 ) !void {
597 _ = self;
598 const target_info = try std.zig.system.NativeTargetInfo.detect(allocator, case.target);685 const target_info = try std.zig.system.NativeTargetInfo.detect(allocator, case.target);
599 const target = target_info.target;686 const target = target_info.target;
600687
...@@ -607,14 +694,155 @@ pub const TestContext = struct {...@@ -607,14 +694,155 @@ pub const TestContext = struct {
607694
608 var cache_dir = try tmp.dir.makeOpenPath("zig-cache", .{});695 var cache_dir = try tmp.dir.makeOpenPath("zig-cache", .{});
609 defer cache_dir.close();696 defer cache_dir.close();
610 const tmp_dir_path = try std.fs.path.join(arena, &[_][]const u8{ ".", "zig-cache", "tmp", &tmp.sub_path });697
698 const tmp_dir_path = try std.fs.path.join(
699 arena,
700 &[_][]const u8{ ".", "zig-cache", "tmp", &tmp.sub_path },
701 );
702 const tmp_dir_path_plus_slash = try std.fmt.allocPrint(
703 arena,
704 "{s}" ++ std.fs.path.sep_str,
705 .{tmp_dir_path},
706 );
707 const local_cache_path = try std.fs.path.join(
708 arena,
709 &[_][]const u8{ tmp_dir_path, "zig-cache" },
710 );
711
712 for (case.files.items) |file| {
713 try tmp.dir.writeFile(file.path, file.src);
714 }
715
716 if (case.backend == .stage1) {
717 // stage1 backend has limitations:
718 // * leaks memory
719 // * calls exit() when a compile error happens
720 // * cannot handle updates
721 // because of this we must spawn a child process rather than
722 // using Compilation directly.
723 assert(case.updates.items.len == 1);
724 const update = case.updates.items[0];
725 try tmp.dir.writeFile(tmp_src_path, update.src);
726
727 var zig_args = std.ArrayList([]const u8).init(arena);
728 try zig_args.append(std.testing.zig_exe_path);
729
730 if (case.is_test) {
731 try zig_args.append("test");
732 } else switch (case.output_mode) {
733 .Obj => try zig_args.append("build-obj"),
734 .Exe => try zig_args.append("build-exe"),
735 .Lib => try zig_args.append("build-lib"),
736 }
737
738 try zig_args.append(try std.fs.path.join(arena, &.{ tmp_dir_path, tmp_src_path }));
739
740 try zig_args.append("--name");
741 try zig_args.append("test");
742
743 try zig_args.append("--cache-dir");
744 try zig_args.append(local_cache_path);
745
746 try zig_args.append("--global-cache-dir");
747 try zig_args.append(global_cache_directory.path orelse ".");
748
749 if (!case.target.isNative()) {
750 try zig_args.append("-target");
751 try zig_args.append(try target.zigTriple(arena));
752 }
753
754 try zig_args.append("-O");
755 try zig_args.append(@tagName(case.optimize_mode));
756
757 const result = try std.ChildProcess.exec(.{
758 .allocator = arena,
759 .argv = zig_args.items,
760 });
761 switch (update.case) {
762 .Error => |case_error_list| {
763 switch (result.term) {
764 .Exited => |code| {
765 if (code == 0) {
766 dumpArgs(zig_args.items);
767 return error.CompilationIncorrectlySucceeded;
768 }
769 },
770 else => {
771 dumpArgs(zig_args.items);
772 return error.CompilationCrashed;
773 },
774 }
775 var ok = true;
776 if (case.expect_exact) {
777 var err_iter = std.mem.split(result.stderr, "\n");
778 var i: usize = 0;
779 ok = while (err_iter.next()) |line| : (i += 1) {
780 if (i >= case_error_list.len) break false;
781 const expected = try std.mem.replaceOwned(
782 u8,
783 arena,
784 try std.fmt.allocPrint(arena, "{s}", .{case_error_list[i]}),
785 "${DIR}",
786 tmp_dir_path_plus_slash,
787 );
788
789 if (std.mem.indexOf(u8, line, expected) == null) break false;
790 continue;
791 } else true;
792
793 ok = ok and i == case_error_list.len;
794
795 if (!ok) {
796 print("\n======== Expected these compile errors: ========\n", .{});
797 for (case_error_list) |msg| {
798 const expected = try std.fmt.allocPrint(arena, "{s}", .{msg});
799 print("{s}\n", .{expected});
800 }
801 }
802 } else {
803 for (case_error_list) |msg| {
804 const expected = try std.mem.replaceOwned(
805 u8,
806 arena,
807 try std.fmt.allocPrint(arena, "{s}", .{msg}),
808 "${DIR}",
809 tmp_dir_path_plus_slash,
810 );
811 if (std.mem.indexOf(u8, result.stderr, expected) == null) {
812 print(
813 \\
814 \\=========== Expected compile error: ============
815 \\{s}
816 \\
817 , .{expected});
818 ok = false;
819 break;
820 }
821 }
822 }
823
824 if (!ok) {
825 print(
826 \\================= Full output: =================
827 \\{s}
828 \\================================================
829 \\
830 , .{result.stderr});
831 return error.TestFailed;
832 }
833 },
834 .CompareObjectFile => @panic("TODO implement in the test harness"),
835 .Execution => @panic("TODO implement in the test harness"),
836 .Header => @panic("TODO implement in the test harness"),
837 }
838 return;
839 }
840
611 const zig_cache_directory: Compilation.Directory = .{841 const zig_cache_directory: Compilation.Directory = .{
612 .handle = cache_dir,842 .handle = cache_dir,
613 .path = try std.fs.path.join(arena, &[_][]const u8{ tmp_dir_path, "zig-cache" }),843 .path = local_cache_path,
614 };844 };
615845
616 const tmp_src_path = "test_case.zig";
617
618 var root_pkg: Package = .{846 var root_pkg: Package = .{
619 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },847 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
620 .root_src_path = tmp_src_path,848 .root_src_path = tmp_src_path,
...@@ -640,6 +868,14 @@ pub const TestContext = struct {...@@ -640,6 +868,14 @@ pub const TestContext = struct {
640 .directory = emit_directory,868 .directory = emit_directory,
641 .basename = "test_case.h",869 .basename = "test_case.h",
642 } else null;870 } else null;
871 const use_llvm: ?bool = switch (case.backend) {
872 .llvm => true,
873 else => null,
874 };
875 const use_stage1: ?bool = switch (case.backend) {
876 .stage1 => true,
877 else => null,
878 };
643 const comp = try Compilation.create(allocator, .{879 const comp = try Compilation.create(allocator, .{
644 .local_cache_directory = zig_cache_directory,880 .local_cache_directory = zig_cache_directory,
645 .global_cache_directory = global_cache_directory,881 .global_cache_directory = global_cache_directory,
...@@ -651,8 +887,8 @@ pub const TestContext = struct {...@@ -651,8 +887,8 @@ pub const TestContext = struct {
651 // and linking. This will require a rework to support multi-file887 // and linking. This will require a rework to support multi-file
652 // tests.888 // tests.
653 .output_mode = case.output_mode,889 .output_mode = case.output_mode,
654 // TODO: support testing optimizations890 .is_test = case.is_test,
655 .optimize_mode = .Debug,891 .optimize_mode = case.optimize_mode,
656 .emit_bin = emit_bin,892 .emit_bin = emit_bin,
657 .emit_h = emit_h,893 .emit_h = emit_h,
658 .root_pkg = &root_pkg,894 .root_pkg = &root_pkg,
...@@ -661,17 +897,13 @@ pub const TestContext = struct {...@@ -661,17 +897,13 @@ pub const TestContext = struct {
661 .is_native_os = case.target.isNativeOs(),897 .is_native_os = case.target.isNativeOs(),
662 .is_native_abi = case.target.isNativeAbi(),898 .is_native_abi = case.target.isNativeAbi(),
663 .dynamic_linker = target_info.dynamic_linker.get(),899 .dynamic_linker = target_info.dynamic_linker.get(),
664 .link_libc = case.llvm_backend,900 .link_libc = case.backend == .llvm,
665 .use_llvm = case.llvm_backend,901 .use_llvm = use_llvm,
666 .use_lld = case.llvm_backend,902 .use_stage1 = use_stage1,
667 .self_exe_path = std.testing.zig_exe_path,903 .self_exe_path = std.testing.zig_exe_path,
668 });904 });
669 defer comp.destroy();905 defer comp.destroy();
670906
671 for (case.files.items) |file| {
672 try tmp.dir.writeFile(file.path, file.src);
673 }
674
675 for (case.updates.items) |update, update_index| {907 for (case.updates.items) |update, update_index| {
676 var update_node = root_node.start("update", 3);908 var update_node = root_node.start("update", 3);
677 update_node.activate();909 update_node.activate();
...@@ -692,19 +924,19 @@ pub const TestContext = struct {...@@ -692,19 +924,19 @@ pub const TestContext = struct {
692 var all_errors = try comp.getAllErrorsAlloc();924 var all_errors = try comp.getAllErrorsAlloc();
693 defer all_errors.deinit(allocator);925 defer all_errors.deinit(allocator);
694 if (all_errors.list.len != 0) {926 if (all_errors.list.len != 0) {
695 std.debug.print(927 print(
696 "\nCase '{s}': unexpected errors at update_index={d}:\n{s}\n",928 "\nCase '{s}': unexpected errors at update_index={d}:\n{s}\n",
697 .{ case.name, update_index, hr },929 .{ case.name, update_index, hr },
698 );930 );
699 for (all_errors.list) |err_msg| {931 for (all_errors.list) |err_msg| {
700 switch (err_msg) {932 switch (err_msg) {
701 .src => |src| {933 .src => |src| {
702 std.debug.print("{s}:{d}:{d}: error: {s}\n{s}\n", .{934 print("{s}:{d}:{d}: error: {s}\n{s}\n", .{
703 src.src_path, src.line + 1, src.column + 1, src.msg, hr,935 src.src_path, src.line + 1, src.column + 1, src.msg, hr,
704 });936 });
705 },937 },
706 .plain => |plain| {938 .plain => |plain| {
707 std.debug.print("error: {s}\n{s}\n", .{ plain.msg, hr });939 print("error: {s}\n{s}\n", .{ plain.msg, hr });
708 },940 },
709 }941 }
710 }942 }
...@@ -757,10 +989,20 @@ pub const TestContext = struct {...@@ -757,10 +989,20 @@ pub const TestContext = struct {
757 const src_path_ok = case_msg.src.src_path.len == 0 or989 const src_path_ok = case_msg.src.src_path.len == 0 or
758 std.mem.eql(u8, case_msg.src.src_path, actual_msg.src_path);990 std.mem.eql(u8, case_msg.src.src_path, actual_msg.src_path);
759991
992 const expected_msg = try std.mem.replaceOwned(
993 u8,
994 arena,
995 case_msg.src.msg,
996 "${DIR}",
997 tmp_dir_path_plus_slash,
998 );
999
760 if (src_path_ok and1000 if (src_path_ok and
761 actual_msg.line == case_msg.src.line and1001 (case_msg.src.line == std.math.maxInt(u32) or
762 actual_msg.column == case_msg.src.column and1002 actual_msg.line == case_msg.src.line) and
763 std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and1003 (case_msg.src.column == std.math.maxInt(u32) or
1004 actual_msg.column == case_msg.src.column) and
1005 std.mem.eql(u8, expected_msg, actual_msg.msg) and
764 case_msg.src.kind == .@"error")1006 case_msg.src.kind == .@"error")
765 {1007 {
766 handled_errors[i] = true;1008 handled_errors[i] = true;
...@@ -779,7 +1021,7 @@ pub const TestContext = struct {...@@ -779,7 +1021,7 @@ pub const TestContext = struct {
779 },1021 },
780 }1022 }
781 } else {1023 } else {
782 std.debug.print(1024 print(
783 "\nUnexpected error:\n{s}\n{}\n{s}",1025 "\nUnexpected error:\n{s}\n{}\n{s}",
784 .{ hr, ErrorMsg.init(actual_error, .@"error"), hr },1026 .{ hr, ErrorMsg.init(actual_error, .@"error"), hr },
785 );1027 );
...@@ -796,9 +1038,19 @@ pub const TestContext = struct {...@@ -796,9 +1038,19 @@ pub const TestContext = struct {
796 }1038 }
797 if (ex_tag != .src) continue;1039 if (ex_tag != .src) continue;
7981040
799 if (actual_msg.line == case_msg.src.line and1041 const expected_msg = try std.mem.replaceOwned(
800 actual_msg.column == case_msg.src.column and1042 u8,
801 std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and1043 arena,
1044 case_msg.src.msg,
1045 "${DIR}",
1046 tmp_dir_path_plus_slash,
1047 );
1048
1049 if ((case_msg.src.line == std.math.maxInt(u32) or
1050 actual_msg.line == case_msg.src.line) and
1051 (case_msg.src.column == std.math.maxInt(u32) or
1052 actual_msg.column == case_msg.src.column) and
1053 std.mem.eql(u8, expected_msg, actual_msg.msg) and
802 case_msg.src.kind == .note)1054 case_msg.src.kind == .note)
803 {1055 {
804 handled_errors[i] = true;1056 handled_errors[i] = true;
...@@ -817,7 +1069,7 @@ pub const TestContext = struct {...@@ -817,7 +1069,7 @@ pub const TestContext = struct {
817 },1069 },
818 }1070 }
819 } else {1071 } else {
820 std.debug.print(1072 print(
821 "\nUnexpected note:\n{s}\n{}\n{s}",1073 "\nUnexpected note:\n{s}\n{}\n{s}",
822 .{ hr, ErrorMsg.init(note.*, .note), hr },1074 .{ hr, ErrorMsg.init(note.*, .note), hr },
823 );1075 );
...@@ -827,7 +1079,7 @@ pub const TestContext = struct {...@@ -827,7 +1079,7 @@ pub const TestContext = struct {
8271079
828 for (handled_errors) |handled, i| {1080 for (handled_errors) |handled, i| {
829 if (!handled) {1081 if (!handled) {
830 std.debug.print(1082 print(
831 "\nExpected error not found:\n{s}\n{}\n{s}",1083 "\nExpected error not found:\n{s}\n{}\n{s}",
832 .{ hr, case_error_list[i], hr },1084 .{ hr, case_error_list[i], hr },
833 );1085 );
...@@ -836,7 +1088,7 @@ pub const TestContext = struct {...@@ -836,7 +1088,7 @@ pub const TestContext = struct {
836 }1088 }
8371089
838 if (any_failed) {1090 if (any_failed) {
839 std.debug.print("\nupdate_index={d} ", .{update_index});1091 print("\nupdate_index={d} ", .{update_index});
840 return error.WrongCompileErrors;1092 return error.WrongCompileErrors;
841 }1093 }
842 },1094 },
...@@ -932,7 +1184,7 @@ pub const TestContext = struct {...@@ -932,7 +1184,7 @@ pub const TestContext = struct {
932 .cwd_dir = tmp.dir,1184 .cwd_dir = tmp.dir,
933 .cwd = tmp_dir_path,1185 .cwd = tmp_dir_path,
934 }) catch |err| {1186 }) catch |err| {
935 std.debug.print("\nupdate_index={d} The following command failed with {s}:\n", .{1187 print("\nupdate_index={d} The following command failed with {s}:\n", .{
936 update_index, @errorName(err),1188 update_index, @errorName(err),
937 });1189 });
938 dumpArgs(argv.items);1190 dumpArgs(argv.items);
...@@ -947,7 +1199,7 @@ pub const TestContext = struct {...@@ -947,7 +1199,7 @@ pub const TestContext = struct {
947 switch (exec_result.term) {1199 switch (exec_result.term) {
948 .Exited => |code| {1200 .Exited => |code| {
949 if (code != 0) {1201 if (code != 0) {
950 std.debug.print("\n{s}\n{s}: execution exited with code {d}:\n", .{1202 print("\n{s}\n{s}: execution exited with code {d}:\n", .{
951 exec_result.stderr, case.name, code,1203 exec_result.stderr, case.name, code,
952 });1204 });
953 dumpArgs(argv.items);1205 dumpArgs(argv.items);
...@@ -955,7 +1207,7 @@ pub const TestContext = struct {...@@ -955,7 +1207,7 @@ pub const TestContext = struct {
955 }1207 }
956 },1208 },
957 else => {1209 else => {
958 std.debug.print("\n{s}\n{s}: execution crashed:\n", .{1210 print("\n{s}\n{s}: execution crashed:\n", .{
959 exec_result.stderr, case.name,1211 exec_result.stderr, case.name,
960 });1212 });
961 dumpArgs(argv.items);1213 dumpArgs(argv.items);
...@@ -974,7 +1226,9 @@ pub const TestContext = struct {...@@ -974,7 +1226,9 @@ pub const TestContext = struct {
9741226
975fn dumpArgs(argv: []const []const u8) void {1227fn dumpArgs(argv: []const []const u8) void {
976 for (argv) |arg| {1228 for (argv) |arg| {
977 std.debug.print("{s} ", .{arg});1229 print("{s} ", .{arg});
978 }1230 }
979 std.debug.print("\n", .{});1231 print("\n", .{});
980}1232}
1233
1234const tmp_src_path = "tmp.zig";
src/translate_c/ast.zig+1-1
...@@ -754,7 +754,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {...@@ -754,7 +754,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
754 });754 });
755755
756 return std.zig.ast.Tree{756 return std.zig.ast.Tree{
757 .source = ctx.buf.toOwnedSlice(),757 .source = try ctx.buf.toOwnedSliceSentinel(0),
758 .tokens = ctx.tokens.toOwnedSlice(),758 .tokens = ctx.tokens.toOwnedSlice(),
759 .nodes = ctx.nodes.toOwnedSlice(),759 .nodes = ctx.nodes.toOwnedSlice(),
760 .extra_data = ctx.extra_data.toOwnedSlice(gpa),760 .extra_data = ctx.extra_data.toOwnedSlice(gpa),
test/cases.zig created+1627
...@@ -0,0 +1,1627 @@
1const std = @import("std");
2const TestContext = @import("../src/test.zig").TestContext;
3
4// Self-hosted has differing levels of support for various architectures. For now we pass explicit
5// target parameters to each test case. At some point we will take this to the next level and have
6// a set of targets that all test cases run on unless specifically overridden. For now, each test
7// case applies to only the specified target.
8
9const linux_x64 = std.zig.CrossTarget{
10 .cpu_arch = .x86_64,
11 .os_tag = .linux,
12};
13
14pub fn addCases(ctx: *TestContext) !void {
15 try @import("compile_errors.zig").addCases(ctx);
16 try @import("stage2/cbe.zig").addCases(ctx);
17 try @import("stage2/arm.zig").addCases(ctx);
18 try @import("stage2/aarch64.zig").addCases(ctx);
19 try @import("stage2/llvm.zig").addCases(ctx);
20 try @import("stage2/wasm.zig").addCases(ctx);
21 try @import("stage2/darwin.zig").addCases(ctx);
22 try @import("stage2/riscv64.zig").addCases(ctx);
23
24 {
25 var case = ctx.exe("hello world with updates", linux_x64);
26
27 case.addError("", &[_][]const u8{
28 ":93:9: error: struct 'tmp.tmp' has no member named 'main'",
29 });
30
31 // Incorrect return type
32 case.addError(
33 \\pub export fn _start() noreturn {
34 \\}
35 , &[_][]const u8{":2:1: error: expected noreturn, found void"});
36
37 // Regular old hello world
38 case.addCompareOutput(
39 \\pub export fn _start() noreturn {
40 \\ print();
41 \\
42 \\ exit();
43 \\}
44 \\
45 \\fn print() void {
46 \\ asm volatile ("syscall"
47 \\ :
48 \\ : [number] "{rax}" (1),
49 \\ [arg1] "{rdi}" (1),
50 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
51 \\ [arg3] "{rdx}" (14)
52 \\ : "rcx", "r11", "memory"
53 \\ );
54 \\ return;
55 \\}
56 \\
57 \\fn exit() noreturn {
58 \\ asm volatile ("syscall"
59 \\ :
60 \\ : [number] "{rax}" (231),
61 \\ [arg1] "{rdi}" (0)
62 \\ : "rcx", "r11", "memory"
63 \\ );
64 \\ unreachable;
65 \\}
66 ,
67 "Hello, World!\n",
68 );
69
70 // Convert to pub fn main
71 case.addCompareOutput(
72 \\pub fn main() void {
73 \\ print();
74 \\}
75 \\
76 \\fn print() void {
77 \\ asm volatile ("syscall"
78 \\ :
79 \\ : [number] "{rax}" (1),
80 \\ [arg1] "{rdi}" (1),
81 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
82 \\ [arg3] "{rdx}" (14)
83 \\ : "rcx", "r11", "memory"
84 \\ );
85 \\ return;
86 \\}
87 ,
88 "Hello, World!\n",
89 );
90
91 // Now change the message only
92 case.addCompareOutput(
93 \\pub fn main() void {
94 \\ print();
95 \\}
96 \\
97 \\fn print() void {
98 \\ asm volatile ("syscall"
99 \\ :
100 \\ : [number] "{rax}" (1),
101 \\ [arg1] "{rdi}" (1),
102 \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")),
103 \\ [arg3] "{rdx}" (104)
104 \\ : "rcx", "r11", "memory"
105 \\ );
106 \\ return;
107 \\}
108 ,
109 "What is up? This is a longer message that will force the data to be relocated in virtual address space.\n",
110 );
111 // Now we print it twice.
112 case.addCompareOutput(
113 \\pub fn main() void {
114 \\ print();
115 \\ print();
116 \\}
117 \\
118 \\fn print() void {
119 \\ asm volatile ("syscall"
120 \\ :
121 \\ : [number] "{rax}" (1),
122 \\ [arg1] "{rdi}" (1),
123 \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")),
124 \\ [arg3] "{rdx}" (104)
125 \\ : "rcx", "r11", "memory"
126 \\ );
127 \\ return;
128 \\}
129 ,
130 \\What is up? This is a longer message that will force the data to be relocated in virtual address space.
131 \\What is up? This is a longer message that will force the data to be relocated in virtual address space.
132 \\
133 );
134 }
135
136 {
137 var case = ctx.exe("adding numbers at comptime", linux_x64);
138 case.addCompareOutput(
139 \\pub export fn _start() noreturn {
140 \\ asm volatile ("syscall"
141 \\ :
142 \\ : [number] "{rax}" (1),
143 \\ [arg1] "{rdi}" (1),
144 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
145 \\ [arg3] "{rdx}" (10 + 4)
146 \\ : "rcx", "r11", "memory"
147 \\ );
148 \\ asm volatile ("syscall"
149 \\ :
150 \\ : [number] "{rax}" (@as(usize, 230) + @as(usize, 1)),
151 \\ [arg1] "{rdi}" (0)
152 \\ : "rcx", "r11", "memory"
153 \\ );
154 \\ unreachable;
155 \\}
156 ,
157 "Hello, World!\n",
158 );
159 }
160
161 {
162 var case = ctx.exe("adding numbers at runtime and comptime", linux_x64);
163 case.addCompareOutput(
164 \\pub export fn _start() noreturn {
165 \\ add(3, 4);
166 \\
167 \\ exit();
168 \\}
169 \\
170 \\fn add(a: u32, b: u32) void {
171 \\ if (a + b != 7) unreachable;
172 \\}
173 \\
174 \\fn exit() noreturn {
175 \\ asm volatile ("syscall"
176 \\ :
177 \\ : [number] "{rax}" (231),
178 \\ [arg1] "{rdi}" (0)
179 \\ : "rcx", "r11", "memory"
180 \\ );
181 \\ unreachable;
182 \\}
183 ,
184 "",
185 );
186 // comptime function call
187 case.addCompareOutput(
188 \\pub export fn _start() noreturn {
189 \\ exit();
190 \\}
191 \\
192 \\fn add(a: u32, b: u32) u32 {
193 \\ return a + b;
194 \\}
195 \\
196 \\const x = add(3, 4);
197 \\
198 \\fn exit() noreturn {
199 \\ asm volatile ("syscall"
200 \\ :
201 \\ : [number] "{rax}" (231),
202 \\ [arg1] "{rdi}" (x - 7)
203 \\ : "rcx", "r11", "memory"
204 \\ );
205 \\ unreachable;
206 \\}
207 ,
208 "",
209 );
210 // Inline function call
211 case.addCompareOutput(
212 \\pub export fn _start() noreturn {
213 \\ var x: usize = 3;
214 \\ const y = add(1, 2, x);
215 \\ exit(y - 6);
216 \\}
217 \\
218 \\fn add(a: usize, b: usize, c: usize) callconv(.Inline) usize {
219 \\ return a + b + c;
220 \\}
221 \\
222 \\fn exit(code: usize) noreturn {
223 \\ asm volatile ("syscall"
224 \\ :
225 \\ : [number] "{rax}" (231),
226 \\ [arg1] "{rdi}" (code)
227 \\ : "rcx", "r11", "memory"
228 \\ );
229 \\ unreachable;
230 \\}
231 ,
232 "",
233 );
234 }
235
236 {
237 var case = ctx.exe("subtracting numbers at runtime", linux_x64);
238 case.addCompareOutput(
239 \\pub fn main() void {
240 \\ sub(7, 4);
241 \\}
242 \\
243 \\fn sub(a: u32, b: u32) void {
244 \\ if (a - b != 3) unreachable;
245 \\}
246 ,
247 "",
248 );
249 }
250 {
251 var case = ctx.exe("unused vars", linux_x64);
252 case.addError(
253 \\pub fn main() void {
254 \\ const x = 1;
255 \\}
256 , &.{":2:11: error: unused local constant"});
257 }
258 {
259 var case = ctx.exe("@TypeOf", linux_x64);
260 case.addCompareOutput(
261 \\pub fn main() void {
262 \\ var x: usize = 0;
263 \\ _ = x;
264 \\ const z = @TypeOf(x, @as(u128, 5));
265 \\ assert(z == u128);
266 \\}
267 \\
268 \\pub fn assert(ok: bool) void {
269 \\ if (!ok) unreachable; // assertion failure
270 \\}
271 ,
272 "",
273 );
274 case.addCompareOutput(
275 \\pub fn main() void {
276 \\ const z = @TypeOf(true);
277 \\ assert(z == bool);
278 \\}
279 \\
280 \\pub fn assert(ok: bool) void {
281 \\ if (!ok) unreachable; // assertion failure
282 \\}
283 ,
284 "",
285 );
286 case.addError(
287 \\pub fn main() void {
288 \\ _ = @TypeOf(true, 1);
289 \\}
290 , &[_][]const u8{":2:9: error: incompatible types: 'bool' and 'comptime_int'"});
291 }
292
293 {
294 var case = ctx.exe("multiplying numbers at runtime and comptime", linux_x64);
295 case.addCompareOutput(
296 \\pub export fn _start() noreturn {
297 \\ mul(3, 4);
298 \\
299 \\ exit();
300 \\}
301 \\
302 \\fn mul(a: u32, b: u32) void {
303 \\ if (a * b != 12) unreachable;
304 \\}
305 \\
306 \\fn exit() noreturn {
307 \\ asm volatile ("syscall"
308 \\ :
309 \\ : [number] "{rax}" (231),
310 \\ [arg1] "{rdi}" (0)
311 \\ : "rcx", "r11", "memory"
312 \\ );
313 \\ unreachable;
314 \\}
315 ,
316 "",
317 );
318 // comptime function call
319 case.addCompareOutput(
320 \\pub fn _start() noreturn {
321 \\ exit();
322 \\}
323 \\
324 \\fn mul(a: u32, b: u32) u32 {
325 \\ return a * b;
326 \\}
327 \\
328 \\const x = mul(3, 4);
329 \\
330 \\fn exit() noreturn {
331 \\ asm volatile ("syscall"
332 \\ :
333 \\ : [number] "{rax}" (231),
334 \\ [arg1] "{rdi}" (x - 12)
335 \\ : "rcx", "r11", "memory"
336 \\ );
337 \\ unreachable;
338 \\}
339 ,
340 "",
341 );
342 // Inline function call
343 case.addCompareOutput(
344 \\pub export fn _start() noreturn {
345 \\ var x: usize = 5;
346 \\ const y = mul(2, 3, x);
347 \\ exit(y - 30);
348 \\}
349 \\
350 \\fn mul(a: usize, b: usize, c: usize) callconv(.Inline) usize {
351 \\ return a * b * c;
352 \\}
353 \\
354 \\fn exit(code: usize) noreturn {
355 \\ asm volatile ("syscall"
356 \\ :
357 \\ : [number] "{rax}" (231),
358 \\ [arg1] "{rdi}" (code)
359 \\ : "rcx", "r11", "memory"
360 \\ );
361 \\ unreachable;
362 \\}
363 ,
364 "",
365 );
366 }
367
368 {
369 var case = ctx.exe("assert function", linux_x64);
370 case.addCompareOutput(
371 \\pub fn main() void {
372 \\ add(3, 4);
373 \\}
374 \\
375 \\fn add(a: u32, b: u32) void {
376 \\ assert(a + b == 7);
377 \\}
378 \\
379 \\pub fn assert(ok: bool) void {
380 \\ if (!ok) unreachable; // assertion failure
381 \\}
382 \\
383 \\fn exit() noreturn {
384 \\ asm volatile ("syscall"
385 \\ :
386 \\ : [number] "{rax}" (231),
387 \\ [arg1] "{rdi}" (0)
388 \\ : "rcx", "r11", "memory"
389 \\ );
390 \\ unreachable;
391 \\}
392 ,
393 "",
394 );
395
396 // Tests copying a register. For the `c = a + b`, it has to
397 // preserve both a and b, because they are both used later.
398 case.addCompareOutput(
399 \\pub fn main() void {
400 \\ add(3, 4);
401 \\}
402 \\
403 \\fn add(a: u32, b: u32) void {
404 \\ const c = a + b; // 7
405 \\ const d = a + c; // 10
406 \\ const e = d + b; // 14
407 \\ assert(e == 14);
408 \\}
409 \\
410 \\pub fn assert(ok: bool) void {
411 \\ if (!ok) unreachable; // assertion failure
412 \\}
413 ,
414 "",
415 );
416
417 // More stress on the liveness detection.
418 case.addCompareOutput(
419 \\pub fn main() void {
420 \\ add(3, 4);
421 \\}
422 \\
423 \\fn add(a: u32, b: u32) void {
424 \\ const c = a + b; // 7
425 \\ const d = a + c; // 10
426 \\ const e = d + b; // 14
427 \\ const f = d + e; // 24
428 \\ const g = e + f; // 38
429 \\ const h = f + g; // 62
430 \\ const i = g + h; // 100
431 \\ assert(i == 100);
432 \\}
433 \\
434 \\pub fn assert(ok: bool) void {
435 \\ if (!ok) unreachable; // assertion failure
436 \\}
437 ,
438 "",
439 );
440
441 // Requires a second move. The register allocator should figure out to re-use rax.
442 case.addCompareOutput(
443 \\pub fn main() void {
444 \\ add(3, 4);
445 \\}
446 \\
447 \\fn add(a: u32, b: u32) void {
448 \\ const c = a + b; // 7
449 \\ const d = a + c; // 10
450 \\ const e = d + b; // 14
451 \\ const f = d + e; // 24
452 \\ const g = e + f; // 38
453 \\ const h = f + g; // 62
454 \\ const i = g + h; // 100
455 \\ const j = i + d; // 110
456 \\ assert(j == 110);
457 \\}
458 \\
459 \\pub fn assert(ok: bool) void {
460 \\ if (!ok) unreachable; // assertion failure
461 \\}
462 ,
463 "",
464 );
465
466 // Now we test integer return values.
467 case.addCompareOutput(
468 \\pub fn main() void {
469 \\ assert(add(3, 4) == 7);
470 \\ assert(add(20, 10) == 30);
471 \\}
472 \\
473 \\fn add(a: u32, b: u32) u32 {
474 \\ return a + b;
475 \\}
476 \\
477 \\pub fn assert(ok: bool) void {
478 \\ if (!ok) unreachable; // assertion failure
479 \\}
480 ,
481 "",
482 );
483
484 // Local mutable variables.
485 case.addCompareOutput(
486 \\pub fn main() void {
487 \\ assert(add(3, 4) == 7);
488 \\ assert(add(20, 10) == 30);
489 \\}
490 \\
491 \\fn add(a: u32, b: u32) u32 {
492 \\ var x: u32 = undefined;
493 \\ x = 0;
494 \\ x += a;
495 \\ x += b;
496 \\ return x;
497 \\}
498 \\
499 \\pub fn assert(ok: bool) void {
500 \\ if (!ok) unreachable; // assertion failure
501 \\}
502 ,
503 "",
504 );
505
506 // Optionals
507 case.addCompareOutput(
508 \\pub fn main() void {
509 \\ const a: u32 = 2;
510 \\ const b: ?u32 = a;
511 \\ const c = b.?;
512 \\ if (c != 2) unreachable;
513 \\}
514 ,
515 "",
516 );
517
518 // While loops
519 case.addCompareOutput(
520 \\pub fn main() void {
521 \\ var i: u32 = 0;
522 \\ while (i < 4) : (i += 1) print();
523 \\ assert(i == 4);
524 \\}
525 \\
526 \\fn print() void {
527 \\ asm volatile ("syscall"
528 \\ :
529 \\ : [number] "{rax}" (1),
530 \\ [arg1] "{rdi}" (1),
531 \\ [arg2] "{rsi}" (@ptrToInt("hello\n")),
532 \\ [arg3] "{rdx}" (6)
533 \\ : "rcx", "r11", "memory"
534 \\ );
535 \\ return;
536 \\}
537 \\
538 \\pub fn assert(ok: bool) void {
539 \\ if (!ok) unreachable; // assertion failure
540 \\}
541 ,
542 "hello\nhello\nhello\nhello\n",
543 );
544
545 // inline while requires the condition to be comptime known.
546 case.addError(
547 \\pub fn main() void {
548 \\ var i: u32 = 0;
549 \\ inline while (i < 4) : (i += 1) print();
550 \\ assert(i == 4);
551 \\}
552 \\
553 \\fn print() void {
554 \\ asm volatile ("syscall"
555 \\ :
556 \\ : [number] "{rax}" (1),
557 \\ [arg1] "{rdi}" (1),
558 \\ [arg2] "{rsi}" (@ptrToInt("hello\n")),
559 \\ [arg3] "{rdx}" (6)
560 \\ : "rcx", "r11", "memory"
561 \\ );
562 \\ return;
563 \\}
564 \\
565 \\pub fn assert(ok: bool) void {
566 \\ if (!ok) unreachable; // assertion failure
567 \\}
568 , &[_][]const u8{":3:21: error: unable to resolve comptime value"});
569
570 // Labeled blocks (no conditional branch)
571 case.addCompareOutput(
572 \\pub fn main() void {
573 \\ assert(add(3, 4) == 20);
574 \\}
575 \\
576 \\fn add(a: u32, b: u32) u32 {
577 \\ const x: u32 = blk: {
578 \\ const c = a + b; // 7
579 \\ const d = a + c; // 10
580 \\ const e = d + b; // 14
581 \\ break :blk e;
582 \\ };
583 \\ const y = x + a; // 17
584 \\ const z = y + a; // 20
585 \\ return z;
586 \\}
587 \\
588 \\pub fn assert(ok: bool) void {
589 \\ if (!ok) unreachable; // assertion failure
590 \\}
591 ,
592 "",
593 );
594
595 // This catches a possible bug in the logic for re-using dying operands.
596 case.addCompareOutput(
597 \\pub fn main() void {
598 \\ assert(add(3, 4) == 116);
599 \\}
600 \\
601 \\fn add(a: u32, b: u32) u32 {
602 \\ const x: u32 = blk: {
603 \\ const c = a + b; // 7
604 \\ const d = a + c; // 10
605 \\ const e = d + b; // 14
606 \\ const f = d + e; // 24
607 \\ const g = e + f; // 38
608 \\ const h = f + g; // 62
609 \\ const i = g + h; // 100
610 \\ const j = i + d; // 110
611 \\ break :blk j;
612 \\ };
613 \\ const y = x + a; // 113
614 \\ const z = y + a; // 116
615 \\ return z;
616 \\}
617 \\
618 \\pub fn assert(ok: bool) void {
619 \\ if (!ok) unreachable; // assertion failure
620 \\}
621 ,
622 "",
623 );
624
625 // Spilling registers to the stack.
626 case.addCompareOutput(
627 \\pub fn main() void {
628 \\ assert(add(3, 4) == 1221);
629 \\ assert(mul(3, 4) == 21609);
630 \\}
631 \\
632 \\fn add(a: u32, b: u32) u32 {
633 \\ const x: u32 = blk: {
634 \\ const c = a + b; // 7
635 \\ const d = a + c; // 10
636 \\ const e = d + b; // 14
637 \\ const f = d + e; // 24
638 \\ const g = e + f; // 38
639 \\ const h = f + g; // 62
640 \\ const i = g + h; // 100
641 \\ const j = i + d; // 110
642 \\ const k = i + j; // 210
643 \\ const l = j + k; // 320
644 \\ const m = l + c; // 327
645 \\ const n = m + d; // 337
646 \\ const o = n + e; // 351
647 \\ const p = o + f; // 375
648 \\ const q = p + g; // 413
649 \\ const r = q + h; // 475
650 \\ const s = r + i; // 575
651 \\ const t = s + j; // 685
652 \\ const u = t + k; // 895
653 \\ const v = u + l; // 1215
654 \\ break :blk v;
655 \\ };
656 \\ const y = x + a; // 1218
657 \\ const z = y + a; // 1221
658 \\ return z;
659 \\}
660 \\
661 \\fn mul(a: u32, b: u32) u32 {
662 \\ const x: u32 = blk: {
663 \\ const c = a * a * a * a; // 81
664 \\ const d = a * a * a * b; // 108
665 \\ const e = a * a * b * a; // 108
666 \\ const f = a * a * b * b; // 144
667 \\ const g = a * b * a * a; // 108
668 \\ const h = a * b * a * b; // 144
669 \\ const i = a * b * b * a; // 144
670 \\ const j = a * b * b * b; // 192
671 \\ const k = b * a * a * a; // 108
672 \\ const l = b * a * a * b; // 144
673 \\ const m = b * a * b * a; // 144
674 \\ const n = b * a * b * b; // 192
675 \\ const o = b * b * a * a; // 144
676 \\ const p = b * b * a * b; // 192
677 \\ const q = b * b * b * a; // 192
678 \\ const r = b * b * b * b; // 256
679 \\ const s = c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r; // 2401
680 \\ break :blk s;
681 \\ };
682 \\ const y = x * a; // 7203
683 \\ const z = y * a; // 21609
684 \\ return z;
685 \\}
686 \\
687 \\pub fn assert(ok: bool) void {
688 \\ if (!ok) unreachable; // assertion failure
689 \\}
690 ,
691 "",
692 );
693
694 // Reusing the registers of dead operands playing nicely with conditional branching.
695 case.addCompareOutput(
696 \\pub fn main() void {
697 \\ assert(add(3, 4) == 791);
698 \\ assert(add(4, 3) == 79);
699 \\}
700 \\
701 \\fn add(a: u32, b: u32) u32 {
702 \\ const x: u32 = if (a < b) blk: {
703 \\ const c = a + b; // 7
704 \\ const d = a + c; // 10
705 \\ const e = d + b; // 14
706 \\ const f = d + e; // 24
707 \\ const g = e + f; // 38
708 \\ const h = f + g; // 62
709 \\ const i = g + h; // 100
710 \\ const j = i + d; // 110
711 \\ const k = i + j; // 210
712 \\ const l = k + c; // 217
713 \\ const m = l + d; // 227
714 \\ const n = m + e; // 241
715 \\ const o = n + f; // 265
716 \\ const p = o + g; // 303
717 \\ const q = p + h; // 365
718 \\ const r = q + i; // 465
719 \\ const s = r + j; // 575
720 \\ const t = s + k; // 785
721 \\ break :blk t;
722 \\ } else blk: {
723 \\ const t = b + b + a; // 10
724 \\ const c = a + t; // 14
725 \\ const d = c + t; // 24
726 \\ const e = d + t; // 34
727 \\ const f = e + t; // 44
728 \\ const g = f + t; // 54
729 \\ const h = c + g; // 68
730 \\ break :blk h + b; // 71
731 \\ };
732 \\ const y = x + a; // 788, 75
733 \\ const z = y + a; // 791, 79
734 \\ return z;
735 \\}
736 \\
737 \\pub fn assert(ok: bool) void {
738 \\ if (!ok) unreachable; // assertion failure
739 \\}
740 ,
741 "",
742 );
743
744 // Character literals and multiline strings.
745 case.addCompareOutput(
746 \\pub fn main() void {
747 \\ const ignore =
748 \\ \\ cool thx
749 \\ \\
750 \\ ;
751 \\ _ = ignore;
752 \\ add('ぁ', '\x03');
753 \\}
754 \\
755 \\fn add(a: u32, b: u32) void {
756 \\ assert(a + b == 12356);
757 \\}
758 \\
759 \\pub fn assert(ok: bool) void {
760 \\ if (!ok) unreachable; // assertion failure
761 \\}
762 ,
763 "",
764 );
765
766 // Global const.
767 case.addCompareOutput(
768 \\pub fn main() void {
769 \\ add(aa, bb);
770 \\}
771 \\
772 \\const aa = 'ぁ';
773 \\const bb = '\x03';
774 \\
775 \\fn add(a: u32, b: u32) void {
776 \\ assert(a + b == 12356);
777 \\}
778 \\
779 \\pub fn assert(ok: bool) void {
780 \\ if (!ok) unreachable; // assertion failure
781 \\}
782 ,
783 "",
784 );
785
786 // Array access.
787 case.addCompareOutput(
788 \\pub fn main() void {
789 \\ assert("hello"[0] == 'h');
790 \\}
791 \\
792 \\pub fn assert(ok: bool) void {
793 \\ if (!ok) unreachable; // assertion failure
794 \\}
795 ,
796 "",
797 );
798
799 // Array access to a global array.
800 case.addCompareOutput(
801 \\const hello = "hello".*;
802 \\pub fn main() void {
803 \\ assert(hello[1] == 'e');
804 \\}
805 \\
806 \\pub fn assert(ok: bool) void {
807 \\ if (!ok) unreachable; // assertion failure
808 \\}
809 ,
810 "",
811 );
812
813 // 64bit set stack
814 case.addCompareOutput(
815 \\pub fn main() void {
816 \\ var i: u64 = 0xFFEEDDCCBBAA9988;
817 \\ assert(i == 0xFFEEDDCCBBAA9988);
818 \\}
819 \\
820 \\pub fn assert(ok: bool) void {
821 \\ if (!ok) unreachable; // assertion failure
822 \\}
823 ,
824 "",
825 );
826
827 // Basic for loop
828 case.addCompareOutput(
829 \\pub fn main() void {
830 \\ for ("hello") |_| print();
831 \\}
832 \\
833 \\fn print() void {
834 \\ asm volatile ("syscall"
835 \\ :
836 \\ : [number] "{rax}" (1),
837 \\ [arg1] "{rdi}" (1),
838 \\ [arg2] "{rsi}" (@ptrToInt("hello\n")),
839 \\ [arg3] "{rdx}" (6)
840 \\ : "rcx", "r11", "memory"
841 \\ );
842 \\ return;
843 \\}
844 ,
845 "hello\nhello\nhello\nhello\nhello\n",
846 );
847 }
848
849 {
850 var case = ctx.exe("basic import", linux_x64);
851 case.addCompareOutput(
852 \\pub fn main() void {
853 \\ @import("print.zig").print();
854 \\}
855 ,
856 "Hello, World!\n",
857 );
858 try case.files.append(.{
859 .src =
860 \\pub fn print() void {
861 \\ asm volatile ("syscall"
862 \\ :
863 \\ : [number] "{rax}" (@as(usize, 1)),
864 \\ [arg1] "{rdi}" (@as(usize, 1)),
865 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
866 \\ [arg3] "{rdx}" (@as(usize, 14))
867 \\ : "rcx", "r11", "memory"
868 \\ );
869 \\ return;
870 \\}
871 ,
872 .path = "print.zig",
873 });
874 }
875 {
876 var case = ctx.exe("redundant comptime", linux_x64);
877 case.addError(
878 \\pub fn main() void {
879 \\ var a: comptime u32 = 0;
880 \\}
881 ,
882 &.{":2:12: error: redundant comptime keyword in already comptime scope"},
883 );
884 case.addError(
885 \\pub fn main() void {
886 \\ comptime {
887 \\ var a: u32 = comptime 0;
888 \\ }
889 \\}
890 ,
891 &.{":3:22: error: redundant comptime keyword in already comptime scope"},
892 );
893 }
894 {
895 var case = ctx.exe("try in comptime in struct in test", linux_x64);
896 case.addError(
897 \\test "@unionInit on union w/ tag but no fields" {
898 \\ const S = struct {
899 \\ comptime {
900 \\ try expect(false);
901 \\ }
902 \\ };
903 \\ _ = S;
904 \\}
905 ,
906 &.{":4:13: error: invalid 'try' outside function scope"},
907 );
908 }
909 {
910 var case = ctx.exe("import private", linux_x64);
911 case.addError(
912 \\pub fn main() void {
913 \\ @import("print.zig").print();
914 \\}
915 ,
916 &.{
917 ":2:25: error: 'print' is not marked 'pub'",
918 "print.zig:2:1: note: declared here",
919 },
920 );
921 try case.files.append(.{
922 .src =
923 \\// dummy comment to make print be on line 2
924 \\fn print() void {
925 \\ asm volatile ("syscall"
926 \\ :
927 \\ : [number] "{rax}" (@as(usize, 1)),
928 \\ [arg1] "{rdi}" (@as(usize, 1)),
929 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
930 \\ [arg3] "{rdx}" (@as(usize, 14))
931 \\ : "rcx", "r11", "memory"
932 \\ );
933 \\ return;
934 \\}
935 ,
936 .path = "print.zig",
937 });
938 }
939
940 ctx.compileError("function redeclaration", linux_x64,
941 \\// dummy comment
942 \\fn entry() void {}
943 \\fn entry() void {}
944 \\
945 \\fn foo() void {
946 \\ var foo = 1234;
947 \\}
948 , &[_][]const u8{
949 ":3:1: error: redeclaration of 'entry'",
950 ":2:1: note: other declaration here",
951 ":6:9: error: local shadows declaration of 'foo'",
952 ":5:1: note: declared here",
953 });
954
955 ctx.compileError("returns in try", linux_x64,
956 \\pub fn main() !void {
957 \\ try a();
958 \\ try b();
959 \\}
960 \\
961 \\pub fn a() !void {
962 \\ defer try b();
963 \\}
964 \\pub fn b() !void {
965 \\ defer return a();
966 \\}
967 , &[_][]const u8{
968 ":7:8: error: 'try' not allowed inside defer expression",
969 ":10:8: error: cannot return from defer expression",
970 });
971
972 ctx.compileError("ambiguous references", linux_x64,
973 \\const T = struct {
974 \\ const T = struct {
975 \\ fn f() void {
976 \\ _ = T;
977 \\ }
978 \\ };
979 \\};
980 , &.{
981 ":4:17: error: ambiguous reference",
982 ":1:1: note: declared here",
983 ":2:5: note: also declared here",
984 });
985
986 ctx.compileError("inner func accessing outer var", linux_x64,
987 \\pub fn f() void {
988 \\ var bar: bool = true;
989 \\ const S = struct {
990 \\ fn baz() bool {
991 \\ return bar;
992 \\ }
993 \\ };
994 \\ _ = S;
995 \\}
996 , &.{
997 ":5:20: error: 'bar' not accessible from inner function",
998 ":2:9: note: declared here",
999 });
1000
1001 ctx.compileError("global variable redeclaration", linux_x64,
1002 \\// dummy comment
1003 \\var foo = false;
1004 \\var foo = true;
1005 , &[_][]const u8{
1006 ":3:1: error: redeclaration of 'foo'",
1007 ":2:1: note: other declaration here",
1008 });
1009
1010 ctx.compileError("compileError", linux_x64,
1011 \\export fn foo() void {
1012 \\ @compileError("this is an error");
1013 \\}
1014 , &[_][]const u8{":2:3: error: this is an error"});
1015
1016 {
1017 var case = ctx.exe("intToPtr", linux_x64);
1018 case.addError(
1019 \\pub fn main() void {
1020 \\ _ = @intToPtr(*u8, 0);
1021 \\}
1022 , &[_][]const u8{
1023 ":2:24: error: pointer type '*u8' does not allow address zero",
1024 });
1025 case.addError(
1026 \\pub fn main() void {
1027 \\ _ = @intToPtr(*u32, 2);
1028 \\}
1029 , &[_][]const u8{
1030 ":2:25: error: pointer type '*u32' requires aligned address",
1031 });
1032 }
1033
1034 {
1035 var case = ctx.obj("variable shadowing", linux_x64);
1036 case.addError(
1037 \\pub fn main() void {
1038 \\ var i: u32 = 10;
1039 \\ var i: u32 = 10;
1040 \\}
1041 , &[_][]const u8{
1042 ":3:9: error: redeclaration of local variable 'i'",
1043 ":2:9: note: previous declaration here",
1044 });
1045 case.addError(
1046 \\var testing: i64 = 10;
1047 \\pub fn main() void {
1048 \\ var testing: i64 = 20;
1049 \\}
1050 , &[_][]const u8{
1051 ":3:9: error: local shadows declaration of 'testing'",
1052 ":1:1: note: declared here",
1053 });
1054 case.addError(
1055 \\fn a() type {
1056 \\ return struct {
1057 \\ pub fn b() void {
1058 \\ const c = 6;
1059 \\ const c = 69;
1060 \\ }
1061 \\ };
1062 \\}
1063 , &[_][]const u8{
1064 ":5:19: error: redeclaration of local constant 'c'",
1065 ":4:19: note: previous declaration here",
1066 });
1067 }
1068
1069 {
1070 // TODO make the test harness support checking the compile log output too
1071 var case = ctx.obj("@compileLog", linux_x64);
1072 // The other compile error prevents emission of a "found compile log" statement.
1073 case.addError(
1074 \\export fn _start() noreturn {
1075 \\ const b = true;
1076 \\ var f: u32 = 1;
1077 \\ @compileLog(b, 20, f, x);
1078 \\ @compileLog(1000);
1079 \\ var bruh: usize = true;
1080 \\ _ = bruh;
1081 \\ unreachable;
1082 \\}
1083 \\export fn other() void {
1084 \\ @compileLog(1234);
1085 \\}
1086 \\fn x() void {}
1087 , &[_][]const u8{
1088 ":6:23: error: expected usize, found bool",
1089 });
1090
1091 // Now only compile log statements remain. One per Decl.
1092 case.addError(
1093 \\export fn _start() noreturn {
1094 \\ const b = true;
1095 \\ var f: u32 = 1;
1096 \\ @compileLog(b, 20, f, x);
1097 \\ @compileLog(1000);
1098 \\ unreachable;
1099 \\}
1100 \\export fn other() void {
1101 \\ @compileLog(1234);
1102 \\}
1103 \\fn x() void {}
1104 , &[_][]const u8{
1105 ":9:5: error: found compile log statement",
1106 ":4:5: note: also here",
1107 });
1108 }
1109
1110 {
1111 var case = ctx.obj("extern variable has no type", linux_x64);
1112 case.addError(
1113 \\comptime {
1114 \\ _ = foo;
1115 \\}
1116 \\extern var foo: i32;
1117 , &[_][]const u8{":2:9: error: unable to resolve comptime value"});
1118 case.addError(
1119 \\export fn entry() void {
1120 \\ _ = foo;
1121 \\}
1122 \\extern var foo;
1123 , &[_][]const u8{":4:8: error: unable to infer variable type"});
1124 }
1125
1126 {
1127 var case = ctx.exe("break/continue", linux_x64);
1128
1129 // Break out of loop
1130 case.addCompareOutput(
1131 \\pub fn main() void {
1132 \\ while (true) {
1133 \\ break;
1134 \\ }
1135 \\}
1136 ,
1137 "",
1138 );
1139 case.addCompareOutput(
1140 \\pub fn main() void {
1141 \\ foo: while (true) {
1142 \\ break :foo;
1143 \\ }
1144 \\}
1145 ,
1146 "",
1147 );
1148
1149 // Continue in loop
1150 case.addCompareOutput(
1151 \\pub export fn _start() noreturn {
1152 \\ var i: u64 = 0;
1153 \\ while (true) : (i+=1) {
1154 \\ if (i == 4) exit();
1155 \\ continue;
1156 \\ }
1157 \\}
1158 \\
1159 \\fn exit() noreturn {
1160 \\ asm volatile ("syscall"
1161 \\ :
1162 \\ : [number] "{rax}" (231),
1163 \\ [arg1] "{rdi}" (0)
1164 \\ : "rcx", "r11", "memory"
1165 \\ );
1166 \\ unreachable;
1167 \\}
1168 ,
1169 "",
1170 );
1171 case.addCompareOutput(
1172 \\pub export fn _start() noreturn {
1173 \\ var i: u64 = 0;
1174 \\ foo: while (true) : (i+=1) {
1175 \\ if (i == 4) exit();
1176 \\ continue :foo;
1177 \\ }
1178 \\}
1179 \\
1180 \\fn exit() noreturn {
1181 \\ asm volatile ("syscall"
1182 \\ :
1183 \\ : [number] "{rax}" (231),
1184 \\ [arg1] "{rdi}" (0)
1185 \\ : "rcx", "r11", "memory"
1186 \\ );
1187 \\ unreachable;
1188 \\}
1189 ,
1190 "",
1191 );
1192 }
1193
1194 {
1195 var case = ctx.exe("unused labels", linux_x64);
1196 case.addError(
1197 \\comptime {
1198 \\ foo: {}
1199 \\}
1200 , &[_][]const u8{":2:5: error: unused block label"});
1201 case.addError(
1202 \\comptime {
1203 \\ foo: while (true) {}
1204 \\}
1205 , &[_][]const u8{":2:5: error: unused while loop label"});
1206 case.addError(
1207 \\comptime {
1208 \\ foo: for ("foo") |_| {}
1209 \\}
1210 , &[_][]const u8{":2:5: error: unused for loop label"});
1211 case.addError(
1212 \\comptime {
1213 \\ blk: {blk: {}}
1214 \\}
1215 , &[_][]const u8{
1216 ":2:11: error: redefinition of label 'blk'",
1217 ":2:5: note: previous definition here",
1218 });
1219 }
1220
1221 {
1222 var case = ctx.exe("bad inferred variable type", linux_x64);
1223 case.addError(
1224 \\pub fn main() void {
1225 \\ var x = null;
1226 \\ _ = x;
1227 \\}
1228 , &[_][]const u8{
1229 ":2:9: error: variable of type '@Type(.Null)' must be const or comptime",
1230 });
1231 }
1232
1233 {
1234 var case = ctx.exe("compile error in inline fn call fixed", linux_x64);
1235 case.addError(
1236 \\pub export fn _start() noreturn {
1237 \\ var x: usize = 3;
1238 \\ const y = add(10, 2, x);
1239 \\ exit(y - 6);
1240 \\}
1241 \\
1242 \\fn add(a: usize, b: usize, c: usize) callconv(.Inline) usize {
1243 \\ if (a == 10) @compileError("bad");
1244 \\ return a + b + c;
1245 \\}
1246 \\
1247 \\fn exit(code: usize) noreturn {
1248 \\ asm volatile ("syscall"
1249 \\ :
1250 \\ : [number] "{rax}" (231),
1251 \\ [arg1] "{rdi}" (code)
1252 \\ : "rcx", "r11", "memory"
1253 \\ );
1254 \\ unreachable;
1255 \\}
1256 , &[_][]const u8{":8:18: error: bad"});
1257
1258 case.addCompareOutput(
1259 \\pub export fn _start() noreturn {
1260 \\ var x: usize = 3;
1261 \\ const y = add(1, 2, x);
1262 \\ exit(y - 6);
1263 \\}
1264 \\
1265 \\fn add(a: usize, b: usize, c: usize) callconv(.Inline) usize {
1266 \\ if (a == 10) @compileError("bad");
1267 \\ return a + b + c;
1268 \\}
1269 \\
1270 \\fn exit(code: usize) noreturn {
1271 \\ asm volatile ("syscall"
1272 \\ :
1273 \\ : [number] "{rax}" (231),
1274 \\ [arg1] "{rdi}" (code)
1275 \\ : "rcx", "r11", "memory"
1276 \\ );
1277 \\ unreachable;
1278 \\}
1279 ,
1280 "",
1281 );
1282 }
1283 {
1284 var case = ctx.exe("recursive inline function", linux_x64);
1285 case.addCompareOutput(
1286 \\pub export fn _start() noreturn {
1287 \\ const y = fibonacci(7);
1288 \\ exit(y - 21);
1289 \\}
1290 \\
1291 \\fn fibonacci(n: usize) callconv(.Inline) usize {
1292 \\ if (n <= 2) return n;
1293 \\ return fibonacci(n - 2) + fibonacci(n - 1);
1294 \\}
1295 \\
1296 \\fn exit(code: usize) noreturn {
1297 \\ asm volatile ("syscall"
1298 \\ :
1299 \\ : [number] "{rax}" (231),
1300 \\ [arg1] "{rdi}" (code)
1301 \\ : "rcx", "r11", "memory"
1302 \\ );
1303 \\ unreachable;
1304 \\}
1305 ,
1306 "",
1307 );
1308 // This additionally tests that the compile error reports the correct source location.
1309 // Without storing source locations relative to the owner decl, the compile error
1310 // here would be off by 2 bytes (from the "7" -> "999").
1311 case.addError(
1312 \\pub export fn _start() noreturn {
1313 \\ const y = fibonacci(999);
1314 \\ exit(y - 21);
1315 \\}
1316 \\
1317 \\fn fibonacci(n: usize) callconv(.Inline) usize {
1318 \\ if (n <= 2) return n;
1319 \\ return fibonacci(n - 2) + fibonacci(n - 1);
1320 \\}
1321 \\
1322 \\fn exit(code: usize) noreturn {
1323 \\ asm volatile ("syscall"
1324 \\ :
1325 \\ : [number] "{rax}" (231),
1326 \\ [arg1] "{rdi}" (code)
1327 \\ : "rcx", "r11", "memory"
1328 \\ );
1329 \\ unreachable;
1330 \\}
1331 , &[_][]const u8{":8:21: error: evaluation exceeded 1000 backwards branches"});
1332 }
1333 {
1334 var case = ctx.exe("orelse at comptime", linux_x64);
1335 case.addCompareOutput(
1336 \\pub fn main() void {
1337 \\ const i: ?u64 = 0;
1338 \\ const result = i orelse 5;
1339 \\ assert(result == 0);
1340 \\}
1341 \\fn assert(b: bool) void {
1342 \\ if (!b) unreachable;
1343 \\}
1344 ,
1345 "",
1346 );
1347 case.addCompareOutput(
1348 \\pub fn main() void {
1349 \\ const i: ?u64 = null;
1350 \\ const result = i orelse 5;
1351 \\ assert(result == 5);
1352 \\}
1353 \\fn assert(b: bool) void {
1354 \\ if (!b) unreachable;
1355 \\}
1356 ,
1357 "",
1358 );
1359 }
1360
1361 {
1362 var case = ctx.exe("only 1 function and it gets updated", linux_x64);
1363 case.addCompareOutput(
1364 \\pub export fn _start() noreturn {
1365 \\ asm volatile ("syscall"
1366 \\ :
1367 \\ : [number] "{rax}" (60), // exit
1368 \\ [arg1] "{rdi}" (0)
1369 \\ : "rcx", "r11", "memory"
1370 \\ );
1371 \\ unreachable;
1372 \\}
1373 ,
1374 "",
1375 );
1376 case.addCompareOutput(
1377 \\pub export fn _start() noreturn {
1378 \\ asm volatile ("syscall"
1379 \\ :
1380 \\ : [number] "{rax}" (231), // exit_group
1381 \\ [arg1] "{rdi}" (0)
1382 \\ : "rcx", "r11", "memory"
1383 \\ );
1384 \\ unreachable;
1385 \\}
1386 ,
1387 "",
1388 );
1389 }
1390 {
1391 var case = ctx.exe("passing u0 to function", linux_x64);
1392 case.addCompareOutput(
1393 \\pub fn main() void {
1394 \\ doNothing(0);
1395 \\}
1396 \\fn doNothing(arg: u0) void {
1397 \\ _ = arg;
1398 \\}
1399 ,
1400 "",
1401 );
1402 }
1403 {
1404 var case = ctx.exe("catch at comptime", linux_x64);
1405 case.addCompareOutput(
1406 \\pub fn main() void {
1407 \\ const i: anyerror!u64 = 0;
1408 \\ const caught = i catch 5;
1409 \\ assert(caught == 0);
1410 \\}
1411 \\fn assert(b: bool) void {
1412 \\ if (!b) unreachable;
1413 \\}
1414 ,
1415 "",
1416 );
1417
1418 case.addCompareOutput(
1419 \\pub fn main() void {
1420 \\ const i: anyerror!u64 = error.B;
1421 \\ const caught = i catch 5;
1422 \\ assert(caught == 5);
1423 \\}
1424 \\fn assert(b: bool) void {
1425 \\ if (!b) unreachable;
1426 \\}
1427 ,
1428 "",
1429 );
1430
1431 case.addCompareOutput(
1432 \\pub fn main() void {
1433 \\ const a: anyerror!comptime_int = 42;
1434 \\ const b: *const comptime_int = &(a catch unreachable);
1435 \\ assert(b.* == 42);
1436 \\}
1437 \\fn assert(b: bool) void {
1438 \\ if (!b) unreachable; // assertion failure
1439 \\}
1440 , "");
1441
1442 case.addCompareOutput(
1443 \\pub fn main() void {
1444 \\ const a: anyerror!u32 = error.B;
1445 \\ _ = &(a catch |err| assert(err == error.B));
1446 \\}
1447 \\fn assert(b: bool) void {
1448 \\ if (!b) unreachable;
1449 \\}
1450 , "");
1451
1452 case.addCompareOutput(
1453 \\pub fn main() void {
1454 \\ const a: anyerror!u32 = error.Bar;
1455 \\ a catch |err| assert(err == error.Bar);
1456 \\}
1457 \\fn assert(b: bool) void {
1458 \\ if (!b) unreachable;
1459 \\}
1460 , "");
1461 }
1462 {
1463 var case = ctx.exe("merge error sets", linux_x64);
1464
1465 case.addCompareOutput(
1466 \\pub fn main() void {
1467 \\ const E = error{ A, B, D } || error { A, B, C };
1468 \\ E.A catch {};
1469 \\ E.B catch {};
1470 \\ E.C catch {};
1471 \\ E.D catch {};
1472 \\ const E2 = error { X, Y } || @TypeOf(error.Z);
1473 \\ E2.X catch {};
1474 \\ E2.Y catch {};
1475 \\ E2.Z catch {};
1476 \\ assert(anyerror || error { Z } == anyerror);
1477 \\}
1478 \\fn assert(b: bool) void {
1479 \\ if (!b) unreachable;
1480 \\}
1481 ,
1482 "",
1483 );
1484 }
1485 {
1486 var case = ctx.exe("inline assembly", linux_x64);
1487
1488 case.addError(
1489 \\pub fn main() void {
1490 \\ const number = 1234;
1491 \\ const x = asm volatile ("syscall"
1492 \\ : [o] "{rax}" (-> number)
1493 \\ : [number] "{rax}" (231),
1494 \\ [arg1] "{rdi}" (code)
1495 \\ : "rcx", "r11", "memory"
1496 \\ );
1497 \\ _ = x;
1498 \\}
1499 , &[_][]const u8{":4:27: error: expected type, found comptime_int"});
1500 }
1501 {
1502 var case = ctx.exe("comptime var", linux_x64);
1503
1504 case.addError(
1505 \\pub fn main() void {
1506 \\ var a: u32 = 0;
1507 \\ comptime var b: u32 = 0;
1508 \\ if (a == 0) b = 3;
1509 \\}
1510 , &.{
1511 ":4:21: error: store to comptime variable depends on runtime condition",
1512 ":4:11: note: runtime condition here",
1513 });
1514
1515 case.addError(
1516 \\pub fn main() void {
1517 \\ var a: u32 = 0;
1518 \\ comptime var b: u32 = 0;
1519 \\ switch (a) {
1520 \\ 0 => {},
1521 \\ else => b = 3,
1522 \\ }
1523 \\}
1524 , &.{
1525 ":6:21: error: store to comptime variable depends on runtime condition",
1526 ":4:13: note: runtime condition here",
1527 });
1528
1529 case.addCompareOutput(
1530 \\pub fn main() void {
1531 \\ comptime var len: u32 = 5;
1532 \\ print(len);
1533 \\ len += 9;
1534 \\ print(len);
1535 \\}
1536 \\
1537 \\fn print(len: usize) void {
1538 \\ asm volatile ("syscall"
1539 \\ :
1540 \\ : [number] "{rax}" (1),
1541 \\ [arg1] "{rdi}" (1),
1542 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
1543 \\ [arg3] "{rdx}" (len)
1544 \\ : "rcx", "r11", "memory"
1545 \\ );
1546 \\ return;
1547 \\}
1548 , "HelloHello, World!\n");
1549
1550 case.addError(
1551 \\comptime {
1552 \\ var x: i32 = 1;
1553 \\ x += 1;
1554 \\ if (x != 1) unreachable;
1555 \\}
1556 \\pub fn main() void {}
1557 , &.{":4:17: error: unable to resolve comptime value"});
1558
1559 case.addError(
1560 \\pub fn main() void {
1561 \\ comptime var i: u64 = 0;
1562 \\ while (i < 5) : (i += 1) {}
1563 \\}
1564 , &.{
1565 ":3:24: error: cannot store to comptime variable in non-inline loop",
1566 ":3:5: note: non-inline loop here",
1567 });
1568
1569 case.addCompareOutput(
1570 \\pub fn main() void {
1571 \\ var a: u32 = 0;
1572 \\ if (a == 0) {
1573 \\ comptime var b: u32 = 0;
1574 \\ b = 1;
1575 \\ }
1576 \\}
1577 \\comptime {
1578 \\ var x: i32 = 1;
1579 \\ x += 1;
1580 \\ if (x != 2) unreachable;
1581 \\}
1582 , "");
1583
1584 case.addCompareOutput(
1585 \\pub fn main() void {
1586 \\ comptime var i: u64 = 2;
1587 \\ inline while (i < 6) : (i+=1) {
1588 \\ print(i);
1589 \\ }
1590 \\}
1591 \\fn print(len: usize) void {
1592 \\ asm volatile ("syscall"
1593 \\ :
1594 \\ : [number] "{rax}" (1),
1595 \\ [arg1] "{rdi}" (1),
1596 \\ [arg2] "{rsi}" (@ptrToInt("Hello")),
1597 \\ [arg3] "{rdx}" (len)
1598 \\ : "rcx", "r11", "memory"
1599 \\ );
1600 \\ return;
1601 \\}
1602 , "HeHelHellHello");
1603 }
1604
1605 {
1606 var case = ctx.exe("double ampersand", linux_x64);
1607
1608 case.addError(
1609 \\pub const a = if (true && false) 1 else 2;
1610 , &[_][]const u8{":1:24: error: `&&` is invalid; note that `and` is boolean AND"});
1611
1612 case.addError(
1613 \\pub fn main() void {
1614 \\ const a = true;
1615 \\ const b = false;
1616 \\ _ = a & &b;
1617 \\}
1618 , &[_][]const u8{":4:11: error: incompatible types: 'bool' and '*const bool'"});
1619
1620 case.addCompareOutput(
1621 \\pub fn main() void {
1622 \\ const b: u8 = 1;
1623 \\ _ = &&b;
1624 \\}
1625 , "");
1626 }
1627}
test/compile_errors.zig+1422-1082
...@@ -1,53 +1,58 @@...@@ -1,53 +1,58 @@
1const tests = @import("tests.zig");
2const std = @import("std");1const std = @import("std");
2const TestContext = @import("../src/test.zig").TestContext;
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(ctx: *TestContext) !void {
5 cases.add("std.fmt error for unused arguments",5 ctx.exeErrStage1("std.fmt error for unused arguments",
6 \\pub fn main() !void {6 \\pub fn main() !void {
7 \\ @import("std").debug.print("{d} {d} {d} {d} {d}", .{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});7 \\ @import("std").debug.print("{d} {d} {d} {d} {d}", .{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});
8 \\}8 \\}
9 , &.{9 , &.{
10 \\error: 10 unused arguments in "{d} {d} {d} {d} {d}"10 "?:?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'",
11 });11 });
1212
13 cases.add("lazy pointer with undefined element type",13 ctx.objErrStage1("lazy pointer with undefined element type",
14 \\export fn foo() void {14 \\export fn foo() void {
15 \\ comptime var T: type = undefined;15 \\ comptime var T: type = undefined;
16 \\ const S = struct { x: *T };16 \\ const S = struct { x: *T };
17 \\ const I = @typeInfo(S);17 \\ const I = @typeInfo(S);
18 \\ _ = I;
18 \\}19 \\}
19 , &[_][]const u8{20 , &[_][]const u8{
20 "tmp.zig:3:28: error: use of undefined value here causes undefined behavior",21 ":3:28: error: use of undefined value here causes undefined behavior",
21 });22 });
2223
23 cases.add("pointer arithmetic on pointer-to-array",24 ctx.objErrStage1("pointer arithmetic on pointer-to-array",
24 \\export fn foo() void {25 \\export fn foo() void {
25 \\ var x: [10]u8 = undefined;26 \\ var x: [10]u8 = undefined;
26 \\ var y = &x;27 \\ var y = &x;
27 \\ var z = y + 1;28 \\ var z = y + 1;
29 \\ _ = z;
28 \\}30 \\}
29 , &[_][]const u8{31 , &[_][]const u8{
30 "tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'",32 "tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'",
31 });33 });
3234
33 cases.add("pointer attributes checked when coercing pointer to anon literal",35 ctx.objErrStage1("pointer attributes checked when coercing pointer to anon literal",
34 \\comptime {36 \\comptime {
35 \\ const c: [][]const u8 = &.{"hello", "world" };37 \\ const c: [][]const u8 = &.{"hello", "world" };
38 \\ _ = c;
36 \\}39 \\}
37 \\comptime {40 \\comptime {
38 \\ const c: *[2][]const u8 = &.{"hello", "world" };41 \\ const c: *[2][]const u8 = &.{"hello", "world" };
42 \\ _ = c;
39 \\}43 \\}
40 \\const S = struct {a: u8 = 1, b: u32 = 2};44 \\const S = struct {a: u8 = 1, b: u32 = 2};
41 \\comptime {45 \\comptime {
42 \\ const c: *S = &.{};46 \\ const c: *S = &.{};
47 \\ _ = c;
43 \\}48 \\}
44 , &[_][]const u8{49 , &[_][]const u8{
45 "tmp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",50 "tmp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",
46 "tmp.zig:5:33: error: expected type '*[2][]const u8', found '*const struct:5:33'",51 "tmp.zig:6:33: error: expected type '*[2][]const u8', found '*const struct:6:33'",
47 "tmp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",52 "tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'",
48 });53 });
4954
50 cases.add("@Type() union payload is undefined",55 ctx.objErrStage1("@Type() union payload is undefined",
51 \\const Foo = @Type(@import("std").builtin.TypeInfo{56 \\const Foo = @Type(@import("std").builtin.TypeInfo{
52 \\ .Struct = undefined,57 \\ .Struct = undefined,
53 \\});58 \\});
...@@ -56,7 +61,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -56,7 +61,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56 "tmp.zig:1:50: error: use of undefined value here causes undefined behavior",61 "tmp.zig:1:50: error: use of undefined value here causes undefined behavior",
57 });62 });
5863
59 cases.add("wrong initializer for union payload of type 'type'",64 ctx.objErrStage1("wrong initializer for union payload of type 'type'",
60 \\const U = union(enum) {65 \\const U = union(enum) {
61 \\ A: type,66 \\ A: type,
62 \\};67 \\};
...@@ -71,7 +76,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -71,7 +76,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
71 "tmp.zig:9:8: error: use of undefined value here causes undefined behavior",76 "tmp.zig:9:8: error: use of undefined value here causes undefined behavior",
72 });77 });
7378
74 cases.add("union with too small explicit signed tag type",79 ctx.objErrStage1("union with too small explicit signed tag type",
75 \\const U = union(enum(i2)) {80 \\const U = union(enum(i2)) {
76 \\ A: u8,81 \\ A: u8,
77 \\ B: u8,82 \\ B: u8,
...@@ -86,7 +91,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -86,7 +91,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
86 "tmp.zig:1:22: note: type i2 cannot fit values in range 0...3",91 "tmp.zig:1:22: note: type i2 cannot fit values in range 0...3",
87 });92 });
8893
89 cases.add("union with too small explicit unsigned tag type",94 ctx.objErrStage1("union with too small explicit unsigned tag type",
90 \\const U = union(enum(u2)) {95 \\const U = union(enum(u2)) {
91 \\ A: u8,96 \\ A: u8,
92 \\ B: u8,97 \\ B: u8,
...@@ -102,56 +107,60 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -102,56 +107,60 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
102 "tmp.zig:1:22: note: type u2 cannot fit values in range 0...4",107 "tmp.zig:1:22: note: type u2 cannot fit values in range 0...4",
103 });108 });
104109
105 cases.addCase(x: {110 {
106 var tc = cases.create("callconv(.Interrupt) on unsupported platform",111 const case = ctx.obj("callconv(.Interrupt) on unsupported platform", .{
112 .cpu_arch = .aarch64,
113 .os_tag = .linux,
114 .abi = .none,
115 });
116 case.backend = .stage1;
117 case.addError(
107 \\export fn entry() callconv(.Interrupt) void {}118 \\export fn entry() callconv(.Interrupt) void {}
108 , &[_][]const u8{119 , &[_][]const u8{
109 "tmp.zig:1:28: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64",120 "tmp.zig:1:28: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64",
110 });121 });
111 tc.target = std.zig.CrossTarget{122 }
112 .cpu_arch = .aarch64,123 {
124 var case = ctx.obj("callconv(.Signal) on unsupported platform", .{
125 .cpu_arch = .x86_64,
113 .os_tag = .linux,126 .os_tag = .linux,
114 .abi = .none,127 .abi = .none,
115 };128 });
116 break :x tc;129 case.backend = .stage1;
117 });130 case.addError(
118
119 cases.addCase(x: {
120 var tc = cases.create("callconv(.Signal) on unsupported platform",
121 \\export fn entry() callconv(.Signal) void {}131 \\export fn entry() callconv(.Signal) void {}
122 , &[_][]const u8{132 , &[_][]const u8{
123 "tmp.zig:1:28: error: callconv 'Signal' is only available on AVR, not x86_64",133 "tmp.zig:1:28: error: callconv 'Signal' is only available on AVR, not x86_64",
124 });134 });
125 tc.target = std.zig.CrossTarget{135 }
136 {
137 const case = ctx.obj("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform", .{
126 .cpu_arch = .x86_64,138 .cpu_arch = .x86_64,
127 .os_tag = .linux,139 .os_tag = .linux,
128 .abi = .none,140 .abi = .none,
129 };141 });
130 break :x tc;142 case.backend = .stage1;
131 });143 case.addError(
132 cases.addCase(x: {
133 var tc = cases.create("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform",
134 \\const F1 = fn () callconv(.Stdcall) void;144 \\const F1 = fn () callconv(.Stdcall) void;
135 \\const F2 = fn () callconv(.Fastcall) void;145 \\const F2 = fn () callconv(.Fastcall) void;
136 \\const F3 = fn () callconv(.Thiscall) void;146 \\const F3 = fn () callconv(.Thiscall) void;
137 \\export fn entry1() void { var a: F1 = undefined; }147 \\export fn entry1() void { var a: F1 = undefined; _ = a; }
138 \\export fn entry2() void { var a: F2 = undefined; }148 \\export fn entry2() void { var a: F2 = undefined; _ = a; }
139 \\export fn entry3() void { var a: F3 = undefined; }149 \\export fn entry3() void { var a: F3 = undefined; _ = a; }
140 , &[_][]const u8{150 , &[_][]const u8{
141 "tmp.zig:1:27: error: callconv 'Stdcall' is only available on x86, not x86_64",151 "tmp.zig:1:27: error: callconv 'Stdcall' is only available on x86, not x86_64",
142 "tmp.zig:2:27: error: callconv 'Fastcall' is only available on x86, not x86_64",152 "tmp.zig:2:27: error: callconv 'Fastcall' is only available on x86, not x86_64",
143 "tmp.zig:3:27: error: callconv 'Thiscall' is only available on x86, not x86_64",153 "tmp.zig:3:27: error: callconv 'Thiscall' is only available on x86, not x86_64",
144 });154 });
145 tc.target = std.zig.CrossTarget{155 }
156 {
157 const case = ctx.obj("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform", .{
146 .cpu_arch = .x86_64,158 .cpu_arch = .x86_64,
147 .os_tag = .linux,159 .os_tag = .linux,
148 .abi = .none,160 .abi = .none,
149 };161 });
150 break :x tc;162 case.backend = .stage1;
151 });163 case.addError(
152
153 cases.addCase(x: {
154 var tc = cases.create("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform",
155 \\export fn entry1() callconv(.Stdcall) void {}164 \\export fn entry1() callconv(.Stdcall) void {}
156 \\export fn entry2() callconv(.Fastcall) void {}165 \\export fn entry2() callconv(.Fastcall) void {}
157 \\export fn entry3() callconv(.Thiscall) void {}166 \\export fn entry3() callconv(.Thiscall) void {}
...@@ -160,30 +169,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -160,30 +169,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
160 "tmp.zig:2:29: error: callconv 'Fastcall' is only available on x86, not x86_64",169 "tmp.zig:2:29: error: callconv 'Fastcall' is only available on x86, not x86_64",
161 "tmp.zig:3:29: error: callconv 'Thiscall' is only available on x86, not x86_64",170 "tmp.zig:3:29: error: callconv 'Thiscall' is only available on x86, not x86_64",
162 });171 });
163 tc.target = std.zig.CrossTarget{172 }
173 {
174 const case = ctx.obj("callconv(.Vectorcall) on unsupported platform", .{
164 .cpu_arch = .x86_64,175 .cpu_arch = .x86_64,
165 .os_tag = .linux,176 .os_tag = .linux,
166 .abi = .none,177 .abi = .none,
167 };178 });
168 break :x tc;179 case.backend = .stage1;
169 });180 case.addError(
170
171 cases.addCase(x: {
172 var tc = cases.create("callconv(.Vectorcall) on unsupported platform",
173 \\export fn entry() callconv(.Vectorcall) void {}181 \\export fn entry() callconv(.Vectorcall) void {}
174 , &[_][]const u8{182 , &[_][]const u8{
175 "tmp.zig:1:28: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64",183 "tmp.zig:1:28: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64",
176 });184 });
177 tc.target = std.zig.CrossTarget{185 }
186 {
187 const case = ctx.obj("callconv(.APCS, .AAPCS, .AAPCSVFP) on unsupported platform", .{
178 .cpu_arch = .x86_64,188 .cpu_arch = .x86_64,
179 .os_tag = .linux,189 .os_tag = .linux,
180 .abi = .none,190 .abi = .none,
181 };191 });
182 break :x tc;192 case.backend = .stage1;
183 });193 case.addError(
184
185 cases.addCase(x: {
186 var tc = cases.create("callconv(.APCS, .AAPCS, .AAPCSVFP) on unsupported platform",
187 \\export fn entry1() callconv(.APCS) void {}194 \\export fn entry1() callconv(.APCS) void {}
188 \\export fn entry2() callconv(.AAPCS) void {}195 \\export fn entry2() callconv(.AAPCS) void {}
189 \\export fn entry3() callconv(.AAPCSVFP) void {}196 \\export fn entry3() callconv(.AAPCSVFP) void {}
...@@ -192,15 +199,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -192,15 +199,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
192 "tmp.zig:2:29: error: callconv 'AAPCS' is only available on ARM, not x86_64",199 "tmp.zig:2:29: error: callconv 'AAPCS' is only available on ARM, not x86_64",
193 "tmp.zig:3:29: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64",200 "tmp.zig:3:29: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64",
194 });201 });
195 tc.target = std.zig.CrossTarget{202 }
196 .cpu_arch = .x86_64,
197 .os_tag = .linux,
198 .abi = .none,
199 };
200 break :x tc;
201 });
202203
203 cases.add("unreachable executed at comptime",204 ctx.objErrStage1("unreachable executed at comptime",
204 \\fn foo(comptime x: i32) i32 {205 \\fn foo(comptime x: i32) i32 {
205 \\ comptime {206 \\ comptime {
206 \\ if (x >= 0) return -x;207 \\ if (x >= 0) return -x;
...@@ -215,7 +216,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -215,7 +216,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
215 "tmp.zig:8:12: note: called from here",216 "tmp.zig:8:12: note: called from here",
216 });217 });
217218
218 cases.add("@Type with TypeInfo.Int",219 ctx.objErrStage1("@Type with TypeInfo.Int",
219 \\const builtin = @import("std").builtin;220 \\const builtin = @import("std").builtin;
220 \\export fn entry() void {221 \\export fn entry() void {
221 \\ _ = @Type(builtin.TypeInfo.Int {222 \\ _ = @Type(builtin.TypeInfo.Int {
...@@ -227,7 +228,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -227,7 +228,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
227 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",228 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",
228 });229 });
229230
230 cases.add("indexing a undefined slice at comptime",231 ctx.objErrStage1("indexing a undefined slice at comptime",
231 \\comptime {232 \\comptime {
232 \\ var slice: []u8 = undefined;233 \\ var slice: []u8 = undefined;
233 \\ slice[0] = 2;234 \\ slice[0] = 2;
...@@ -236,7 +237,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -236,7 +237,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
236 "tmp.zig:3:10: error: index 0 outside slice of size 0",237 "tmp.zig:3:10: error: index 0 outside slice of size 0",
237 });238 });
238239
239 cases.add("array in c exported function",240 ctx.objErrStage1("array in c exported function",
240 \\export fn zig_array(x: [10]u8) void {241 \\export fn zig_array(x: [10]u8) void {
241 \\try expect(std.mem.eql(u8, &x, "1234567890"));242 \\try expect(std.mem.eql(u8, &x, "1234567890"));
242 \\}243 \\}
...@@ -249,7 +250,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -249,7 +250,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
249 "tmp.zig:5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'",250 "tmp.zig:5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'",
250 });251 });
251252
252 cases.add("@Type for exhaustive enum with undefined tag type",253 ctx.objErrStage1("@Type for exhaustive enum with undefined tag type",
253 \\const TypeInfo = @import("std").builtin.TypeInfo;254 \\const TypeInfo = @import("std").builtin.TypeInfo;
254 \\const Tag = @Type(.{255 \\const Tag = @Type(.{
255 \\ .Enum = .{256 \\ .Enum = .{
...@@ -267,19 +268,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -267,19 +268,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
267 "tmp.zig:2:20: error: use of undefined value here causes undefined behavior",268 "tmp.zig:2:20: error: use of undefined value here causes undefined behavior",
268 });269 });
269270
270 cases.add("extern struct with non-extern-compatible integer tag type",271 ctx.objErrStage1("extern struct with non-extern-compatible integer tag type",
271 \\pub const E = enum(u31) { A, B, C };272 \\pub const E = enum(u31) { A, B, C };
272 \\pub const S = extern struct {273 \\pub const S = extern struct {
273 \\ e: E,274 \\ e: E,
274 \\};275 \\};
275 \\export fn entry() void {276 \\export fn entry() void {
276 \\ const s: S = undefined;277 \\ const s: S = undefined;
278 \\ _ = s;
277 \\}279 \\}
278 , &[_][]const u8{280 , &[_][]const u8{
279 "tmp.zig:3:5: error: extern structs cannot contain fields of type 'E'",281 "tmp.zig:3:5: error: extern structs cannot contain fields of type 'E'",
280 });282 });
281283
282 cases.add("@Type for exhaustive enum with non-integer tag type",284 ctx.objErrStage1("@Type for exhaustive enum with non-integer tag type",
283 \\const TypeInfo = @import("std").builtin.TypeInfo;285 \\const TypeInfo = @import("std").builtin.TypeInfo;
284 \\const Tag = @Type(.{286 \\const Tag = @Type(.{
285 \\ .Enum = .{287 \\ .Enum = .{
...@@ -297,7 +299,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -297,7 +299,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
297 "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",299 "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",
298 });300 });
299301
300 cases.add("extern struct with extern-compatible but inferred integer tag type",302 ctx.objErrStage1("extern struct with extern-compatible but inferred integer tag type",
301 \\pub const E = enum {303 \\pub const E = enum {
302 \\@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",304 \\@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",
303 \\@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",305 \\@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",
...@@ -333,12 +335,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -333,12 +335,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
333 \\export fn entry() void {335 \\export fn entry() void {
334 \\ if (@typeInfo(E).Enum.tag_type != u8) @compileError("did not infer u8 tag type");336 \\ if (@typeInfo(E).Enum.tag_type != u8) @compileError("did not infer u8 tag type");
335 \\ const s: S = undefined;337 \\ const s: S = undefined;
338 \\ _ = s;
336 \\}339 \\}
337 , &[_][]const u8{340 , &[_][]const u8{
338 "tmp.zig:31:5: error: extern structs cannot contain fields of type 'E'",341 "tmp.zig:31:5: error: extern structs cannot contain fields of type 'E'",
339 });342 });
340343
341 cases.add("@Type for tagged union with extra enum field",344 ctx.objErrStage1("@Type for tagged union with extra enum field",
342 \\const TypeInfo = @import("std").builtin.TypeInfo;345 \\const TypeInfo = @import("std").builtin.TypeInfo;
343 \\const Tag = @Type(.{346 \\const Tag = @Type(.{
344 \\ .Enum = .{347 \\ .Enum = .{
...@@ -373,7 +376,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -373,7 +376,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
373 "tmp.zig:27:24: note: referenced here",376 "tmp.zig:27:24: note: referenced here",
374 });377 });
375378
376 cases.add("field access of opaque type",379 ctx.objErrStage1("field access of opaque type",
377 \\const MyType = opaque {};380 \\const MyType = opaque {};
378 \\381 \\
379 \\export fn entry() bool {382 \\export fn entry() bool {
...@@ -388,16 +391,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -388,16 +391,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
388 "tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType'",391 "tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType'",
389 });392 });
390393
391 cases.add("opaque type with field",394 ctx.objErrStage1("opaque type with field",
392 \\const Opaque = opaque { foo: i32 };395 \\const Opaque = opaque { foo: i32 };
393 \\export fn entry() void {396 \\export fn entry() void {
394 \\ const foo: ?*Opaque = null;397 \\ const foo: ?*Opaque = null;
398 \\ _ = foo;
395 \\}399 \\}
396 , &[_][]const u8{400 , &[_][]const u8{
397 "tmp.zig:1:25: error: opaque types cannot have fields",401 "tmp.zig:1:25: error: opaque types cannot have fields",
398 });402 });
399403
400 cases.add("@Type(.Fn) with is_generic = true",404 ctx.objErrStage1("@Type(.Fn) with is_generic = true",
401 \\const Foo = @Type(.{405 \\const Foo = @Type(.{
402 \\ .Fn = .{406 \\ .Fn = .{
403 \\ .calling_convention = .Unspecified,407 \\ .calling_convention = .Unspecified,
...@@ -413,7 +417,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -413,7 +417,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
413 "tmp.zig:1:20: error: TypeInfo.Fn.is_generic must be false for @Type",417 "tmp.zig:1:20: error: TypeInfo.Fn.is_generic must be false for @Type",
414 });418 });
415419
416 cases.add("@Type(.Fn) with is_var_args = true and non-C callconv",420 ctx.objErrStage1("@Type(.Fn) with is_var_args = true and non-C callconv",
417 \\const Foo = @Type(.{421 \\const Foo = @Type(.{
418 \\ .Fn = .{422 \\ .Fn = .{
419 \\ .calling_convention = .Unspecified,423 \\ .calling_convention = .Unspecified,
...@@ -429,7 +433,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -429,7 +433,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
429 "tmp.zig:1:20: error: varargs functions must have C calling convention",433 "tmp.zig:1:20: error: varargs functions must have C calling convention",
430 });434 });
431435
432 cases.add("@Type(.Fn) with return_type = null",436 ctx.objErrStage1("@Type(.Fn) with return_type = null",
433 \\const Foo = @Type(.{437 \\const Foo = @Type(.{
434 \\ .Fn = .{438 \\ .Fn = .{
435 \\ .calling_convention = .Unspecified,439 \\ .calling_convention = .Unspecified,
...@@ -445,7 +449,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -445,7 +449,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
445 "tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type",449 "tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type",
446 });450 });
447451
448 cases.add("@Type for union with opaque field",452 ctx.objErrStage1("@Type for union with opaque field",
449 \\const TypeInfo = @import("std").builtin.TypeInfo;453 \\const TypeInfo = @import("std").builtin.TypeInfo;
450 \\const Untagged = @Type(.{454 \\const Untagged = @Type(.{
451 \\ .Union = .{455 \\ .Union = .{
...@@ -465,23 +469,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -465,23 +469,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
465 "tmp.zig:13:17: note: referenced here",469 "tmp.zig:13:17: note: referenced here",
466 });470 });
467471
468 cases.add("slice sentinel mismatch",472 ctx.objErrStage1("slice sentinel mismatch",
469 \\export fn entry() void {473 \\export fn entry() void {
470 \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };474 \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };
475 \\ _ = x;
471 \\}476 \\}
472 , &[_][]const u8{477 , &[_][]const u8{
473 "tmp.zig:2:62: error: index 3 outside vector of size 3",478 "tmp.zig:2:62: error: index 3 outside vector of size 3",
474 });479 });
475480
476 cases.add("slice sentinel mismatch",481 ctx.objErrStage1("slice sentinel mismatch",
477 \\export fn entry() void {482 \\export fn entry() void {
478 \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 };483 \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 };
484 \\ _ = y;
479 \\}485 \\}
480 , &[_][]const u8{486 , &[_][]const u8{
481 "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",487 "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",
482 });488 });
483489
484 cases.add("@Type for union with zero fields",490 ctx.objErrStage1("@Type for union with zero fields",
485 \\const TypeInfo = @import("std").builtin.TypeInfo;491 \\const TypeInfo = @import("std").builtin.TypeInfo;
486 \\const Untagged = @Type(.{492 \\const Untagged = @Type(.{
487 \\ .Union = .{493 \\ .Union = .{
...@@ -499,7 +505,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -499,7 +505,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
499 "tmp.zig:11:17: note: referenced here",505 "tmp.zig:11:17: note: referenced here",
500 });506 });
501507
502 cases.add("@Type for exhaustive enum with zero fields",508 ctx.objErrStage1("@Type for exhaustive enum with zero fields",
503 \\const TypeInfo = @import("std").builtin.TypeInfo;509 \\const TypeInfo = @import("std").builtin.TypeInfo;
504 \\const Tag = @Type(.{510 \\const Tag = @Type(.{
505 \\ .Enum = .{511 \\ .Enum = .{
...@@ -518,7 +524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -518,7 +524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
518 "tmp.zig:12:9: note: referenced here",524 "tmp.zig:12:9: note: referenced here",
519 });525 });
520526
521 cases.add("@Type for tagged union with extra union field",527 ctx.objErrStage1("@Type for tagged union with extra union field",
522 \\const TypeInfo = @import("std").builtin.TypeInfo;528 \\const TypeInfo = @import("std").builtin.TypeInfo;
523 \\const Tag = @Type(.{529 \\const Tag = @Type(.{
524 \\ .Enum = .{530 \\ .Enum = .{
...@@ -554,7 +560,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -554,7 +560,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
554 "tmp.zig:27:24: note: referenced here",560 "tmp.zig:27:24: note: referenced here",
555 });561 });
556562
557 cases.add("@Type with undefined",563 ctx.objErrStage1("@Type with undefined",
558 \\comptime {564 \\comptime {
559 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });565 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
560 \\}566 \\}
...@@ -573,7 +579,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -573,7 +579,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
573 "tmp.zig:5:16: error: use of undefined value here causes undefined behavior",579 "tmp.zig:5:16: error: use of undefined value here causes undefined behavior",
574 });580 });
575581
576 cases.add("struct with declarations unavailable for @Type",582 ctx.objErrStage1("struct with declarations unavailable for @Type",
577 \\export fn entry() void {583 \\export fn entry() void {
578 \\ _ = @Type(@typeInfo(struct { const foo = 1; }));584 \\ _ = @Type(@typeInfo(struct { const foo = 1; }));
579 \\}585 \\}
...@@ -581,7 +587,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -581,7 +587,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
581 "tmp.zig:2:15: error: TypeInfo.Struct.decls must be empty for @Type",587 "tmp.zig:2:15: error: TypeInfo.Struct.decls must be empty for @Type",
582 });588 });
583589
584 cases.add("enum with declarations unavailable for @Type",590 ctx.objErrStage1("enum with declarations unavailable for @Type",
585 \\export fn entry() void {591 \\export fn entry() void {
586 \\ _ = @Type(@typeInfo(enum { foo, const bar = 1; }));592 \\ _ = @Type(@typeInfo(enum { foo, const bar = 1; }));
587 \\}593 \\}
...@@ -589,36 +595,44 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -589,36 +595,44 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
589 "tmp.zig:2:15: error: TypeInfo.Enum.decls must be empty for @Type",595 "tmp.zig:2:15: error: TypeInfo.Enum.decls must be empty for @Type",
590 });596 });
591597
592 cases.addTest("reject extern variables with initializers",598 ctx.testErrStage1("reject extern variables with initializers",
593 \\extern var foo: int = 2;599 \\extern var foo: int = 2;
594 , &[_][]const u8{600 , &[_][]const u8{
595 "tmp.zig:1:1: error: extern variables have no initializers",601 "tmp.zig:1:23: error: extern variables have no initializers",
596 });602 });
597603
598 cases.addTest("duplicate/unused labels",604 ctx.testErrStage1("duplicate/unused labels",
599 \\comptime {605 \\comptime {
600 \\ blk: { blk: while (false) {} }606 \\ blk: { blk: while (false) {} }
607 \\}
608 \\comptime {
601 \\ blk: while (false) { blk: for (@as([0]void, undefined)) |_| {} }609 \\ blk: while (false) { blk: for (@as([0]void, undefined)) |_| {} }
610 \\}
611 \\comptime {
602 \\ blk: for (@as([0]void, undefined)) |_| { blk: {} }612 \\ blk: for (@as([0]void, undefined)) |_| { blk: {} }
603 \\}613 \\}
604 \\comptime {614 \\comptime {
605 \\ blk: {}615 \\ blk: {}
616 \\}
617 \\comptime {
606 \\ blk: while(false) {}618 \\ blk: while(false) {}
619 \\}
620 \\comptime {
607 \\ blk: for(@as([0]void, undefined)) |_| {}621 \\ blk: for(@as([0]void, undefined)) |_| {}
608 \\}622 \\}
609 , &[_][]const u8{623 , &[_][]const u8{
610 "tmp.zig:2:17: error: redeclaration of label 'blk'",624 "tmp.zig:2:12: error: redefinition of label 'blk'",
611 "tmp.zig:2:10: note: previous declaration is here",625 "tmp.zig:2:5: note: previous definition here",
612 "tmp.zig:3:31: error: redeclaration of label 'blk'",626 "tmp.zig:5:26: error: redefinition of label 'blk'",
613 "tmp.zig:3:10: note: previous declaration is here",627 "tmp.zig:5:5: note: previous definition here",
614 "tmp.zig:4:51: error: redeclaration of label 'blk'",628 "tmp.zig:8:46: error: redefinition of label 'blk'",
615 "tmp.zig:4:10: note: previous declaration is here",629 "tmp.zig:8:5: note: previous definition here",
616 "tmp.zig:7:10: error: unused block label",630 "tmp.zig:11:5: error: unused block label",
617 "tmp.zig:8:10: error: unused while label",631 "tmp.zig:14:5: error: unused while loop label",
618 "tmp.zig:9:10: error: unused for label",632 "tmp.zig:17:5: error: unused for loop label",
619 });633 });
620634
621 cases.addTest("@alignCast of zero sized types",635 ctx.testErrStage1("@alignCast of zero sized types",
622 \\export fn foo() void {636 \\export fn foo() void {
623 \\ const a: *void = undefined;637 \\ const a: *void = undefined;
624 \\ _ = @alignCast(2, a);638 \\ _ = @alignCast(2, a);
...@@ -633,7 +647,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -633,7 +647,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
633 \\}647 \\}
634 \\export fn qux() void {648 \\export fn qux() void {
635 \\ const a = struct {649 \\ const a = struct {
636 \\ fn a(comptime b: u32) void {}650 \\ fn a(comptime b: u32) void { _ = b; }
637 \\ }.a;651 \\ }.a;
638 \\ _ = @alignCast(2, a);652 \\ _ = @alignCast(2, a);
639 \\}653 \\}
...@@ -644,7 +658,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -644,7 +658,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
644 "tmp.zig:17:23: error: cannot adjust alignment of zero sized type 'fn(u32) anytype'",658 "tmp.zig:17:23: error: cannot adjust alignment of zero sized type 'fn(u32) anytype'",
645 });659 });
646660
647 cases.addTest("invalid non-exhaustive enum to union",661 ctx.testErrStage1("invalid non-exhaustive enum to union",
648 \\const E = enum(u8) {662 \\const E = enum(u8) {
649 \\ a,663 \\ a,
650 \\ b,664 \\ b,
...@@ -657,17 +671,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -657,17 +671,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
657 \\export fn foo() void {671 \\export fn foo() void {
658 \\ var e = @intToEnum(E, 15);672 \\ var e = @intToEnum(E, 15);
659 \\ var u: U = e;673 \\ var u: U = e;
674 \\ _ = u;
660 \\}675 \\}
661 \\export fn bar() void {676 \\export fn bar() void {
662 \\ const e = @intToEnum(E, 15);677 \\ const e = @intToEnum(E, 15);
663 \\ var u: U = e;678 \\ var u: U = e;
679 \\ _ = u;
664 \\}680 \\}
665 , &[_][]const u8{681 , &[_][]const u8{
666 "tmp.zig:12:16: error: runtime cast to union 'U' from non-exhustive enum",682 "tmp.zig:12:16: error: runtime cast to union 'U' from non-exhustive enum",
667 "tmp.zig:16:16: error: no tag by value 15",683 "tmp.zig:17:16: error: no tag by value 15",
668 });684 });
669685
670 cases.addTest("switching with exhaustive enum has '_' prong ",686 ctx.testErrStage1("switching with exhaustive enum has '_' prong ",
671 \\const E = enum{687 \\const E = enum{
672 \\ a,688 \\ a,
673 \\ b,689 \\ b,
...@@ -684,7 +700,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -684,7 +700,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
684 "tmp.zig:7:5: error: switch on exhaustive enum has `_` prong",700 "tmp.zig:7:5: error: switch on exhaustive enum has `_` prong",
685 });701 });
686702
687 cases.addTest("invalid pointer with @Type",703 ctx.testErrStage1("invalid pointer with @Type",
688 \\export fn entry() void {704 \\export fn entry() void {
689 \\ _ = @Type(.{ .Pointer = .{705 \\ _ = @Type(.{ .Pointer = .{
690 \\ .size = .One,706 \\ .size = .One,
...@@ -700,7 +716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -700,7 +716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
700 "tmp.zig:2:16: error: sentinels are only allowed on slices and unknown-length pointers",716 "tmp.zig:2:16: error: sentinels are only allowed on slices and unknown-length pointers",
701 });717 });
702718
703 cases.addTest("helpful return type error message",719 ctx.testErrStage1("helpful return type error message",
704 \\export fn foo() u32 {720 \\export fn foo() u32 {
705 \\ return error.Ohno;721 \\ return error.Ohno;
706 \\}722 \\}
...@@ -728,7 +744,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -728,7 +744,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
728 "tmp.zig:14:5: note: cannot store an error in type 'u32'",744 "tmp.zig:14:5: note: cannot store an error in type 'u32'",
729 });745 });
730746
731 cases.addTest("int/float conversion to comptime_int/float",747 ctx.testErrStage1("int/float conversion to comptime_int/float",
732 \\export fn foo() void {748 \\export fn foo() void {
733 \\ var a: f32 = 2;749 \\ var a: f32 = 2;
734 \\ _ = @floatToInt(comptime_int, a);750 \\ _ = @floatToInt(comptime_int, a);
...@@ -744,16 +760,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -744,16 +760,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
744 "tmp.zig:7:9: note: referenced here",760 "tmp.zig:7:9: note: referenced here",
745 });761 });
746762
747 cases.add("extern variable has no type",763 ctx.objErrStage1("extern variable has no type",
748 \\extern var foo;764 \\extern var foo;
749 \\pub export fn entry() void {765 \\pub export fn entry() void {
750 \\ foo;766 \\ foo;
751 \\}767 \\}
752 , &[_][]const u8{768 , &[_][]const u8{
753 "tmp.zig:1:1: error: unable to infer variable type",769 "tmp.zig:1:8: error: unable to infer variable type",
754 });770 });
755771
756 cases.add("@src outside function",772 ctx.objErrStage1("@src outside function",
757 \\comptime {773 \\comptime {
758 \\ @src();774 \\ @src();
759 \\}775 \\}
...@@ -761,7 +777,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -761,7 +777,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
761 "tmp.zig:2:5: error: @src outside function",777 "tmp.zig:2:5: error: @src outside function",
762 });778 });
763779
764 cases.add("call assigned to constant",780 ctx.objErrStage1("call assigned to constant",
765 \\const Foo = struct {781 \\const Foo = struct {
766 \\ x: i32,782 \\ x: i32,
767 \\};783 \\};
...@@ -784,15 +800,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -784,15 +800,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
784 "tmp.zig:16:14: error: cannot assign to constant",800 "tmp.zig:16:14: error: cannot assign to constant",
785 });801 });
786802
787 cases.add("invalid pointer syntax",803 ctx.objErrStage1("invalid pointer syntax",
788 \\export fn foo() void {804 \\export fn foo() void {
789 \\ var guid: *:0 const u8 = undefined;805 \\ var guid: *:0 const u8 = undefined;
790 \\}806 \\}
791 , &[_][]const u8{807 , &[_][]const u8{
792 "tmp.zig:2:15: error: sentinels are only allowed on unknown-length pointers",808 "tmp.zig:2:16: error: expected type expression, found ':'",
793 });809 });
794810
795 cases.add("declaration between fields",811 ctx.objErrStage1("declaration between fields",
796 \\const S = struct {812 \\const S = struct {
797 \\ const foo = 2;813 \\ const foo = 2;
798 \\ const bar = 2;814 \\ const bar = 2;
...@@ -810,16 +826,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -810,16 +826,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
810 "tmp.zig:6:5: error: declarations are not allowed between container fields",826 "tmp.zig:6:5: error: declarations are not allowed between container fields",
811 });827 });
812828
813 cases.add("non-extern function with var args",829 ctx.objErrStage1("non-extern function with var args",
814 \\fn foo(args: ...) void {}830 \\fn foo(args: ...) void {}
815 \\export fn entry() void {831 \\export fn entry() void {
816 \\ foo();832 \\ foo();
817 \\}833 \\}
818 , &[_][]const u8{834 , &[_][]const u8{
819 "tmp.zig:1:1: error: non-extern function is variadic",835 "tmp.zig:1:14: error: expected type expression, found '...'",
820 });836 });
821837
822 cases.addTest("invalid int casts",838 ctx.testErrStage1("invalid int casts",
823 \\export fn foo() void {839 \\export fn foo() void {
824 \\ var a: u32 = 2;840 \\ var a: u32 = 2;
825 \\ _ = @intCast(comptime_int, a);841 \\ _ = @intCast(comptime_int, a);
...@@ -847,7 +863,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -847,7 +863,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
847 "tmp.zig:15:9: note: referenced here",863 "tmp.zig:15:9: note: referenced here",
848 });864 });
849865
850 cases.addTest("invalid float casts",866 ctx.testErrStage1("invalid float casts",
851 \\export fn foo() void {867 \\export fn foo() void {
852 \\ var a: f32 = 2;868 \\ var a: f32 = 2;
853 \\ _ = @floatCast(comptime_float, a);869 \\ _ = @floatCast(comptime_float, a);
...@@ -875,7 +891,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -875,7 +891,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
875 "tmp.zig:15:9: note: referenced here",891 "tmp.zig:15:9: note: referenced here",
876 });892 });
877893
878 cases.addTest("invalid assignments",894 ctx.testErrStage1("invalid assignments",
879 \\export fn entry1() void {895 \\export fn entry1() void {
880 \\ var a: []const u8 = "foo";896 \\ var a: []const u8 = "foo";
881 \\ a[0..2] = "bar";897 \\ a[0..2] = "bar";
...@@ -893,7 +909,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -893,7 +909,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
893 "tmp.zig:10:7: error: invalid left-hand side to assignment",909 "tmp.zig:10:7: error: invalid left-hand side to assignment",
894 });910 });
895911
896 cases.addTest("reassign to array parameter",912 ctx.testErrStage1("reassign to array parameter",
897 \\fn reassign(a: [3]f32) void {913 \\fn reassign(a: [3]f32) void {
898 \\ a = [3]f32{4, 5, 6};914 \\ a = [3]f32{4, 5, 6};
899 \\}915 \\}
...@@ -904,7 +920,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -904,7 +920,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
904 "tmp.zig:2:15: error: cannot assign to constant",920 "tmp.zig:2:15: error: cannot assign to constant",
905 });921 });
906922
907 cases.addTest("reassign to slice parameter",923 ctx.testErrStage1("reassign to slice parameter",
908 \\pub fn reassign(s: []const u8) void {924 \\pub fn reassign(s: []const u8) void {
909 \\ s = s[0..];925 \\ s = s[0..];
910 \\}926 \\}
...@@ -915,7 +931,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -915,7 +931,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
915 "tmp.zig:2:10: error: cannot assign to constant",931 "tmp.zig:2:10: error: cannot assign to constant",
916 });932 });
917933
918 cases.addTest("reassign to struct parameter",934 ctx.testErrStage1("reassign to struct parameter",
919 \\const S = struct {935 \\const S = struct {
920 \\ x: u32,936 \\ x: u32,
921 \\};937 \\};
...@@ -929,7 +945,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -929,7 +945,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
929 "tmp.zig:5:10: error: cannot assign to constant",945 "tmp.zig:5:10: error: cannot assign to constant",
930 });946 });
931947
932 cases.addTest("reference to const data",948 ctx.testErrStage1("reference to const data",
933 \\export fn foo() void {949 \\export fn foo() void {
934 \\ var ptr = &[_]u8{0,0,0,0};950 \\ var ptr = &[_]u8{0,0,0,0};
935 \\ ptr[1] = 2;951 \\ ptr[1] = 2;
...@@ -957,7 +973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -957,7 +973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
957 "tmp.zig:19:13: error: cannot assign to constant",973 "tmp.zig:19:13: error: cannot assign to constant",
958 });974 });
959975
960 cases.addTest("cast between ?T where T is not a pointer",976 ctx.testErrStage1("cast between ?T where T is not a pointer",
961 \\pub const fnty1 = ?fn (i8) void;977 \\pub const fnty1 = ?fn (i8) void;
962 \\pub const fnty2 = ?fn (u64) void;978 \\pub const fnty2 = ?fn (u64) void;
963 \\export fn entry() void {979 \\export fn entry() void {
...@@ -970,7 +986,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -970,7 +986,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
970 "tmp.zig:6:9: note: optional type child 'fn(u64) void' cannot cast into optional type child 'fn(i8) void'",986 "tmp.zig:6:9: note: optional type child 'fn(u64) void' cannot cast into optional type child 'fn(i8) void'",
971 });987 });
972988
973 cases.addTest("unused variable error on errdefer",989 ctx.testErrStage1("unused variable error on errdefer",
974 \\fn foo() !void {990 \\fn foo() !void {
975 \\ errdefer |a| unreachable;991 \\ errdefer |a| unreachable;
976 \\ return error.A;992 \\ return error.A;
...@@ -982,18 +998,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -982,18 +998,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
982 "tmp.zig:2:15: error: unused variable: 'a'",998 "tmp.zig:2:15: error: unused variable: 'a'",
983 });999 });
9841000
985 cases.addTest("comparison of non-tagged union and enum literal",1001 ctx.testErrStage1("comparison of non-tagged union and enum literal",
986 \\export fn entry() void {1002 \\export fn entry() void {
987 \\ const U = union { A: u32, B: u64 };1003 \\ const U = union { A: u32, B: u64 };
988 \\ var u = U{ .A = 42 };1004 \\ var u = U{ .A = 42 };
989 \\ var ok = u == .A;1005 \\ var ok = u == .A;
1006 \\ _ = ok;
990 \\}1007 \\}
991 , &[_][]const u8{1008 , &[_][]const u8{
992 "tmp.zig:4:16: error: comparison of union and enum literal is only valid for tagged union types",1009 "tmp.zig:4:16: error: comparison of union and enum literal is only valid for tagged union types",
993 "tmp.zig:2:15: note: type U is not a tagged union",1010 "tmp.zig:2:15: note: type U is not a tagged union",
994 });1011 });
9951012
996 cases.addTest("shift on type with non-power-of-two size",1013 ctx.testErrStage1("shift on type with non-power-of-two size",
997 \\export fn entry() void {1014 \\export fn entry() void {
998 \\ const S = struct {1015 \\ const S = struct {
999 \\ fn a() void {1016 \\ fn a() void {
...@@ -1025,7 +1042,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1025,7 +1042,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1025 "tmp.zig:17:17: error: RHS of shift is too large for LHS type",1042 "tmp.zig:17:17: error: RHS of shift is too large for LHS type",
1026 });1043 });
10271044
1028 cases.addTest("combination of nosuspend and async",1045 ctx.testErrStage1("combination of nosuspend and async",
1029 \\export fn entry() void {1046 \\export fn entry() void {
1030 \\ nosuspend {1047 \\ nosuspend {
1031 \\ const bar = async foo();1048 \\ const bar = async foo();
...@@ -1035,10 +1052,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1035,10 +1052,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1035 \\}1052 \\}
1036 \\fn foo() void {}1053 \\fn foo() void {}
1037 , &[_][]const u8{1054 , &[_][]const u8{
1038 "tmp.zig:4:9: error: suspend in nosuspend scope",1055 "tmp.zig:4:9: error: suspend inside nosuspend block",
1056 "tmp.zig:2:5: note: nosuspend block here",
1039 });1057 });
10401058
1041 cases.add("atomicrmw with bool op not .Xchg",1059 ctx.objErrStage1("atomicrmw with bool op not .Xchg",
1042 \\export fn entry() void {1060 \\export fn entry() void {
1043 \\ var x = false;1061 \\ var x = false;
1044 \\ _ = @atomicRmw(bool, &x, .Add, true, .SeqCst);1062 \\ _ = @atomicRmw(bool, &x, .Add, true, .SeqCst);
...@@ -1047,7 +1065,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1047,7 +1065,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1047 "tmp.zig:3:30: error: @atomicRmw with bool only allowed with .Xchg",1065 "tmp.zig:3:30: error: @atomicRmw with bool only allowed with .Xchg",
1048 });1066 });
10491067
1050 cases.addTest("@TypeOf with no arguments",1068 ctx.testErrStage1("@TypeOf with no arguments",
1051 \\export fn entry() void {1069 \\export fn entry() void {
1052 \\ _ = @TypeOf();1070 \\ _ = @TypeOf();
1053 \\}1071 \\}
...@@ -1055,7 +1073,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1055,7 +1073,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1055 "tmp.zig:2:9: error: expected at least 1 argument, found 0",1073 "tmp.zig:2:9: error: expected at least 1 argument, found 0",
1056 });1074 });
10571075
1058 cases.addTest("@TypeOf with incompatible arguments",1076 ctx.testErrStage1("@TypeOf with incompatible arguments",
1059 \\export fn entry() void {1077 \\export fn entry() void {
1060 \\ var var_1: f32 = undefined;1078 \\ var var_1: f32 = undefined;
1061 \\ var var_2: u32 = undefined;1079 \\ var var_2: u32 = undefined;
...@@ -1065,7 +1083,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1065,7 +1083,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1065 "tmp.zig:4:9: error: incompatible types: 'f32' and 'u32'",1083 "tmp.zig:4:9: error: incompatible types: 'f32' and 'u32'",
1066 });1084 });
10671085
1068 cases.addTest("type mismatch with tuple concatenation",1086 ctx.testErrStage1("type mismatch with tuple concatenation",
1069 \\export fn entry() void {1087 \\export fn entry() void {
1070 \\ var x = .{};1088 \\ var x = .{};
1071 \\ x = x ++ .{ 1, 2, 3 };1089 \\ x = x ++ .{ 1, 2, 3 };
...@@ -1074,7 +1092,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1074,7 +1092,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1074 "tmp.zig:3:11: error: expected type 'struct:2:14', found 'struct:3:11'",1092 "tmp.zig:3:11: error: expected type 'struct:2:14', found 'struct:3:11'",
1075 });1093 });
10761094
1077 cases.addTest("@tagName on invalid value of non-exhaustive enum",1095 ctx.testErrStage1("@tagName on invalid value of non-exhaustive enum",
1078 \\test "enum" {1096 \\test "enum" {
1079 \\ const E = enum(u8) {A, B, _};1097 \\ const E = enum(u8) {A, B, _};
1080 \\ _ = @tagName(@intToEnum(E, 5));1098 \\ _ = @tagName(@intToEnum(E, 5));
...@@ -1083,16 +1101,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1083,16 +1101,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1083 "tmp.zig:3:18: error: no tag by value 5",1101 "tmp.zig:3:18: error: no tag by value 5",
1084 });1102 });
10851103
1086 cases.addTest("@ptrToInt with pointer to zero-sized type",1104 ctx.testErrStage1("@ptrToInt with pointer to zero-sized type",
1087 \\export fn entry() void {1105 \\export fn entry() void {
1088 \\ var pointer: ?*u0 = null;1106 \\ var pointer: ?*u0 = null;
1089 \\ var x = @ptrToInt(pointer);1107 \\ var x = @ptrToInt(pointer);
1108 \\ _ = x;
1090 \\}1109 \\}
1091 , &[_][]const u8{1110 , &[_][]const u8{
1092 "tmp.zig:3:23: error: pointer to size 0 type has no address",1111 "tmp.zig:3:23: error: pointer to size 0 type has no address",
1093 });1112 });
10941113
1095 cases.addTest("access invalid @typeInfo decl",1114 ctx.testErrStage1("access invalid @typeInfo decl",
1096 \\const A = B;1115 \\const A = B;
1097 \\test "Crash" {1116 \\test "Crash" {
1098 \\ _ = @typeInfo(@This()).Struct.decls[0];1117 \\ _ = @typeInfo(@This()).Struct.decls[0];
...@@ -1101,7 +1120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1101,7 +1120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1101 "tmp.zig:1:11: error: use of undeclared identifier 'B'",1120 "tmp.zig:1:11: error: use of undeclared identifier 'B'",
1102 });1121 });
11031122
1104 cases.addTest("reject extern function definitions with body",1123 ctx.testErrStage1("reject extern function definitions with body",
1105 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 {1124 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 {
1106 \\ return a + b;1125 \\ return a + b;
1107 \\}1126 \\}
...@@ -1109,7 +1128,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1109,7 +1128,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1109 "tmp.zig:1:1: error: extern functions have no body",1128 "tmp.zig:1:1: error: extern functions have no body",
1110 });1129 });
11111130
1112 cases.addTest("duplicate field in anonymous struct literal",1131 ctx.testErrStage1("duplicate field in anonymous struct literal",
1113 \\export fn entry() void {1132 \\export fn entry() void {
1114 \\ const anon = .{1133 \\ const anon = .{
1115 \\ .inner = .{1134 \\ .inner = .{
...@@ -1119,31 +1138,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1119,31 +1138,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1119 \\ .a = .{},1138 \\ .a = .{},
1120 \\ },1139 \\ },
1121 \\ };1140 \\ };
1141 \\ _ = anon;
1122 \\}1142 \\}
1123 , &[_][]const u8{1143 , &[_][]const u8{
1124 "tmp.zig:7:13: error: duplicate field",1144 "tmp.zig:7:13: error: duplicate field",
1125 "tmp.zig:4:13: note: other field here",1145 "tmp.zig:4:13: note: other field here",
1126 });1146 });
11271147
1128 cases.addTest("type mismatch in C prototype with varargs",1148 ctx.testErrStage1("type mismatch in C prototype with varargs",
1129 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;1149 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;
1130 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;1150 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;
1131 \\1151 \\
1132 \\export fn main() void {1152 \\export fn main() void {
1133 \\ const x: fn_ty = fn_decl;1153 \\ const x: fn_ty = fn_decl;
1154 \\ _ = x;
1134 \\}1155 \\}
1135 , &[_][]const u8{1156 , &[_][]const u8{
1136 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",1157 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
1137 });1158 });
11381159
1139 cases.addTest("dependency loop in top-level decl with @TypeInfo when accessing the decls",1160 ctx.testErrStage1("dependency loop in top-level decl with @TypeInfo when accessing the decls",
1140 \\export const foo = @typeInfo(@This()).Struct.decls;1161 \\export const foo = @typeInfo(@This()).Struct.decls;
1141 , &[_][]const u8{1162 , &[_][]const u8{
1142 "tmp.zig:1:20: error: dependency loop detected",1163 "tmp.zig:1:20: error: dependency loop detected",
1143 "tmp.zig:1:45: note: referenced here",1164 "tmp.zig:1:45: note: referenced here",
1144 });1165 });
11451166
1146 cases.add("function call assigned to incorrect type",1167 ctx.objErrStage1("function call assigned to incorrect type",
1147 \\export fn entry() void {1168 \\export fn entry() void {
1148 \\ var arr: [4]f32 = undefined;1169 \\ var arr: [4]f32 = undefined;
1149 \\ arr = concat();1170 \\ arr = concat();
...@@ -1155,7 +1176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1155,7 +1176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1155 "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'",1176 "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'",
1156 });1177 });
11571178
1158 cases.add("generic function call assigned to incorrect type",1179 ctx.objErrStage1("generic function call assigned to incorrect type",
1159 \\pub export fn entry() void {1180 \\pub export fn entry() void {
1160 \\ var res: []i32 = undefined;1181 \\ var res: []i32 = undefined;
1161 \\ res = myAlloc(i32);1182 \\ res = myAlloc(i32);
...@@ -1167,12 +1188,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1167,12 +1188,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1167 "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32",1188 "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32",
1168 });1189 });
11691190
1170 cases.addTest("non-exhaustive enums",1191 ctx.testErrStage1("non-exhaustive enum marker assigned a value",
1171 \\const A = enum {1192 \\const A = enum {
1172 \\ a,1193 \\ a,
1173 \\ b,1194 \\ b,
1174 \\ _ = 1,1195 \\ _ = 1,
1175 \\};1196 \\};
1197 \\const B = enum {
1198 \\ a,
1199 \\ b,
1200 \\ _,
1201 \\};
1202 \\comptime { _ = A; _ = B; }
1203 , &[_][]const u8{
1204 "tmp.zig:4:9: error: '_' is used to mark an enum as non-exhaustive and cannot be assigned a value",
1205 "tmp.zig:6:11: error: non-exhaustive enum missing integer tag type",
1206 "tmp.zig:9:5: note: marked non-exhaustive here",
1207 });
1208
1209 ctx.testErrStage1("non-exhaustive enums",
1176 \\const B = enum(u1) {1210 \\const B = enum(u1) {
1177 \\ a,1211 \\ a,
1178 \\ _,1212 \\ _,
...@@ -1184,18 +1218,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1184,18 +1218,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1184 \\ _,1218 \\ _,
1185 \\};1219 \\};
1186 \\pub export fn entry() void {1220 \\pub export fn entry() void {
1187 \\ _ = A;
1188 \\ _ = B;1221 \\ _ = B;
1189 \\ _ = C;1222 \\ _ = C;
1190 \\}1223 \\}
1191 , &[_][]const u8{1224 , &[_][]const u8{
1192 "tmp.zig:4:5: error: value assigned to '_' field of non-exhaustive enum",1225 "tmp.zig:3:5: error: '_' field of non-exhaustive enum must be last",
1193 "error: non-exhaustive enum must specify size",1226 "tmp.zig:6:11: error: non-exhaustive enum specifies every value",
1194 "error: non-exhaustive enum specifies every value",
1195 "error: '_' field of non-exhaustive enum must be last",
1196 });1227 });
11971228
1198 cases.addTest("switching with non-exhaustive enums",1229 ctx.testErrStage1("switching with non-exhaustive enums",
1199 \\const E = enum(u8) {1230 \\const E = enum(u8) {
1200 \\ a,1231 \\ a,
1201 \\ b,1232 \\ b,
...@@ -1228,7 +1259,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1228,7 +1259,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1228 "tmp.zig:21:5: error: `_` prong not allowed when switching on tagged union",1259 "tmp.zig:21:5: error: `_` prong not allowed when switching on tagged union",
1229 });1260 });
12301261
1231 cases.add("switch expression - unreachable else prong (bool)",1262 ctx.objErrStage1("switch expression - unreachable else prong (bool)",
1232 \\fn foo(x: bool) void {1263 \\fn foo(x: bool) void {
1233 \\ switch (x) {1264 \\ switch (x) {
1234 \\ true => {},1265 \\ true => {},
...@@ -1241,7 +1272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1241,7 +1272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1241 "tmp.zig:5:9: error: unreachable else prong, all cases already handled",1272 "tmp.zig:5:9: error: unreachable else prong, all cases already handled",
1242 });1273 });
12431274
1244 cases.add("switch expression - unreachable else prong (u1)",1275 ctx.objErrStage1("switch expression - unreachable else prong (u1)",
1245 \\fn foo(x: u1) void {1276 \\fn foo(x: u1) void {
1246 \\ switch (x) {1277 \\ switch (x) {
1247 \\ 0 => {},1278 \\ 0 => {},
...@@ -1254,7 +1285,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1254,7 +1285,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1254 "tmp.zig:5:9: error: unreachable else prong, all cases already handled",1285 "tmp.zig:5:9: error: unreachable else prong, all cases already handled",
1255 });1286 });
12561287
1257 cases.add("switch expression - unreachable else prong (u2)",1288 ctx.objErrStage1("switch expression - unreachable else prong (u2)",
1258 \\fn foo(x: u2) void {1289 \\fn foo(x: u2) void {
1259 \\ switch (x) {1290 \\ switch (x) {
1260 \\ 0 => {},1291 \\ 0 => {},
...@@ -1269,7 +1300,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1269,7 +1300,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1269 "tmp.zig:7:9: error: unreachable else prong, all cases already handled",1300 "tmp.zig:7:9: error: unreachable else prong, all cases already handled",
1270 });1301 });
12711302
1272 cases.add("switch expression - unreachable else prong (range u8)",1303 ctx.objErrStage1("switch expression - unreachable else prong (range u8)",
1273 \\fn foo(x: u8) void {1304 \\fn foo(x: u8) void {
1274 \\ switch (x) {1305 \\ switch (x) {
1275 \\ 0 => {},1306 \\ 0 => {},
...@@ -1285,7 +1316,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1285,7 +1316,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1285 "tmp.zig:8:9: error: unreachable else prong, all cases already handled",1316 "tmp.zig:8:9: error: unreachable else prong, all cases already handled",
1286 });1317 });
12871318
1288 cases.add("switch expression - unreachable else prong (range i8)",1319 ctx.objErrStage1("switch expression - unreachable else prong (range i8)",
1289 \\fn foo(x: i8) void {1320 \\fn foo(x: i8) void {
1290 \\ switch (x) {1321 \\ switch (x) {
1291 \\ -128...0 => {},1322 \\ -128...0 => {},
...@@ -1301,7 +1332,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1301,7 +1332,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1301 "tmp.zig:8:9: error: unreachable else prong, all cases already handled",1332 "tmp.zig:8:9: error: unreachable else prong, all cases already handled",
1302 });1333 });
13031334
1304 cases.add("switch expression - unreachable else prong (enum)",1335 ctx.objErrStage1("switch expression - unreachable else prong (enum)",
1305 \\const TestEnum = enum{ T1, T2 };1336 \\const TestEnum = enum{ T1, T2 };
1306 \\1337 \\
1307 \\fn err(x: u8) TestEnum {1338 \\fn err(x: u8) TestEnum {
...@@ -1324,7 +1355,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1324,7 +1355,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1324 "tmp.zig:14:9: error: unreachable else prong, all cases already handled",1355 "tmp.zig:14:9: error: unreachable else prong, all cases already handled",
1325 });1356 });
13261357
1327 cases.addTest("@export with empty name string",1358 ctx.testErrStage1("@export with empty name string",
1328 \\pub export fn entry() void { }1359 \\pub export fn entry() void { }
1329 \\comptime {1360 \\comptime {
1330 \\ @export(entry, .{ .name = "" });1361 \\ @export(entry, .{ .name = "" });
...@@ -1333,7 +1364,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1333,7 +1364,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1333 "tmp.zig:3:5: error: exported symbol name cannot be empty",1364 "tmp.zig:3:5: error: exported symbol name cannot be empty",
1334 });1365 });
13351366
1336 cases.addTest("switch ranges endpoints are validated",1367 ctx.testErrStage1("switch ranges endpoints are validated",
1337 \\pub export fn entry() void {1368 \\pub export fn entry() void {
1338 \\ var x: i32 = 0;1369 \\ var x: i32 = 0;
1339 \\ switch (x) {1370 \\ switch (x) {
...@@ -1347,16 +1378,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1347,16 +1378,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1347 "tmp.zig:5:9: error: range start value is greater than the end value",1378 "tmp.zig:5:9: error: range start value is greater than the end value",
1348 });1379 });
13491380
1350 cases.addTest("errors in for loop bodies are propagated",1381 ctx.testErrStage1("errors in for loop bodies are propagated",
1351 \\pub export fn entry() void {1382 \\pub export fn entry() void {
1352 \\ var arr: [100]u8 = undefined;1383 \\ var arr: [100]u8 = undefined;
1353 \\ for (arr) |bits| _ = @popCount(bits);1384 \\ for (arr) |bits| _ = @popCount(bits);
1354 \\}1385 \\}
1355 , &[_][]const u8{1386 , &[_][]const u8{
1356 "tmp.zig:3:26: error: expected 2 argument(s), found 1",1387 "tmp.zig:3:26: error: expected 2 arguments, found 1",
1357 });1388 });
13581389
1359 cases.addTest("@call rejects non comptime-known fn - always_inline",1390 ctx.testErrStage1("@call rejects non comptime-known fn - always_inline",
1360 \\pub export fn entry() void {1391 \\pub export fn entry() void {
1361 \\ var call_me: fn () void = undefined;1392 \\ var call_me: fn () void = undefined;
1362 \\ @call(.{ .modifier = .always_inline }, call_me, .{});1393 \\ @call(.{ .modifier = .always_inline }, call_me, .{});
...@@ -1365,7 +1396,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1365,7 +1396,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1365 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function",1396 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function",
1366 });1397 });
13671398
1368 cases.addTest("@call rejects non comptime-known fn - compile_time",1399 ctx.testErrStage1("@call rejects non comptime-known fn - compile_time",
1369 \\pub export fn entry() void {1400 \\pub export fn entry() void {
1370 \\ var call_me: fn () void = undefined;1401 \\ var call_me: fn () void = undefined;
1371 \\ @call(.{ .modifier = .compile_time }, call_me, .{});1402 \\ @call(.{ .modifier = .compile_time }, call_me, .{});
...@@ -1374,19 +1405,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1374,19 +1405,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1374 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function",1405 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function",
1375 });1406 });
13761407
1377 cases.addTest("error in struct initializer doesn't crash the compiler",1408 ctx.testErrStage1("error in struct initializer doesn't crash the compiler",
1378 \\pub export fn entry() void {1409 \\pub export fn entry() void {
1379 \\ const bitfield = struct {1410 \\ const bitfield = struct {
1380 \\ e: u8,1411 \\ e: u8,
1381 \\ e: u8,1412 \\ e: u8,
1382 \\ };1413 \\ };
1383 \\ var a = .{@sizeOf(bitfield)};1414 \\ var a = .{@sizeOf(bitfield)};
1415 \\ _ = a;
1384 \\}1416 \\}
1385 , &[_][]const u8{1417 , &[_][]const u8{
1386 "tmp.zig:4:9: error: duplicate struct field: 'e'",1418 "tmp.zig:4:9: error: duplicate struct field: 'e'",
1387 });1419 });
13881420
1389 cases.addTest("repeated invalid field access to generic function returning type crashes compiler. #2655",1421 ctx.testErrStage1("repeated invalid field access to generic function returning type crashes compiler. #2655",
1390 \\pub fn A() type {1422 \\pub fn A() type {
1391 \\ return Q;1423 \\ return Q;
1392 \\}1424 \\}
...@@ -1398,15 +1430,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1398,15 +1430,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1398 "tmp.zig:2:12: error: use of undeclared identifier 'Q'",1430 "tmp.zig:2:12: error: use of undeclared identifier 'Q'",
1399 });1431 });
14001432
1401 cases.add("bitCast to enum type",1433 ctx.objErrStage1("bitCast to enum type",
1402 \\export fn entry() void {1434 \\export fn entry() void {
1403 \\ const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));1435 \\ const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));
1436 \\ _ = y;
1404 \\}1437 \\}
1405 , &[_][]const u8{1438 , &[_][]const u8{
1406 "tmp.zig:2:24: error: cannot cast a value of type 'y'",1439 "tmp.zig:2:24: error: cannot cast a value of type 'y'",
1407 });1440 });
14081441
1409 cases.add("comparing against undefined produces undefined value",1442 ctx.objErrStage1("comparing against undefined produces undefined value",
1410 \\export fn entry() void {1443 \\export fn entry() void {
1411 \\ if (2 == undefined) {}1444 \\ if (2 == undefined) {}
1412 \\}1445 \\}
...@@ -1414,17 +1447,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1414,17 +1447,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1414 "tmp.zig:2:11: error: use of undefined value here causes undefined behavior",1447 "tmp.zig:2:11: error: use of undefined value here causes undefined behavior",
1415 });1448 });
14161449
1417 cases.add("comptime ptrcast of zero-sized type",1450 ctx.objErrStage1("comptime ptrcast of zero-sized type",
1418 \\fn foo() void {1451 \\fn foo() void {
1419 \\ const node: struct {} = undefined;1452 \\ const node: struct {} = undefined;
1420 \\ const vla_ptr = @ptrCast([*]const u8, &node);1453 \\ const vla_ptr = @ptrCast([*]const u8, &node);
1454 \\ _ = vla_ptr;
1421 \\}1455 \\}
1422 \\comptime { foo(); }1456 \\comptime { foo(); }
1423 , &[_][]const u8{1457 , &[_][]const u8{
1424 "tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation",1458 "tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation",
1425 });1459 });
14261460
1427 cases.add("slice sentinel mismatch",1461 ctx.objErrStage1("slice sentinel mismatch",
1428 \\fn foo() [:0]u8 {1462 \\fn foo() [:0]u8 {
1429 \\ var x: []u8 = undefined;1463 \\ var x: []u8 = undefined;
1430 \\ return x;1464 \\ return x;
...@@ -1435,7 +1469,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1435,7 +1469,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1435 "tmp.zig:3:12: note: destination pointer requires a terminating '0' sentinel",1469 "tmp.zig:3:12: note: destination pointer requires a terminating '0' sentinel",
1436 });1470 });
14371471
1438 cases.add("cmpxchg with float",1472 ctx.objErrStage1("cmpxchg with float",
1439 \\export fn entry() void {1473 \\export fn entry() void {
1440 \\ var x: f32 = 0;1474 \\ var x: f32 = 0;
1441 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);1475 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);
...@@ -1444,7 +1478,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1444,7 +1478,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1444 "tmp.zig:3:22: error: expected bool, integer, enum or pointer type, found 'f32'",1478 "tmp.zig:3:22: error: expected bool, integer, enum or pointer type, found 'f32'",
1445 });1479 });
14461480
1447 cases.add("atomicrmw with float op not .Xchg, .Add or .Sub",1481 ctx.objErrStage1("atomicrmw with float op not .Xchg, .Add or .Sub",
1448 \\export fn entry() void {1482 \\export fn entry() void {
1449 \\ var x: f32 = 0;1483 \\ var x: f32 = 0;
1450 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);1484 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);
...@@ -1453,15 +1487,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1453,15 +1487,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1453 "tmp.zig:3:29: error: @atomicRmw with float only allowed with .Xchg, .Add and .Sub",1487 "tmp.zig:3:29: error: @atomicRmw with float only allowed with .Xchg, .Add and .Sub",
1454 });1488 });
14551489
1456 cases.add("intToPtr with misaligned address",1490 ctx.objErrStage1("intToPtr with misaligned address",
1457 \\pub fn main() void {1491 \\pub fn main() void {
1458 \\ var y = @intToPtr([*]align(4) u8, 5);1492 \\ var y = @intToPtr([*]align(4) u8, 5);
1493 \\ _ = y;
1459 \\}1494 \\}
1460 , &[_][]const u8{1495 , &[_][]const u8{
1461 "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address",1496 "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address",
1462 });1497 });
14631498
1464 cases.add("invalid float literal",1499 ctx.objErrStage1("invalid float literal",
1465 \\const std = @import("std");1500 \\const std = @import("std");
1466 \\1501 \\
1467 \\pub fn main() void {1502 \\pub fn main() void {
...@@ -1473,170 +1508,209 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1473,170 +1508,209 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1473 "tmp.zig:5:29: error: invalid token: '.'",1508 "tmp.zig:5:29: error: invalid token: '.'",
1474 });1509 });
14751510
1476 cases.add("invalid exponent in float literal - 1",1511 ctx.objErrStage1("invalid exponent in float literal - 1",
1477 \\fn main() void {1512 \\fn main() void {
1478 \\ var bad: f128 = 0x1.0p1ab1;1513 \\ var bad: f128 = 0x1.0p1ab1;
1514 \\ _ = bad;
1479 \\}1515 \\}
1480 , &[_][]const u8{1516 , &[_][]const u8{
1481 "tmp.zig:2:28: error: invalid character: 'a'",1517 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1518 "tmp.zig:2:28: note: invalid byte: 'a'",
1482 });1519 });
14831520
1484 cases.add("invalid exponent in float literal - 2",1521 ctx.objErrStage1("invalid exponent in float literal - 2",
1485 \\fn main() void {1522 \\fn main() void {
1486 \\ var bad: f128 = 0x1.0p50F;1523 \\ var bad: f128 = 0x1.0p50F;
1524 \\ _ = bad;
1487 \\}1525 \\}
1488 , &[_][]const u8{1526 , &[_][]const u8{
1489 "tmp.zig:2:29: error: invalid character: 'F'",1527 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1528 "tmp.zig:2:29: note: invalid byte: 'F'",
1490 });1529 });
14911530
1492 cases.add("invalid underscore placement in float literal - 1",1531 ctx.objErrStage1("invalid underscore placement in float literal - 1",
1493 \\fn main() void {1532 \\fn main() void {
1494 \\ var bad: f128 = 0._0;1533 \\ var bad: f128 = 0._0;
1534 \\ _ = bad;
1495 \\}1535 \\}
1496 , &[_][]const u8{1536 , &[_][]const u8{
1497 "tmp.zig:2:23: error: invalid character: '_'",1537 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1538 "tmp.zig:2:23: note: invalid byte: '_'",
1498 });1539 });
14991540
1500 cases.add("invalid underscore placement in float literal - 2",1541 ctx.objErrStage1("invalid underscore placement in float literal - 2",
1501 \\fn main() void {1542 \\fn main() void {
1502 \\ var bad: f128 = 0_.0;1543 \\ var bad: f128 = 0_.0;
1544 \\ _ = bad;
1503 \\}1545 \\}
1504 , &[_][]const u8{1546 , &[_][]const u8{
1505 "tmp.zig:2:23: error: invalid character: '.'",1547 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1548 "tmp.zig:2:23: note: invalid byte: '.'",
1506 });1549 });
15071550
1508 cases.add("invalid underscore placement in float literal - 3",1551 ctx.objErrStage1("invalid underscore placement in float literal - 3",
1509 \\fn main() void {1552 \\fn main() void {
1510 \\ var bad: f128 = 0.0_;1553 \\ var bad: f128 = 0.0_;
1554 \\ _ = bad;
1511 \\}1555 \\}
1512 , &[_][]const u8{1556 , &[_][]const u8{
1513 "tmp.zig:2:25: error: invalid character: ';'",1557 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1558 "tmp.zig:2:25: note: invalid byte: ';'",
1514 });1559 });
15151560
1516 cases.add("invalid underscore placement in float literal - 4",1561 ctx.objErrStage1("invalid underscore placement in float literal - 4",
1517 \\fn main() void {1562 \\fn main() void {
1518 \\ var bad: f128 = 1.0e_1;1563 \\ var bad: f128 = 1.0e_1;
1564 \\ _ = bad;
1519 \\}1565 \\}
1520 , &[_][]const u8{1566 , &[_][]const u8{
1521 "tmp.zig:2:25: error: invalid character: '_'",1567 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1568 "tmp.zig:2:25: note: invalid byte: '_'",
1522 });1569 });
15231570
1524 cases.add("invalid underscore placement in float literal - 5",1571 ctx.objErrStage1("invalid underscore placement in float literal - 5",
1525 \\fn main() void {1572 \\fn main() void {
1526 \\ var bad: f128 = 1.0e+_1;1573 \\ var bad: f128 = 1.0e+_1;
1574 \\ _ = bad;
1527 \\}1575 \\}
1528 , &[_][]const u8{1576 , &[_][]const u8{
1529 "tmp.zig:2:26: error: invalid character: '_'",1577 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1578 "tmp.zig:2:26: note: invalid byte: '_'",
1530 });1579 });
15311580
1532 cases.add("invalid underscore placement in float literal - 6",1581 ctx.objErrStage1("invalid underscore placement in float literal - 6",
1533 \\fn main() void {1582 \\fn main() void {
1534 \\ var bad: f128 = 1.0e-_1;1583 \\ var bad: f128 = 1.0e-_1;
1584 \\ _ = bad;
1535 \\}1585 \\}
1536 , &[_][]const u8{1586 , &[_][]const u8{
1537 "tmp.zig:2:26: error: invalid character: '_'",1587 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1588 "tmp.zig:2:26: note: invalid byte: '_'",
1538 });1589 });
15391590
1540 cases.add("invalid underscore placement in float literal - 7",1591 ctx.objErrStage1("invalid underscore placement in float literal - 7",
1541 \\fn main() void {1592 \\fn main() void {
1542 \\ var bad: f128 = 1.0e-1_;1593 \\ var bad: f128 = 1.0e-1_;
1594 \\ _ = bad;
1543 \\}1595 \\}
1544 , &[_][]const u8{1596 , &[_][]const u8{
1545 "tmp.zig:2:28: error: invalid character: ';'",1597 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1598 "tmp.zig:2:28: note: invalid byte: ';'",
1546 });1599 });
15471600
1548 cases.add("invalid underscore placement in float literal - 9",1601 ctx.objErrStage1("invalid underscore placement in float literal - 9",
1549 \\fn main() void {1602 \\fn main() void {
1550 \\ var bad: f128 = 1__0.0e-1;1603 \\ var bad: f128 = 1__0.0e-1;
1604 \\ _ = bad;
1551 \\}1605 \\}
1552 , &[_][]const u8{1606 , &[_][]const u8{
1553 "tmp.zig:2:23: error: invalid character: '_'",1607 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1608 "tmp.zig:2:23: note: invalid byte: '_'",
1554 });1609 });
15551610
1556 cases.add("invalid underscore placement in float literal - 10",1611 ctx.objErrStage1("invalid underscore placement in float literal - 10",
1557 \\fn main() void {1612 \\fn main() void {
1558 \\ var bad: f128 = 1.0__0e-1;1613 \\ var bad: f128 = 1.0__0e-1;
1614 \\ _ = bad;
1559 \\}1615 \\}
1560 , &[_][]const u8{1616 , &[_][]const u8{
1561 "tmp.zig:2:25: error: invalid character: '_'",1617 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1618 "tmp.zig:2:25: note: invalid byte: '_'",
1562 });1619 });
15631620
1564 cases.add("invalid underscore placement in float literal - 11",1621 ctx.objErrStage1("invalid underscore placement in float literal - 11",
1565 \\fn main() void {1622 \\fn main() void {
1566 \\ var bad: f128 = 1.0e-1__0;1623 \\ var bad: f128 = 1.0e-1__0;
1624 \\ _ = bad;
1567 \\}1625 \\}
1568 , &[_][]const u8{1626 , &[_][]const u8{
1569 "tmp.zig:2:28: error: invalid character: '_'",1627 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1628 "tmp.zig:2:28: note: invalid byte: '_'",
1570 });1629 });
15711630
1572 cases.add("invalid underscore placement in float literal - 12",1631 ctx.objErrStage1("invalid underscore placement in float literal - 12",
1573 \\fn main() void {1632 \\fn main() void {
1574 \\ var bad: f128 = 0_x0.0;1633 \\ var bad: f128 = 0_x0.0;
1634 \\ _ = bad;
1575 \\}1635 \\}
1576 , &[_][]const u8{1636 , &[_][]const u8{
1577 "tmp.zig:2:23: error: invalid character: 'x'",1637 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1638 "tmp.zig:2:23: note: invalid byte: 'x'",
1578 });1639 });
15791640
1580 cases.add("invalid underscore placement in float literal - 13",1641 ctx.objErrStage1("invalid underscore placement in float literal - 13",
1581 \\fn main() void {1642 \\fn main() void {
1582 \\ var bad: f128 = 0x_0.0;1643 \\ var bad: f128 = 0x_0.0;
1644 \\ _ = bad;
1583 \\}1645 \\}
1584 , &[_][]const u8{1646 , &[_][]const u8{
1585 "tmp.zig:2:23: error: invalid character: '_'",1647 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1648 "tmp.zig:2:23: note: invalid byte: '_'",
1586 });1649 });
15871650
1588 cases.add("invalid underscore placement in float literal - 14",1651 ctx.objErrStage1("invalid underscore placement in float literal - 14",
1589 \\fn main() void {1652 \\fn main() void {
1590 \\ var bad: f128 = 0x0.0_p1;1653 \\ var bad: f128 = 0x0.0_p1;
1654 \\ _ = bad;
1591 \\}1655 \\}
1592 , &[_][]const u8{1656 , &[_][]const u8{
1593 "tmp.zig:2:27: error: invalid character: 'p'",1657 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1658 "tmp.zig:2:27: note: invalid byte: 'p'",
1594 });1659 });
15951660
1596 cases.add("invalid underscore placement in int literal - 1",1661 ctx.objErrStage1("invalid underscore placement in int literal - 1",
1597 \\fn main() void {1662 \\fn main() void {
1598 \\ var bad: u128 = 0010_;1663 \\ var bad: u128 = 0010_;
1664 \\ _ = bad;
1599 \\}1665 \\}
1600 , &[_][]const u8{1666 , &[_][]const u8{
1601 "tmp.zig:2:26: error: invalid character: ';'",1667 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1668 "tmp.zig:2:26: note: invalid byte: ';'",
1602 });1669 });
16031670
1604 cases.add("invalid underscore placement in int literal - 2",1671 ctx.objErrStage1("invalid underscore placement in int literal - 2",
1605 \\fn main() void {1672 \\fn main() void {
1606 \\ var bad: u128 = 0b0010_;1673 \\ var bad: u128 = 0b0010_;
1674 \\ _ = bad;
1607 \\}1675 \\}
1608 , &[_][]const u8{1676 , &[_][]const u8{
1609 "tmp.zig:2:28: error: invalid character: ';'",1677 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1678 "tmp.zig:2:28: note: invalid byte: ';'",
1610 });1679 });
16111680
1612 cases.add("invalid underscore placement in int literal - 3",1681 ctx.objErrStage1("invalid underscore placement in int literal - 3",
1613 \\fn main() void {1682 \\fn main() void {
1614 \\ var bad: u128 = 0o0010_;1683 \\ var bad: u128 = 0o0010_;
1684 \\ _ = bad;
1615 \\}1685 \\}
1616 , &[_][]const u8{1686 , &[_][]const u8{
1617 "tmp.zig:2:28: error: invalid character: ';'",1687 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1688 "tmp.zig:2:28: note: invalid byte: ';'",
1618 });1689 });
16191690
1620 cases.add("invalid underscore placement in int literal - 4",1691 ctx.objErrStage1("invalid underscore placement in int literal - 4",
1621 \\fn main() void {1692 \\fn main() void {
1622 \\ var bad: u128 = 0x0010_;1693 \\ var bad: u128 = 0x0010_;
1694 \\ _ = bad;
1623 \\}1695 \\}
1624 , &[_][]const u8{1696 , &[_][]const u8{
1625 "tmp.zig:2:28: error: invalid character: ';'",1697 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1698 "tmp.zig:2:28: note: invalid byte: ';'",
1626 });1699 });
16271700
1628 cases.add("comptime struct field, no init value",1701 ctx.objErrStage1("comptime struct field, no init value",
1629 \\const Foo = struct {1702 \\const Foo = struct {
1630 \\ comptime b: i32,1703 \\ comptime b: i32,
1631 \\};1704 \\};
1632 \\export fn entry() void {1705 \\export fn entry() void {
1633 \\ var f: Foo = undefined;1706 \\ var f: Foo = undefined;
1707 \\ _ = f;
1634 \\}1708 \\}
1635 , &[_][]const u8{1709 , &[_][]const u8{
1636 "tmp.zig:2:5: error: comptime struct field missing initialization value",1710 "tmp.zig:2:5: error: comptime field without default initialization value",
1637 });1711 });
16381712
1639 cases.add("bad usage of @call",1713 ctx.objErrStage1("bad usage of @call",
1640 \\export fn entry1() void {1714 \\export fn entry1() void {
1641 \\ @call(.{}, foo, {});1715 \\ @call(.{}, foo, {});
1642 \\}1716 \\}
...@@ -1665,20 +1739,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1665,20 +1739,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1665 "tmp.zig:15:5: error: the specified modifier requires a comptime-known function",1739 "tmp.zig:15:5: error: the specified modifier requires a comptime-known function",
1666 });1740 });
16671741
1668 cases.add("exported async function",1742 ctx.objErrStage1("exported async function",
1669 \\export fn foo() callconv(.Async) void {}1743 \\export fn foo() callconv(.Async) void {}
1670 , &[_][]const u8{1744 , &[_][]const u8{
1671 "tmp.zig:1:1: error: exported function cannot be async",1745 "tmp.zig:1:1: error: exported function cannot be async",
1672 });1746 });
16731747
1674 cases.addExe("main missing name",1748 ctx.exeErrStage1("main missing name",
1675 \\pub fn (main) void {}1749 \\pub fn (main) void {}
1676 , &[_][]const u8{1750 , &[_][]const u8{
1677 "tmp.zig:1:5: error: missing function name",1751 "tmp.zig:1:5: error: missing function name",
1678 });1752 });
16791753
1680 cases.addCase(x: {1754 {
1681 var tc = cases.create("call with new stack on unsupported target",1755 const case = ctx.obj("call with new stack on unsupported target", .{
1756 .cpu_arch = .wasm32,
1757 .os_tag = .wasi,
1758 .abi = .none,
1759 });
1760 case.backend = .stage1;
1761 case.addError(
1682 \\var buf: [10]u8 align(16) = undefined;1762 \\var buf: [10]u8 align(16) = undefined;
1683 \\export fn entry() void {1763 \\export fn entry() void {
1684 \\ @call(.{.stack = &buf}, foo, .{});1764 \\ @call(.{.stack = &buf}, foo, .{});
...@@ -1687,17 +1767,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1687,17 +1767,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1687 , &[_][]const u8{1767 , &[_][]const u8{
1688 "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack",1768 "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack",
1689 });1769 });
1690 tc.target = std.zig.CrossTarget{1770 }
1691 .cpu_arch = .wasm32,
1692 .os_tag = .wasi,
1693 .abi = .none,
1694 };
1695 break :x tc;
1696 });
16971771
1698 // Note: One of the error messages here is backwards. It would be nice to fix, but that's not1772 // Note: One of the error messages here is backwards. It would be nice to fix, but that's not
1699 // going to stop me from merging this branch which fixes a bunch of other stuff.1773 // going to stop me from merging this branch which fixes a bunch of other stuff.
1700 cases.add("incompatible sentinels",1774 ctx.objErrStage1("incompatible sentinels",
1701 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {1775 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
1702 \\ return ptr;1776 \\ return ptr;
1703 \\}1777 \\}
...@@ -1706,9 +1780,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1706,9 +1780,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1706 \\}1780 \\}
1707 \\export fn entry3() void {1781 \\export fn entry3() void {
1708 \\ var array: [2:0]u8 = [_:255]u8{1, 2};1782 \\ var array: [2:0]u8 = [_:255]u8{1, 2};
1783 \\ _ = array;
1709 \\}1784 \\}
1710 \\export fn entry4() void {1785 \\export fn entry4() void {
1711 \\ var array: [2:0]u8 = [_]u8{1, 2};1786 \\ var array: [2:0]u8 = [_]u8{1, 2};
1787 \\ _ = array;
1712 \\}1788 \\}
1713 , &[_][]const u8{1789 , &[_][]const u8{
1714 "tmp.zig:2:12: error: expected type '[*:0]u8', found '[*:255]u8'",1790 "tmp.zig:2:12: error: expected type '[*:0]u8', found '[*:255]u8'",
...@@ -1718,11 +1794,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1718,11 +1794,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17181794
1719 "tmp.zig:8:35: error: expected type '[2:255]u8', found '[2:0]u8'",1795 "tmp.zig:8:35: error: expected type '[2:255]u8', found '[2:0]u8'",
1720 "tmp.zig:8:35: note: destination array requires a terminating '255' sentinel, but source array has a terminating '0' sentinel",1796 "tmp.zig:8:35: note: destination array requires a terminating '255' sentinel, but source array has a terminating '0' sentinel",
1721 "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'",1797 "tmp.zig:12:31: error: expected type '[2:0]u8', found '[2]u8'",
1722 "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",1798 "tmp.zig:12:31: note: destination array requires a terminating '0' sentinel",
1723 });1799 });
17241800
1725 cases.add("empty switch on an integer",1801 ctx.objErrStage1("empty switch on an integer",
1726 \\export fn entry() void {1802 \\export fn entry() void {
1727 \\ var x: u32 = 0;1803 \\ var x: u32 = 0;
1728 \\ switch(x) {}1804 \\ switch(x) {}
...@@ -1731,7 +1807,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1731,7 +1807,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1731 "tmp.zig:3:5: error: switch must handle all possibilities",1807 "tmp.zig:3:5: error: switch must handle all possibilities",
1732 });1808 });
17331809
1734 cases.add("incorrect return type",1810 ctx.objErrStage1("incorrect return type",
1735 \\ pub export fn entry() void{1811 \\ pub export fn entry() void{
1736 \\ _ = foo();1812 \\ _ = foo();
1737 \\ }1813 \\ }
...@@ -1751,12 +1827,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1751,12 +1827,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1751 "tmp.zig:8:16: error: expected type 'A', found 'B'",1827 "tmp.zig:8:16: error: expected type 'A', found 'B'",
1752 });1828 });
17531829
1754 cases.add("regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",1830 ctx.objErrStage1("regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
1755 \\const Foo = struct {1831 \\const Foo = struct {
1756 \\ ptr: ?*usize,1832 \\ ptr: ?*usize,
1757 \\ uval: u32,1833 \\ uval: u32,
1758 \\};1834 \\};
1759 \\fn get_uval(x: u32) !u32 {1835 \\fn get_uval(x: u32) !u32 {
1836 \\ _ = x;
1760 \\ return error.NotFound;1837 \\ return error.NotFound;
1761 \\}1838 \\}
1762 \\export fn entry() void {1839 \\export fn entry() void {
...@@ -1764,12 +1841,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1764,12 +1841,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1764 \\ .ptr = null,1841 \\ .ptr = null,
1765 \\ .uval = get_uval(42),1842 \\ .uval = get_uval(42),
1766 \\ };1843 \\ };
1844 \\ _ = afoo;
1767 \\}1845 \\}
1768 , &[_][]const u8{1846 , &[_][]const u8{
1769 "tmp.zig:11:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'",1847 "tmp.zig:12:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'",
1770 });1848 });
17711849
1772 cases.add("assigning to struct or union fields that are not optionals with a function that returns an optional",1850 ctx.objErrStage1("assigning to struct or union fields that are not optionals with a function that returns an optional",
1773 \\fn maybe(is: bool) ?u8 {1851 \\fn maybe(is: bool) ?u8 {
1774 \\ if (is) return @as(u8, 10) else return null;1852 \\ if (is) return @as(u8, 10) else return null;
1775 \\}1853 \\}
...@@ -1782,12 +1860,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1782,12 +1860,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1782 \\export fn entry() void {1860 \\export fn entry() void {
1783 \\ var u = U{ .Ye = maybe(false) };1861 \\ var u = U{ .Ye = maybe(false) };
1784 \\ var s = S{ .num = maybe(false) };1862 \\ var s = S{ .num = maybe(false) };
1863 \\ _ = u;
1864 \\ _ = s;
1785 \\}1865 \\}
1786 , &[_][]const u8{1866 , &[_][]const u8{
1787 "tmp.zig:11:27: error: expected type 'u8', found '?u8'",1867 "tmp.zig:11:27: error: expected type 'u8', found '?u8'",
1788 });1868 });
17891869
1790 cases.add("missing result type for phi node",1870 ctx.objErrStage1("missing result type for phi node",
1791 \\fn foo() !void {1871 \\fn foo() !void {
1792 \\ return anyerror.Foo;1872 \\ return anyerror.Foo;
1793 \\}1873 \\}
...@@ -1798,7 +1878,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1798,7 +1878,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1798 "tmp.zig:5:17: error: integer value 0 cannot be coerced to type 'void'",1878 "tmp.zig:5:17: error: integer value 0 cannot be coerced to type 'void'",
1799 });1879 });
18001880
1801 cases.add("atomicrmw with enum op not .Xchg",1881 ctx.objErrStage1("atomicrmw with enum op not .Xchg",
1802 \\export fn entry() void {1882 \\export fn entry() void {
1803 \\ const E = enum(u8) {1883 \\ const E = enum(u8) {
1804 \\ a,1884 \\ a,
...@@ -1813,7 +1893,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1813,7 +1893,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1813 "tmp.zig:9:27: error: @atomicRmw with enum only allowed with .Xchg",1893 "tmp.zig:9:27: error: @atomicRmw with enum only allowed with .Xchg",
1814 });1894 });
18151895
1816 cases.add("disallow coercion from non-null-terminated pointer to null-terminated pointer",1896 ctx.objErrStage1("disallow coercion from non-null-terminated pointer to null-terminated pointer",
1817 \\extern fn puts(s: [*:0]const u8) c_int;1897 \\extern fn puts(s: [*:0]const u8) c_int;
1818 \\pub fn main() void {1898 \\pub fn main() void {
1819 \\ const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};1899 \\ const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};
...@@ -1824,7 +1904,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1824,7 +1904,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1824 "tmp.zig:5:14: error: expected type '[*:0]const u8', found '[*]const u8'",1904 "tmp.zig:5:14: error: expected type '[*:0]const u8', found '[*]const u8'",
1825 });1905 });
18261906
1827 cases.add("atomic orderings of atomicStore Acquire or AcqRel",1907 ctx.objErrStage1("atomic orderings of atomicStore Acquire or AcqRel",
1828 \\export fn entry() void {1908 \\export fn entry() void {
1829 \\ var x: u32 = 0;1909 \\ var x: u32 = 0;
1830 \\ @atomicStore(u32, &x, 1, .Acquire);1910 \\ @atomicStore(u32, &x, 1, .Acquire);
...@@ -1833,7 +1913,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1833,7 +1913,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1833 "tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel",1913 "tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel",
1834 });1914 });
18351915
1836 cases.add("missing const in slice with nested array type",1916 ctx.objErrStage1("missing const in slice with nested array type",
1837 \\const Geo3DTex2D = struct { vertices: [][2]f32 };1917 \\const Geo3DTex2D = struct { vertices: [][2]f32 };
1838 \\pub fn getGeo3DTex2D() Geo3DTex2D {1918 \\pub fn getGeo3DTex2D() Geo3DTex2D {
1839 \\ return Geo3DTex2D{1919 \\ return Geo3DTex2D{
...@@ -1844,12 +1924,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1844,12 +1924,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1844 \\}1924 \\}
1845 \\export fn entry() void {1925 \\export fn entry() void {
1846 \\ var geo_data = getGeo3DTex2D();1926 \\ var geo_data = getGeo3DTex2D();
1927 \\ _ = geo_data;
1847 \\}1928 \\}
1848 , &[_][]const u8{1929 , &[_][]const u8{
1849 "tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'",1930 "tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'",
1850 });1931 });
18511932
1852 cases.add("slicing of global undefined pointer",1933 ctx.objErrStage1("slicing of global undefined pointer",
1853 \\var buf: *[1]u8 = undefined;1934 \\var buf: *[1]u8 = undefined;
1854 \\export fn entry() void {1935 \\export fn entry() void {
1855 \\ _ = buf[0..1];1936 \\ _ = buf[0..1];
...@@ -1858,18 +1939,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1858,18 +1939,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1858 "tmp.zig:3:12: error: non-zero length slice of undefined pointer",1939 "tmp.zig:3:12: error: non-zero length slice of undefined pointer",
1859 });1940 });
18601941
1861 cases.add("using invalid types in function call raises an error",1942 ctx.objErrStage1("using invalid types in function call raises an error",
1862 \\const MenuEffect = enum {};1943 \\const MenuEffect = enum {};
1863 \\fn func(effect: MenuEffect) void {}1944 \\fn func(effect: MenuEffect) void { _ = effect; }
1864 \\export fn entry() void {1945 \\export fn entry() void {
1865 \\ func(MenuEffect.ThisDoesNotExist);1946 \\ func(MenuEffect.ThisDoesNotExist);
1866 \\}1947 \\}
1867 , &[_][]const u8{1948 , &[_][]const u8{
1868 "tmp.zig:1:20: error: enums must have 1 or more fields",1949 "tmp.zig:1:20: error: enum declarations must have at least one tag",
1869 "tmp.zig:4:20: note: referenced here",
1870 });1950 });
18711951
1872 cases.add("store vector pointer with unknown runtime index",1952 ctx.objErrStage1("store vector pointer with unknown runtime index",
1873 \\export fn entry() void {1953 \\export fn entry() void {
1874 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };1954 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
1875 \\1955 \\
...@@ -1884,22 +1964,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1884,22 +1964,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1884 "tmp.zig:9:8: error: unable to determine vector element index of type '*align(16:0:4:?) i32",1964 "tmp.zig:9:8: error: unable to determine vector element index of type '*align(16:0:4:?) i32",
1885 });1965 });
18861966
1887 cases.add("load vector pointer with unknown runtime index",1967 ctx.objErrStage1("load vector pointer with unknown runtime index",
1888 \\export fn entry() void {1968 \\export fn entry() void {
1889 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };1969 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
1890 \\1970 \\
1891 \\ var i: u32 = 0;1971 \\ var i: u32 = 0;
1892 \\ var x = loadv(&v[i]);1972 \\ var x = loadv(&v[i]);
1973 \\ _ = x;
1893 \\}1974 \\}
1894 \\1975 \\
1895 \\fn loadv(ptr: anytype) i32 {1976 \\fn loadv(ptr: anytype) i32 {
1896 \\ return ptr.*;1977 \\ return ptr.*;
1897 \\}1978 \\}
1898 , &[_][]const u8{1979 , &[_][]const u8{
1899 "tmp.zig:9:12: error: unable to determine vector element index of type '*align(16:0:4:?) i32",1980 "tmp.zig:10:12: error: unable to determine vector element index of type '*align(16:0:4:?) i32",
1900 });1981 });
19011982
1902 cases.add("using an unknown len ptr type instead of array",1983 ctx.objErrStage1("using an unknown len ptr type instead of array",
1903 \\const resolutions = [*][*]const u8{1984 \\const resolutions = [*][*]const u8{
1904 \\ "[320 240 ]",1985 \\ "[320 240 ]",
1905 \\ null,1986 \\ null,
...@@ -1911,7 +1992,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1911,7 +1992,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1911 "tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'",1992 "tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'",
1912 });1993 });
19131994
1914 cases.add("comparison with error union and error value",1995 ctx.objErrStage1("comparison with error union and error value",
1915 \\export fn entry() void {1996 \\export fn entry() void {
1916 \\ var number_or_error: anyerror!i32 = error.SomethingAwful;1997 \\ var number_or_error: anyerror!i32 = error.SomethingAwful;
1917 \\ _ = number_or_error == error.SomethingAwful;1998 \\ _ = number_or_error == error.SomethingAwful;
...@@ -1920,7 +2001,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1920,7 +2001,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1920 "tmp.zig:3:25: error: operator not allowed for type 'anyerror!i32'",2001 "tmp.zig:3:25: error: operator not allowed for type 'anyerror!i32'",
1921 });2002 });
19222003
1923 cases.add("switch with overlapping case ranges",2004 ctx.objErrStage1("switch with overlapping case ranges",
1924 \\export fn entry() void {2005 \\export fn entry() void {
1925 \\ var q: u8 = 0;2006 \\ var q: u8 = 0;
1926 \\ switch (q) {2007 \\ switch (q) {
...@@ -1932,28 +2013,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1932,28 +2013,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1932 "tmp.zig:5:9: error: duplicate switch value",2013 "tmp.zig:5:9: error: duplicate switch value",
1933 });2014 });
19342015
1935 cases.add("invalid optional type in extern struct",2016 ctx.objErrStage1("invalid optional type in extern struct",
1936 \\const stroo = extern struct {2017 \\const stroo = extern struct {
1937 \\ moo: ?[*c]u8,2018 \\ moo: ?[*c]u8,
1938 \\};2019 \\};
1939 \\export fn testf(fluff: *stroo) void {}2020 \\export fn testf(fluff: *stroo) void { _ = fluff; }
1940 , &[_][]const u8{2021 , &[_][]const u8{
1941 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?[*c]u8'",2022 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?[*c]u8'",
1942 });2023 });
19432024
1944 cases.add("attempt to negate a non-integer, non-float or non-vector type",2025 ctx.objErrStage1("attempt to negate a non-integer, non-float or non-vector type",
1945 \\fn foo() anyerror!u32 {2026 \\fn foo() anyerror!u32 {
1946 \\ return 1;2027 \\ return 1;
1947 \\}2028 \\}
1948 \\2029 \\
1949 \\export fn entry() void {2030 \\export fn entry() void {
1950 \\ const x = -foo();2031 \\ const x = -foo();
2032 \\ _ = x;
1951 \\}2033 \\}
1952 , &[_][]const u8{2034 , &[_][]const u8{
1953 "tmp.zig:6:15: error: negation of type 'anyerror!u32'",2035 "tmp.zig:6:15: error: negation of type 'anyerror!u32'",
1954 });2036 });
19552037
1956 cases.add("attempt to create 17 bit float type",2038 ctx.objErrStage1("attempt to create 17 bit float type",
1957 \\const builtin = @import("std").builtin;2039 \\const builtin = @import("std").builtin;
1958 \\comptime {2040 \\comptime {
1959 \\ _ = @Type(builtin.TypeInfo { .Float = builtin.TypeInfo.Float { .bits = 17 } });2041 \\ _ = @Type(builtin.TypeInfo { .Float = builtin.TypeInfo.Float { .bits = 17 } });
...@@ -1962,7 +2044,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1962,7 +2044,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1962 "tmp.zig:3:32: error: 17-bit float unsupported",2044 "tmp.zig:3:32: error: 17-bit float unsupported",
1963 });2045 });
19642046
1965 cases.add("wrong type for @Type",2047 ctx.objErrStage1("wrong type for @Type",
1966 \\export fn entry() void {2048 \\export fn entry() void {
1967 \\ _ = @Type(0);2049 \\ _ = @Type(0);
1968 \\}2050 \\}
...@@ -1970,7 +2052,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1970,7 +2052,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1970 "tmp.zig:2:15: error: expected type 'std.builtin.TypeInfo', found 'comptime_int'",2052 "tmp.zig:2:15: error: expected type 'std.builtin.TypeInfo', found 'comptime_int'",
1971 });2053 });
19722054
1973 cases.add("@Type with non-constant expression",2055 ctx.objErrStage1("@Type with non-constant expression",
1974 \\const builtin = @import("std").builtin;2056 \\const builtin = @import("std").builtin;
1975 \\var globalTypeInfo : builtin.TypeInfo = undefined;2057 \\var globalTypeInfo : builtin.TypeInfo = undefined;
1976 \\export fn entry() void {2058 \\export fn entry() void {
...@@ -1980,7 +2062,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1980,7 +2062,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1980 "tmp.zig:4:15: error: unable to evaluate constant expression",2062 "tmp.zig:4:15: error: unable to evaluate constant expression",
1981 });2063 });
19822064
1983 cases.add("wrong type for argument tuple to @asyncCall",2065 ctx.objErrStage1("wrong type for argument tuple to @asyncCall",
1984 \\export fn entry1() void {2066 \\export fn entry1() void {
1985 \\ var frame: @Frame(foo) = undefined;2067 \\ var frame: @Frame(foo) = undefined;
1986 \\ @asyncCall(&frame, {}, foo, {});2068 \\ @asyncCall(&frame, {}, foo, {});
...@@ -1993,7 +2075,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1993,7 +2075,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1993 "tmp.zig:3:33: error: expected tuple or struct, found 'void'",2075 "tmp.zig:3:33: error: expected tuple or struct, found 'void'",
1994 });2076 });
19952077
1996 cases.add("wrong type for result ptr to @asyncCall",2078 ctx.objErrStage1("wrong type for result ptr to @asyncCall",
1997 \\export fn entry() void {2079 \\export fn entry() void {
1998 \\ _ = async amain();2080 \\ _ = async amain();
1999 \\}2081 \\}
...@@ -2008,25 +2090,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2008,25 +2090,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2008 "tmp.zig:6:37: error: expected type '*i32', found 'bool'",2090 "tmp.zig:6:37: error: expected type '*i32', found 'bool'",
2009 });2091 });
20102092
2011 cases.add("shift amount has to be an integer type",2093 ctx.objErrStage1("shift amount has to be an integer type",
2012 \\export fn entry() void {2094 \\export fn entry() void {
2013 \\ const x = 1 << &@as(u8, 10);2095 \\ const x = 1 << &@as(u8, 10);
2096 \\ _ = x;
2014 \\}2097 \\}
2015 , &[_][]const u8{2098 , &[_][]const u8{
2016 "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*const u8'",2099 "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*const u8'",
2017 "tmp.zig:2:17: note: referenced here",2100 "tmp.zig:2:17: note: referenced here",
2018 });2101 });
20192102
2020 cases.add("bit shifting only works on integer types",2103 ctx.objErrStage1("bit shifting only works on integer types",
2021 \\export fn entry() void {2104 \\export fn entry() void {
2022 \\ const x = &@as(u8, 1) << 10;2105 \\ const x = &@as(u8, 1) << 10;
2106 \\ _ = x;
2023 \\}2107 \\}
2024 , &[_][]const u8{2108 , &[_][]const u8{
2025 "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*const u8'",2109 "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*const u8'",
2026 "tmp.zig:2:27: note: referenced here",2110 "tmp.zig:2:27: note: referenced here",
2027 });2111 });
20282112
2029 cases.add("struct depends on itself via optional field",2113 ctx.objErrStage1("struct depends on itself via optional field",
2030 \\const LhsExpr = struct {2114 \\const LhsExpr = struct {
2031 \\ rhsExpr: ?AstObject,2115 \\ rhsExpr: ?AstObject,
2032 \\};2116 \\};
...@@ -2036,6 +2120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2036,6 +2120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2036 \\export fn entry() void {2120 \\export fn entry() void {
2037 \\ const lhsExpr = LhsExpr{ .rhsExpr = null };2121 \\ const lhsExpr = LhsExpr{ .rhsExpr = null };
2038 \\ const obj = AstObject{ .lhsExpr = lhsExpr };2122 \\ const obj = AstObject{ .lhsExpr = lhsExpr };
2123 \\ _ = obj;
2039 \\}2124 \\}
2040 , &[_][]const u8{2125 , &[_][]const u8{
2041 "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",2126 "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",
...@@ -2043,51 +2128,54 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2043,51 +2128,54 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2043 "tmp.zig:2:5: note: while checking this field",2128 "tmp.zig:2:5: note: while checking this field",
2044 });2129 });
20452130
2046 cases.add("alignment of enum field specified",2131 ctx.objErrStage1("alignment of enum field specified",
2047 \\const Number = enum {2132 \\const Number = enum {
2048 \\ a,2133 \\ a,
2049 \\ b align(i32),2134 \\ b align(i32),
2050 \\};2135 \\};
2051 \\export fn entry1() void {2136 \\export fn entry1() void {
2052 \\ var x: Number = undefined;2137 \\ var x: Number = undefined;
2138 \\ _ = x;
2053 \\}2139 \\}
2054 , &[_][]const u8{2140 , &[_][]const u8{
2055 "tmp.zig:3:13: error: structs and unions, not enums, support field alignment",2141 "tmp.zig:3:7: error: expected ',', found 'align'",
2056 "tmp.zig:1:16: note: consider 'union(enum)' here",
2057 });2142 });
20582143
2059 cases.add("bad alignment type",2144 ctx.objErrStage1("bad alignment type",
2060 \\export fn entry1() void {2145 \\export fn entry1() void {
2061 \\ var x: []align(true) i32 = undefined;2146 \\ var x: []align(true) i32 = undefined;
2147 \\ _ = x;
2062 \\}2148 \\}
2063 \\export fn entry2() void {2149 \\export fn entry2() void {
2064 \\ var x: *align(@as(f64, 12.34)) i32 = undefined;2150 \\ var x: *align(@as(f64, 12.34)) i32 = undefined;
2151 \\ _ = x;
2065 \\}2152 \\}
2066 , &[_][]const u8{2153 , &[_][]const u8{
2067 "tmp.zig:2:20: error: expected type 'u29', found 'bool'",2154 "tmp.zig:2:20: error: expected type 'u29', found 'bool'",
2068 "tmp.zig:5:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",2155 "tmp.zig:6:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",
2069 });2156 });
20702157
2071 cases.addCase(x: {2158 {
2072 var tc = cases.create("variable in inline assembly template cannot be found",2159 const case = ctx.obj("variable in inline assembly template cannot be found", .{
2160 .cpu_arch = .x86_64,
2161 .os_tag = .linux,
2162 .abi = .gnu,
2163 });
2164 case.backend = .stage1;
2165 case.addError(
2073 \\export fn entry() void {2166 \\export fn entry() void {
2074 \\ var sp = asm volatile (2167 \\ var sp = asm volatile (
2075 \\ "mov %[foo], sp"2168 \\ "mov %[foo], sp"
2076 \\ : [bar] "=r" (-> usize)2169 \\ : [bar] "=r" (-> usize)
2077 \\ );2170 \\ );
2171 \\ _ = sp;
2078 \\}2172 \\}
2079 , &[_][]const u8{2173 , &[_][]const u8{
2080 "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs",2174 "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs",
2081 });2175 });
2082 tc.target = std.zig.CrossTarget{2176 }
2083 .cpu_arch = .x86_64,
2084 .os_tag = .linux,
2085 .abi = .gnu,
2086 };
2087 break :x tc;
2088 });
20892177
2090 cases.add("indirect recursion of async functions detected",2178 ctx.objErrStage1("indirect recursion of async functions detected",
2091 \\var frame: ?anyframe = null;2179 \\var frame: ?anyframe = null;
2092 \\2180 \\
2093 \\export fn a() void {2181 \\export fn a() void {
...@@ -2122,7 +2210,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2122,7 +2210,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2122 "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSumIndirect)' here",2210 "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSumIndirect)' here",
2123 });2211 });
21242212
2125 cases.add("non-async function pointer eventually is inferred to become async",2213 ctx.objErrStage1("non-async function pointer eventually is inferred to become async",
2126 \\export fn a() void {2214 \\export fn a() void {
2127 \\ var non_async_fn: fn () void = undefined;2215 \\ var non_async_fn: fn () void = undefined;
2128 \\ non_async_fn = func;2216 \\ non_async_fn = func;
...@@ -2136,20 +2224,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2136,20 +2224,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2136 "tmp.zig:6:5: note: suspends here",2224 "tmp.zig:6:5: note: suspends here",
2137 });2225 });
21382226
2139 cases.add("bad alignment in @asyncCall",2227 {
2140 \\export fn entry() void {2228 const case = ctx.obj("bad alignment in @asyncCall", .{
2141 \\ var ptr: fn () callconv(.Async) void = func;2229 .cpu_arch = .aarch64,
2142 \\ var bytes: [64]u8 = undefined;2230 .os_tag = .linux,
2143 \\ _ = @asyncCall(&bytes, {}, ptr, .{});2231 .abi = .none,
2144 \\}2232 });
2145 \\fn func() callconv(.Async) void {}2233 case.backend = .stage1;
2146 , &[_][]const u8{2234 case.addError(
2147 // Split the check in two as the alignment value is target dependent.2235 \\export fn entry() void {
2148 "tmp.zig:4:21: error: expected type '[]align(",2236 \\ var ptr: fn () callconv(.Async) void = func;
2149 ") u8', found '*[64]u8'",2237 \\ var bytes: [64]u8 = undefined;
2150 });2238 \\ _ = @asyncCall(&bytes, {}, ptr, .{});
2239 \\}
2240 \\fn func() callconv(.Async) void {}
2241 , &[_][]const u8{
2242 "tmp.zig:4:21: error: expected type '[]align(8) u8', found '*[64]u8'",
2243 });
2244 }
21512245
2152 cases.add("atomic orderings of fence Acquire or stricter",2246 ctx.objErrStage1("atomic orderings of fence Acquire or stricter",
2153 \\export fn entry() void {2247 \\export fn entry() void {
2154 \\ @fence(.Monotonic);2248 \\ @fence(.Monotonic);
2155 \\}2249 \\}
...@@ -2157,20 +2251,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2157,20 +2251,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2157 "tmp.zig:2:12: error: atomic ordering must be Acquire or stricter",2251 "tmp.zig:2:12: error: atomic ordering must be Acquire or stricter",
2158 });2252 });
21592253
2160 cases.add("bad alignment in implicit cast from array pointer to slice",2254 ctx.objErrStage1("bad alignment in implicit cast from array pointer to slice",
2161 \\export fn a() void {2255 \\export fn a() void {
2162 \\ var x: [10]u8 = undefined;2256 \\ var x: [10]u8 = undefined;
2163 \\ var y: []align(16) u8 = &x;2257 \\ var y: []align(16) u8 = &x;
2258 \\ _ = y;
2164 \\}2259 \\}
2165 , &[_][]const u8{2260 , &[_][]const u8{
2166 "tmp.zig:3:30: error: expected type '[]align(16) u8', found '*[10]u8'",2261 "tmp.zig:3:30: error: expected type '[]align(16) u8', found '*[10]u8'",
2167 });2262 });
21682263
2169 cases.add("result location incompatibility mismatching handle_is_ptr (generic call)",2264 ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr (generic call)",
2170 \\export fn entry() void {2265 \\export fn entry() void {
2171 \\ var damn = Container{2266 \\ var damn = Container{
2172 \\ .not_optional = getOptional(i32),2267 \\ .not_optional = getOptional(i32),
2173 \\ };2268 \\ };
2269 \\ _ = damn;
2174 \\}2270 \\}
2175 \\pub fn getOptional(comptime T: type) ?T {2271 \\pub fn getOptional(comptime T: type) ?T {
2176 \\ return 0;2272 \\ return 0;
...@@ -2182,11 +2278,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2182,11 +2278,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2182 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",2278 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",
2183 });2279 });
21842280
2185 cases.add("result location incompatibility mismatching handle_is_ptr",2281 ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr",
2186 \\export fn entry() void {2282 \\export fn entry() void {
2187 \\ var damn = Container{2283 \\ var damn = Container{
2188 \\ .not_optional = getOptional(),2284 \\ .not_optional = getOptional(),
2189 \\ };2285 \\ };
2286 \\ _ = damn;
2190 \\}2287 \\}
2191 \\pub fn getOptional() ?i32 {2288 \\pub fn getOptional() ?i32 {
2192 \\ return 0;2289 \\ return 0;
...@@ -2198,7 +2295,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2198,7 +2295,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2198 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",2295 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",
2199 });2296 });
22002297
2201 cases.add("const frame cast to anyframe",2298 ctx.objErrStage1("const frame cast to anyframe",
2202 \\export fn a() void {2299 \\export fn a() void {
2203 \\ const f = async func();2300 \\ const f = async func();
2204 \\ resume f;2301 \\ resume f;
...@@ -2206,6 +2303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2206,6 +2303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2206 \\export fn b() void {2303 \\export fn b() void {
2207 \\ const f = async func();2304 \\ const f = async func();
2208 \\ var x: anyframe = &f;2305 \\ var x: anyframe = &f;
2306 \\ _ = x;
2209 \\}2307 \\}
2210 \\fn func() void {2308 \\fn func() void {
2211 \\ suspend {}2309 \\ suspend {}
...@@ -2215,27 +2313,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2215,27 +2313,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2215 "tmp.zig:7:24: error: expected type 'anyframe', found '*const @Frame(func)'",2313 "tmp.zig:7:24: error: expected type 'anyframe', found '*const @Frame(func)'",
2216 });2314 });
22172315
2218 cases.add("prevent bad implicit casting of anyframe types",2316 ctx.objErrStage1("prevent bad implicit casting of anyframe types",
2219 \\export fn a() void {2317 \\export fn a() void {
2220 \\ var x: anyframe = undefined;2318 \\ var x: anyframe = undefined;
2221 \\ var y: anyframe->i32 = x;2319 \\ var y: anyframe->i32 = x;
2320 \\ _ = y;
2222 \\}2321 \\}
2223 \\export fn b() void {2322 \\export fn b() void {
2224 \\ var x: i32 = undefined;2323 \\ var x: i32 = undefined;
2225 \\ var y: anyframe->i32 = x;2324 \\ var y: anyframe->i32 = x;
2325 \\ _ = y;
2226 \\}2326 \\}
2227 \\export fn c() void {2327 \\export fn c() void {
2228 \\ var x: @Frame(func) = undefined;2328 \\ var x: @Frame(func) = undefined;
2229 \\ var y: anyframe->i32 = &x;2329 \\ var y: anyframe->i32 = &x;
2330 \\ _ = y;
2230 \\}2331 \\}
2231 \\fn func() void {}2332 \\fn func() void {}
2232 , &[_][]const u8{2333 , &[_][]const u8{
2233 "tmp.zig:3:28: error: expected type 'anyframe->i32', found 'anyframe'",2334 "tmp.zig:3:28: error: expected type 'anyframe->i32', found 'anyframe'",
2234 "tmp.zig:7:28: error: expected type 'anyframe->i32', found 'i32'",2335 "tmp.zig:8:28: error: expected type 'anyframe->i32', found 'i32'",
2235 "tmp.zig:11:29: error: expected type 'anyframe->i32', found '*@Frame(func)'",2336 "tmp.zig:13:29: error: expected type 'anyframe->i32', found '*@Frame(func)'",
2236 });2337 });
22372338
2238 cases.add("wrong frame type used for async call",2339 ctx.objErrStage1("wrong frame type used for async call",
2239 \\export fn entry() void {2340 \\export fn entry() void {
2240 \\ var frame: @Frame(foo) = undefined;2341 \\ var frame: @Frame(foo) = undefined;
2241 \\ frame = async bar();2342 \\ frame = async bar();
...@@ -2250,18 +2351,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2250,18 +2351,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2250 "tmp.zig:3:13: error: expected type '*@Frame(bar)', found '*@Frame(foo)'",2351 "tmp.zig:3:13: error: expected type '*@Frame(bar)', found '*@Frame(foo)'",
2251 });2352 });
22522353
2253 cases.add("@Frame() of generic function",2354 ctx.objErrStage1("@Frame() of generic function",
2254 \\export fn entry() void {2355 \\export fn entry() void {
2255 \\ var frame: @Frame(func) = undefined;2356 \\ var frame: @Frame(func) = undefined;
2357 \\ _ = frame;
2256 \\}2358 \\}
2257 \\fn func(comptime T: type) void {2359 \\fn func(comptime T: type) void {
2258 \\ var x: T = undefined;2360 \\ var x: T = undefined;
2361 \\ _ = x;
2259 \\}2362 \\}
2260 , &[_][]const u8{2363 , &[_][]const u8{
2261 "tmp.zig:2:16: error: @Frame() of generic function",2364 "tmp.zig:2:16: error: @Frame() of generic function",
2262 });2365 });
22632366
2264 cases.add("@frame() causes function to be async",2367 ctx.objErrStage1("@frame() causes function to be async",
2265 \\export fn entry() void {2368 \\export fn entry() void {
2266 \\ func();2369 \\ func();
2267 \\}2370 \\}
...@@ -2273,10 +2376,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2273,10 +2376,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2273 "tmp.zig:5:9: note: @frame() causes function to be async",2376 "tmp.zig:5:9: note: @frame() causes function to be async",
2274 });2377 });
22752378
2276 cases.add("invalid suspend in exported function",2379 ctx.objErrStage1("invalid suspend in exported function",
2277 \\export fn entry() void {2380 \\export fn entry() void {
2278 \\ var frame = async func();2381 \\ var frame = async func();
2279 \\ var result = await frame;2382 \\ var result = await frame;
2383 \\ _ = result;
2280 \\}2384 \\}
2281 \\fn func() void {2385 \\fn func() void {
2282 \\ suspend {}2386 \\ suspend {}
...@@ -2286,7 +2390,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2286,7 +2390,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2286 "tmp.zig:3:18: note: await here is a suspend point",2390 "tmp.zig:3:18: note: await here is a suspend point",
2287 });2391 });
22882392
2289 cases.add("async function indirectly depends on its own frame",2393 ctx.objErrStage1("async function indirectly depends on its own frame",
2290 \\export fn entry() void {2394 \\export fn entry() void {
2291 \\ _ = async amain();2395 \\ _ = async amain();
2292 \\}2396 \\}
...@@ -2295,6 +2399,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2295,6 +2399,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2295 \\}2399 \\}
2296 \\fn other() void {2400 \\fn other() void {
2297 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;2401 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
2402 \\ _ = x;
2298 \\}2403 \\}
2299 , &[_][]const u8{2404 , &[_][]const u8{
2300 "tmp.zig:4:1: error: unable to determine async function frame of 'amain'",2405 "tmp.zig:4:1: error: unable to determine async function frame of 'amain'",
...@@ -2302,19 +2407,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2302,19 +2407,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2302 "tmp.zig:8:13: note: referenced here",2407 "tmp.zig:8:13: note: referenced here",
2303 });2408 });
23042409
2305 cases.add("async function depends on its own frame",2410 ctx.objErrStage1("async function depends on its own frame",
2306 \\export fn entry() void {2411 \\export fn entry() void {
2307 \\ _ = async amain();2412 \\ _ = async amain();
2308 \\}2413 \\}
2309 \\fn amain() callconv(.Async) void {2414 \\fn amain() callconv(.Async) void {
2310 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;2415 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
2416 \\ _ = x;
2311 \\}2417 \\}
2312 , &[_][]const u8{2418 , &[_][]const u8{
2313 "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet",2419 "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet",
2314 "tmp.zig:5:13: note: referenced here",2420 "tmp.zig:5:13: note: referenced here",
2315 });2421 });
23162422
2317 cases.add("non async function pointer passed to @asyncCall",2423 ctx.objErrStage1("non async function pointer passed to @asyncCall",
2318 \\export fn entry() void {2424 \\export fn entry() void {
2319 \\ var ptr = afunc;2425 \\ var ptr = afunc;
2320 \\ var bytes: [100]u8 align(16) = undefined;2426 \\ var bytes: [100]u8 align(16) = undefined;
...@@ -2325,7 +2431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2325,7 +2431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2325 "tmp.zig:4:32: error: expected async function, found 'fn() void'",2431 "tmp.zig:4:32: error: expected async function, found 'fn() void'",
2326 });2432 });
23272433
2328 cases.add("runtime-known async function called",2434 ctx.objErrStage1("runtime-known async function called",
2329 \\export fn entry() void {2435 \\export fn entry() void {
2330 \\ _ = async amain();2436 \\ _ = async amain();
2331 \\}2437 \\}
...@@ -2338,7 +2444,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2338,7 +2444,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2338 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",2444 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",
2339 });2445 });
23402446
2341 cases.add("runtime-known function called with async keyword",2447 ctx.objErrStage1("runtime-known function called with async keyword",
2342 \\export fn entry() void {2448 \\export fn entry() void {
2343 \\ var ptr = afunc;2449 \\ var ptr = afunc;
2344 \\ _ = async ptr();2450 \\ _ = async ptr();
...@@ -2349,7 +2455,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2349,7 +2455,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2349 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",2455 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",
2350 });2456 });
23512457
2352 cases.add("function with ccc indirectly calling async function",2458 ctx.objErrStage1("function with ccc indirectly calling async function",
2353 \\export fn entry() void {2459 \\export fn entry() void {
2354 \\ foo();2460 \\ foo();
2355 \\}2461 \\}
...@@ -2366,7 +2472,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2366,7 +2472,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2366 "tmp.zig:8:5: note: suspends here",2472 "tmp.zig:8:5: note: suspends here",
2367 });2473 });
23682474
2369 cases.add("capture group on switch prong with incompatible payload types",2475 ctx.objErrStage1("capture group on switch prong with incompatible payload types",
2370 \\const Union = union(enum) {2476 \\const Union = union(enum) {
2371 \\ A: usize,2477 \\ A: usize,
2372 \\ B: isize,2478 \\ B: isize,
...@@ -2374,7 +2480,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2374,7 +2480,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2374 \\comptime {2480 \\comptime {
2375 \\ var u = Union{ .A = 8 };2481 \\ var u = Union{ .A = 8 };
2376 \\ switch (u) {2482 \\ switch (u) {
2377 \\ .A, .B => |e| unreachable,2483 \\ .A, .B => |e| {
2484 \\ _ = e;
2485 \\ unreachable;
2486 \\ },
2378 \\ }2487 \\ }
2379 \\}2488 \\}
2380 , &[_][]const u8{2489 , &[_][]const u8{
...@@ -2383,7 +2492,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2383,7 +2492,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2383 "tmp.zig:8:13: note: type 'isize' here",2492 "tmp.zig:8:13: note: type 'isize' here",
2384 });2493 });
23852494
2386 cases.add("wrong type to @hasField",2495 ctx.objErrStage1("wrong type to @hasField",
2387 \\export fn entry() bool {2496 \\export fn entry() bool {
2388 \\ return @hasField(i32, "hi");2497 \\ return @hasField(i32, "hi");
2389 \\}2498 \\}
...@@ -2391,44 +2500,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2391,44 +2500,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2391 "tmp.zig:2:22: error: type 'i32' does not support @hasField",2500 "tmp.zig:2:22: error: type 'i32' does not support @hasField",
2392 });2501 });
23932502
2394 cases.add("slice passed as array init type with elems",2503 ctx.objErrStage1("slice passed as array init type with elems",
2395 \\export fn entry() void {2504 \\export fn entry() void {
2396 \\ const x = []u8{1, 2};2505 \\ const x = []u8{1, 2};
2506 \\ _ = x;
2397 \\}2507 \\}
2398 , &[_][]const u8{2508 , &[_][]const u8{
2399 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",2509 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",
2400 });2510 });
24012511
2402 cases.add("slice passed as array init type",2512 ctx.objErrStage1("slice passed as array init type",
2403 \\export fn entry() void {2513 \\export fn entry() void {
2404 \\ const x = []u8{};2514 \\ const x = []u8{};
2515 \\ _ = x;
2405 \\}2516 \\}
2406 , &[_][]const u8{2517 , &[_][]const u8{
2407 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",2518 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",
2408 });2519 });
24092520
2410 cases.add("inferred array size invalid here",2521 ctx.objErrStage1("inferred array size invalid here",
2411 \\export fn entry() void {2522 \\export fn entry() void {
2412 \\ const x = [_]u8;2523 \\ const x = [_]u8;
2524 \\ _ = x;
2413 \\}2525 \\}
2414 \\export fn entry2() void {2526 \\export fn entry2() void {
2415 \\ const S = struct { a: *const [_]u8 };2527 \\ const S = struct { a: *const [_]u8 };
2416 \\ var a = .{ S{} };2528 \\ var a = .{ S{} };
2529 \\ _ = a;
2417 \\}2530 \\}
2418 , &[_][]const u8{2531 , &[_][]const u8{
2419 "tmp.zig:2:15: error: inferred array size invalid here",2532 "tmp.zig:2:16: error: unable to infer array size",
2420 "tmp.zig:5:34: error: inferred array size invalid here",2533 "tmp.zig:6:35: error: unable to infer array size",
2421 });2534 });
24222535
2423 cases.add("initializing array with struct syntax",2536 ctx.objErrStage1("initializing array with struct syntax",
2424 \\export fn entry() void {2537 \\export fn entry() void {
2425 \\ const x = [_]u8{ .y = 2 };2538 \\ const x = [_]u8{ .y = 2 };
2539 \\ _ = x;
2426 \\}2540 \\}
2427 , &[_][]const u8{2541 , &[_][]const u8{
2428 "tmp.zig:2:15: error: initializing array with struct syntax",2542 "tmp.zig:2:15: error: initializing array with struct syntax",
2429 });2543 });
24302544
2431 cases.add("compile error in struct init expression",2545 ctx.objErrStage1("compile error in struct init expression",
2432 \\const Foo = struct {2546 \\const Foo = struct {
2433 \\ a: i32 = crap,2547 \\ a: i32 = crap,
2434 \\ b: i32,2548 \\ b: i32,
...@@ -2437,23 +2551,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2437,23 +2551,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2437 \\ var x = Foo{2551 \\ var x = Foo{
2438 \\ .b = 5,2552 \\ .b = 5,
2439 \\ };2553 \\ };
2554 \\ _ = x;
2440 \\}2555 \\}
2441 , &[_][]const u8{2556 , &[_][]const u8{
2442 "tmp.zig:2:14: error: use of undeclared identifier 'crap'",2557 "tmp.zig:2:14: error: use of undeclared identifier 'crap'",
2443 });2558 });
24442559
2445 cases.add("undefined as field type is rejected",2560 ctx.objErrStage1("undefined as field type is rejected",
2446 \\const Foo = struct {2561 \\const Foo = struct {
2447 \\ a: undefined,2562 \\ a: undefined,
2448 \\};2563 \\};
2449 \\export fn entry1() void {2564 \\export fn entry1() void {
2450 \\ const foo: Foo = undefined;2565 \\ const foo: Foo = undefined;
2566 \\ _ = foo;
2451 \\}2567 \\}
2452 , &[_][]const u8{2568 , &[_][]const u8{
2453 "tmp.zig:2:8: error: use of undefined value here causes undefined behavior",2569 "tmp.zig:2:8: error: use of undefined value here causes undefined behavior",
2454 });2570 });
24552571
2456 cases.add("@hasDecl with non-container",2572 ctx.objErrStage1("@hasDecl with non-container",
2457 \\export fn entry() void {2573 \\export fn entry() void {
2458 \\ _ = @hasDecl(i32, "hi");2574 \\ _ = @hasDecl(i32, "hi");
2459 \\}2575 \\}
...@@ -2461,16 +2577,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2461,16 +2577,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2461 "tmp.zig:2:18: error: expected struct, enum, or union; found 'i32'",2577 "tmp.zig:2:18: error: expected struct, enum, or union; found 'i32'",
2462 });2578 });
24632579
2464 cases.add("field access of slices",2580 ctx.objErrStage1("field access of slices",
2465 \\export fn entry() void {2581 \\export fn entry() void {
2466 \\ var slice: []i32 = undefined;2582 \\ var slice: []i32 = undefined;
2467 \\ const info = @TypeOf(slice).unknown;2583 \\ const info = @TypeOf(slice).unknown;
2584 \\ _ = info;
2468 \\}2585 \\}
2469 , &[_][]const u8{2586 , &[_][]const u8{
2470 "tmp.zig:3:32: error: type 'type' does not support field access",2587 "tmp.zig:3:32: error: type 'type' does not support field access",
2471 });2588 });
24722589
2473 cases.add("peer cast then implicit cast const pointer to mutable C pointer",2590 ctx.objErrStage1("peer cast then implicit cast const pointer to mutable C pointer",
2474 \\export fn func() void {2591 \\export fn func() void {
2475 \\ var strValue: [*c]u8 = undefined;2592 \\ var strValue: [*c]u8 = undefined;
2476 \\ strValue = strValue orelse "";2593 \\ strValue = strValue orelse "";
...@@ -2480,19 +2597,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2480,19 +2597,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2480 "tmp.zig:3:32: note: cast discards const qualifier",2597 "tmp.zig:3:32: note: cast discards const qualifier",
2481 });2598 });
24822599
2483 cases.add("overflow in enum value allocation",2600 ctx.objErrStage1("overflow in enum value allocation",
2484 \\const Moo = enum(u8) {2601 \\const Moo = enum(u8) {
2485 \\ Last = 255,2602 \\ Last = 255,
2486 \\ Over,2603 \\ Over,
2487 \\};2604 \\};
2488 \\pub fn main() void {2605 \\pub fn main() void {
2489 \\ var y = Moo.Last;2606 \\ var y = Moo.Last;
2607 \\ _ = y;
2490 \\}2608 \\}
2491 , &[_][]const u8{2609 , &[_][]const u8{
2492 "tmp.zig:3:5: error: enumeration value 256 too large for type 'u8'",2610 "tmp.zig:3:5: error: enumeration value 256 too large for type 'u8'",
2493 });2611 });
24942612
2495 cases.add("attempt to cast enum literal to error",2613 ctx.objErrStage1("attempt to cast enum literal to error",
2496 \\export fn entry() void {2614 \\export fn entry() void {
2497 \\ switch (error.Hi) {2615 \\ switch (error.Hi) {
2498 \\ .Hi => {},2616 \\ .Hi => {},
...@@ -2502,7 +2620,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2502,7 +2620,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2502 "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'",2620 "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'",
2503 });2621 });
25042622
2505 cases.add("@sizeOf bad type",2623 ctx.objErrStage1("@sizeOf bad type",
2506 \\export fn entry() usize {2624 \\export fn entry() usize {
2507 \\ return @sizeOf(@TypeOf(null));2625 \\ return @sizeOf(@TypeOf(null));
2508 \\}2626 \\}
...@@ -2510,7 +2628,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2510,7 +2628,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2510 "tmp.zig:2:20: error: no size available for type '(null)'",2628 "tmp.zig:2:20: error: no size available for type '(null)'",
2511 });2629 });
25122630
2513 cases.add("generic function where return type is self-referenced",2631 ctx.objErrStage1("generic function where return type is self-referenced",
2514 \\fn Foo(comptime T: type) Foo(T) {2632 \\fn Foo(comptime T: type) Foo(T) {
2515 \\ return struct{ x: T };2633 \\ return struct{ x: T };
2516 \\}2634 \\}
...@@ -2518,34 +2636,37 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2518,34 +2636,37 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2518 \\ const t = Foo(u32) {2636 \\ const t = Foo(u32) {
2519 \\ .x = 12637 \\ .x = 1
2520 \\ };2638 \\ };
2639 \\ _ = t;
2521 \\}2640 \\}
2522 , &[_][]const u8{2641 , &[_][]const u8{
2523 "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches",2642 "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches",
2524 "tmp.zig:5:18: note: referenced here",2643 "tmp.zig:5:18: note: referenced here",
2525 });2644 });
25262645
2527 cases.add("@ptrToInt 0 to non optional pointer",2646 ctx.objErrStage1("@ptrToInt 0 to non optional pointer",
2528 \\export fn entry() void {2647 \\export fn entry() void {
2529 \\ var b = @intToPtr(*i32, 0);2648 \\ var b = @intToPtr(*i32, 0);
2649 \\ _ = b;
2530 \\}2650 \\}
2531 , &[_][]const u8{2651 , &[_][]const u8{
2532 "tmp.zig:2:13: error: pointer type '*i32' does not allow address zero",2652 "tmp.zig:2:13: error: pointer type '*i32' does not allow address zero",
2533 });2653 });
25342654
2535 cases.add("cast enum literal to enum but it doesn't match",2655 ctx.objErrStage1("cast enum literal to enum but it doesn't match",
2536 \\const Foo = enum {2656 \\const Foo = enum {
2537 \\ a,2657 \\ a,
2538 \\ b,2658 \\ b,
2539 \\};2659 \\};
2540 \\export fn entry() void {2660 \\export fn entry() void {
2541 \\ const x: Foo = .c;2661 \\ const x: Foo = .c;
2662 \\ _ = x;
2542 \\}2663 \\}
2543 , &[_][]const u8{2664 , &[_][]const u8{
2544 "tmp.zig:6:20: error: enum 'Foo' has no field named 'c'",2665 "tmp.zig:6:20: error: enum 'Foo' has no field named 'c'",
2545 "tmp.zig:1:13: note: 'Foo' declared here",2666 "tmp.zig:1:13: note: 'Foo' declared here",
2546 });2667 });
25472668
2548 cases.add("discarding error value",2669 ctx.objErrStage1("discarding error value",
2549 \\export fn entry() void {2670 \\export fn entry() void {
2550 \\ _ = foo();2671 \\ _ = foo();
2551 \\}2672 \\}
...@@ -2556,7 +2677,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2556,7 +2677,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2556 "tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`",2677 "tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`",
2557 });2678 });
25582679
2559 cases.add("volatile on global assembly",2680 ctx.objErrStage1("volatile on global assembly",
2560 \\comptime {2681 \\comptime {
2561 \\ asm volatile ("");2682 \\ asm volatile ("");
2562 \\}2683 \\}
...@@ -2564,7 +2685,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2564,7 +2685,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2564 "tmp.zig:2:9: error: volatile is meaningless on global assembly",2685 "tmp.zig:2:9: error: volatile is meaningless on global assembly",
2565 });2686 });
25662687
2567 cases.add("invalid multiple dereferences",2688 ctx.objErrStage1("invalid multiple dereferences",
2568 \\export fn a() void {2689 \\export fn a() void {
2569 \\ var box = Box{ .field = 0 };2690 \\ var box = Box{ .field = 0 };
2570 \\ box.*.field = 1;2691 \\ box.*.field = 1;
...@@ -2582,13 +2703,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2582,13 +2703,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2582 "tmp.zig:8:13: error: attempt to dereference non-pointer type 'Box'",2703 "tmp.zig:8:13: error: attempt to dereference non-pointer type 'Box'",
2583 });2704 });
25842705
2585 cases.add("usingnamespace with wrong type",2706 ctx.objErrStage1("usingnamespace with wrong type",
2586 \\usingnamespace void;2707 \\usingnamespace void;
2587 , &[_][]const u8{2708 , &[_][]const u8{
2588 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",2709 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
2589 });2710 });
25902711
2591 cases.add("ignored expression in while continuation",2712 ctx.objErrStage1("ignored expression in while continuation",
2592 \\export fn a() void {2713 \\export fn a() void {
2593 \\ while (true) : (bad()) {}2714 \\ while (true) : (bad()) {}
2594 \\}2715 \\}
...@@ -2609,31 +2730,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2609,31 +2730,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2609 "tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if`",2730 "tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if`",
2610 });2731 });
26112732
2612 cases.add("empty while loop body",2733 ctx.objErrStage1("empty while loop body",
2613 \\export fn a() void {2734 \\export fn a() void {
2614 \\ while(true);2735 \\ while(true);
2615 \\}2736 \\}
2616 , &[_][]const u8{2737 , &[_][]const u8{
2617 "tmp.zig:2:16: error: expected loop body, found ';'",2738 "tmp.zig:2:16: error: expected block or assignment, found ';'",
2618 });2739 });
26192740
2620 cases.add("empty for loop body",2741 ctx.objErrStage1("empty for loop body",
2621 \\export fn a() void {2742 \\export fn a() void {
2622 \\ for(undefined) |x|;2743 \\ for(undefined) |x|;
2623 \\}2744 \\}
2624 , &[_][]const u8{2745 , &[_][]const u8{
2625 "tmp.zig:2:23: error: expected loop body, found ';'",2746 "tmp.zig:2:23: error: expected block or assignment, found ';'",
2626 });2747 });
26272748
2628 cases.add("empty if body",2749 ctx.objErrStage1("empty if body",
2629 \\export fn a() void {2750 \\export fn a() void {
2630 \\ if(true);2751 \\ if(true);
2631 \\}2752 \\}
2632 , &[_][]const u8{2753 , &[_][]const u8{
2633 "tmp.zig:2:13: error: expected if body, found ';'",2754 "tmp.zig:2:13: error: expected block or assignment, found ';'",
2634 });2755 });
26352756
2636 cases.add("import outside package path",2757 ctx.objErrStage1("import outside package path",
2637 \\comptime{2758 \\comptime{
2638 \\ _ = @import("../a.zig");2759 \\ _ = @import("../a.zig");
2639 \\}2760 \\}
...@@ -2641,14 +2762,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2641,14 +2762,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2641 "tmp.zig:2:9: error: import of file outside package path: '../a.zig'",2762 "tmp.zig:2:9: error: import of file outside package path: '../a.zig'",
2642 });2763 });
26432764
2644 cases.add("bogus compile var",2765 ctx.objErrStage1("bogus compile var",
2645 \\const x = @import("builtin").bogus;2766 \\const x = @import("builtin").bogus;
2646 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }2767 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }
2647 , &[_][]const u8{2768 , &[_][]const u8{
2648 "tmp.zig:1:29: error: container 'builtin' has no member called 'bogus'",2769 "tmp.zig:1:29: error: container 'builtin' has no member called 'bogus'",
2649 });2770 });
26502771
2651 cases.add("wrong panic signature, runtime function",2772 ctx.objErrStage1("wrong panic signature, runtime function",
2652 \\test "" {}2773 \\test "" {}
2653 \\2774 \\
2654 \\pub fn panic() void {}2775 \\pub fn panic() void {}
...@@ -2657,8 +2778,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2657,8 +2778,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2657 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn() void'",2778 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn() void'",
2658 });2779 });
26592780
2660 cases.add("wrong panic signature, generic function",2781 ctx.objErrStage1("wrong panic signature, generic function",
2661 \\pub fn panic(comptime msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {2782 \\pub fn panic(comptime msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
2783 \\ _ = msg; _ = error_return_trace;
2662 \\ while (true) {}2784 \\ while (true) {}
2663 \\}2785 \\}
2664 , &[_][]const u8{2786 , &[_][]const u8{
...@@ -2666,14 +2788,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2666,14 +2788,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2666 "note: only one of the functions is generic",2788 "note: only one of the functions is generic",
2667 });2789 });
26682790
2669 cases.add("direct struct loop",2791 ctx.objErrStage1("direct struct loop",
2670 \\const A = struct { a : A, };2792 \\const A = struct { a : A, };
2671 \\export fn entry() usize { return @sizeOf(A); }2793 \\export fn entry() usize { return @sizeOf(A); }
2672 , &[_][]const u8{2794 , &[_][]const u8{
2673 "tmp.zig:1:11: error: struct 'A' depends on itself",2795 "tmp.zig:1:11: error: struct 'A' depends on itself",
2674 });2796 });
26752797
2676 cases.add("indirect struct loop",2798 ctx.objErrStage1("indirect struct loop",
2677 \\const A = struct { b : B, };2799 \\const A = struct { b : B, };
2678 \\const B = struct { c : C, };2800 \\const B = struct { c : C, };
2679 \\const C = struct { a : A, };2801 \\const C = struct { a : A, };
...@@ -2682,7 +2804,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2682,7 +2804,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2682 "tmp.zig:1:11: error: struct 'A' depends on itself",2804 "tmp.zig:1:11: error: struct 'A' depends on itself",
2683 });2805 });
26842806
2685 cases.add("instantiating an undefined value for an invalid struct that contains itself",2807 ctx.objErrStage1("instantiating an undefined value for an invalid struct that contains itself",
2686 \\const Foo = struct {2808 \\const Foo = struct {
2687 \\ x: Foo,2809 \\ x: Foo,
2688 \\};2810 \\};
...@@ -2697,23 +2819,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2697,23 +2819,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2697 "tmp.zig:8:28: note: referenced here",2819 "tmp.zig:8:28: note: referenced here",
2698 });2820 });
26992821
2700 cases.add("enum field value references enum",2822 ctx.objErrStage1("enum field value references enum",
2701 \\pub const Foo = extern enum {2823 \\pub const Foo = enum(c_int) {
2702 \\ A = Foo.B,2824 \\ A = Foo.B,
2703 \\ C = D,2825 \\ C = D,
2704 \\};2826 \\};
2705 \\export fn entry() void {2827 \\export fn entry() void {
2706 \\ var s: Foo = Foo.E;2828 \\ var s: Foo = Foo.E;
2829 \\ _ = s;
2707 \\}2830 \\}
2708 , &[_][]const u8{2831 , &[_][]const u8{
2709 "tmp.zig:1:17: error: enum 'Foo' depends on itself",2832 "tmp.zig:1:17: error: enum 'Foo' depends on itself",
2710 });2833 });
27112834
2712 cases.add("top level decl dependency loop",2835 ctx.objErrStage1("top level decl dependency loop",
2713 \\const a : @TypeOf(b) = 0;2836 \\const a : @TypeOf(b) = 0;
2714 \\const b : @TypeOf(a) = 0;2837 \\const b : @TypeOf(a) = 0;
2715 \\export fn entry() void {2838 \\export fn entry() void {
2716 \\ const c = a + b;2839 \\ const c = a + b;
2840 \\ _ = c;
2717 \\}2841 \\}
2718 , &[_][]const u8{2842 , &[_][]const u8{
2719 "tmp.zig:2:19: error: dependency loop detected",2843 "tmp.zig:2:19: error: dependency loop detected",
...@@ -2721,7 +2845,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2721,7 +2845,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2721 "tmp.zig:4:15: note: referenced here",2845 "tmp.zig:4:15: note: referenced here",
2722 });2846 });
27232847
2724 cases.addTest("not an enum type",2848 ctx.testErrStage1("not an enum type",
2725 \\export fn entry() void {2849 \\export fn entry() void {
2726 \\ var self: Error = undefined;2850 \\ var self: Error = undefined;
2727 \\ switch (self) {2851 \\ switch (self) {
...@@ -2739,18 +2863,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2739,18 +2863,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2739 "tmp.zig:4:9: error: expected type '@typeInfo(Error).Union.tag_type.?', found 'type'",2863 "tmp.zig:4:9: error: expected type '@typeInfo(Error).Union.tag_type.?', found 'type'",
2740 });2864 });
27412865
2742 cases.addTest("binary OR operator on error sets",2866 ctx.testErrStage1("binary OR operator on error sets",
2743 \\pub const A = error.A;2867 \\pub const A = error.A;
2744 \\pub const AB = A | error.B;2868 \\pub const AB = A | error.B;
2745 \\export fn entry() void {2869 \\export fn entry() void {
2746 \\ var x: AB = undefined;2870 \\ var x: AB = undefined;
2871 \\ _ = x;
2747 \\}2872 \\}
2748 , &[_][]const u8{2873 , &[_][]const u8{
2749 "tmp.zig:2:18: error: invalid operands to binary expression: 'error{A}' and 'error{B}'",2874 "tmp.zig:2:18: error: invalid operands to binary expression: 'error{A}' and 'error{B}'",
2750 });2875 });
27512876
2752 if (std.Target.current.os.tag == .linux) {2877 if (std.Target.current.os.tag == .linux) {
2753 cases.addTest("implicit dependency on libc",2878 ctx.testErrStage1("implicit dependency on libc",
2754 \\extern "c" fn exit(u8) void;2879 \\extern "c" fn exit(u8) void;
2755 \\export fn entry() void {2880 \\export fn entry() void {
2756 \\ exit(0);2881 \\ exit(0);
...@@ -2759,7 +2884,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2759,7 +2884,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2759 "tmp.zig:3:5: error: dependency on libc must be explicitly specified in the build command",2884 "tmp.zig:3:5: error: dependency on libc must be explicitly specified in the build command",
2760 });2885 });
27612886
2762 cases.addTest("libc headers note",2887 ctx.testErrStage1("libc headers note",
2763 \\const c = @cImport(@cInclude("stdio.h"));2888 \\const c = @cImport(@cInclude("stdio.h"));
2764 \\export fn entry() void {2889 \\export fn entry() void {
2765 \\ _ = c.printf("hello, world!\n");2890 \\ _ = c.printf("hello, world!\n");
...@@ -2770,18 +2895,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2770,18 +2895,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2770 });2895 });
2771 }2896 }
27722897
2773 cases.addTest("comptime vector overflow shows the index",2898 ctx.testErrStage1("comptime vector overflow shows the index",
2774 \\comptime {2899 \\comptime {
2775 \\ var a: @import("std").meta.Vector(4, u8) = [_]u8{ 1, 2, 255, 4 };2900 \\ var a: @import("std").meta.Vector(4, u8) = [_]u8{ 1, 2, 255, 4 };
2776 \\ var b: @import("std").meta.Vector(4, u8) = [_]u8{ 5, 6, 1, 8 };2901 \\ var b: @import("std").meta.Vector(4, u8) = [_]u8{ 5, 6, 1, 8 };
2777 \\ var x = a + b;2902 \\ var x = a + b;
2903 \\ _ = x;
2778 \\}2904 \\}
2779 , &[_][]const u8{2905 , &[_][]const u8{
2780 "tmp.zig:4:15: error: operation caused overflow",2906 "tmp.zig:4:15: error: operation caused overflow",
2781 "tmp.zig:4:15: note: when computing vector element at index 2",2907 "tmp.zig:4:15: note: when computing vector element at index 2",
2782 });2908 });
27832909
2784 cases.addTest("packed struct with fields of not allowed types",2910 ctx.testErrStage1("packed struct with fields of not allowed types",
2785 \\const A = packed struct {2911 \\const A = packed struct {
2786 \\ x: anyerror,2912 \\ x: anyerror,
2787 \\};2913 \\};
...@@ -2805,24 +2931,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2805,24 +2931,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2805 \\};2931 \\};
2806 \\export fn entry1() void {2932 \\export fn entry1() void {
2807 \\ var a: A = undefined;2933 \\ var a: A = undefined;
2934 \\ _ = a;
2808 \\}2935 \\}
2809 \\export fn entry2() void {2936 \\export fn entry2() void {
2810 \\ var b: B = undefined;2937 \\ var b: B = undefined;
2938 \\ _ = b;
2811 \\}2939 \\}
2812 \\export fn entry3() void {2940 \\export fn entry3() void {
2813 \\ var r: C = undefined;2941 \\ var r: C = undefined;
2942 \\ _ = r;
2814 \\}2943 \\}
2815 \\export fn entry4() void {2944 \\export fn entry4() void {
2816 \\ var d: D = undefined;2945 \\ var d: D = undefined;
2946 \\ _ = d;
2817 \\}2947 \\}
2818 \\export fn entry5() void {2948 \\export fn entry5() void {
2819 \\ var e: E = undefined;2949 \\ var e: E = undefined;
2950 \\ _ = e;
2820 \\}2951 \\}
2821 \\export fn entry6() void {2952 \\export fn entry6() void {
2822 \\ var f: F = undefined;2953 \\ var f: F = undefined;
2954 \\ _ = f;
2823 \\}2955 \\}
2824 \\export fn entry7() void {2956 \\export fn entry7() void {
2825 \\ var g: G = undefined;2957 \\ var g: G = undefined;
2958 \\ _ = g;
2826 \\}2959 \\}
2827 \\const S = struct {2960 \\const S = struct {
2828 \\ x: i32,2961 \\ x: i32,
...@@ -2843,42 +2976,40 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2843,42 +2976,40 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2843 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",2976 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",
2844 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",2977 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",
2845 "tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation",2978 "tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation",
2846 "tmp.zig:50:14: note: enum declaration does not specify an integer tag type",2979 "tmp.zig:57:14: note: enum declaration does not specify an integer tag type",
2847 });2980 });
28482981
2849 cases.addCase(x: {2982 ctx.objErrStage1("deduplicate undeclared identifier",
2850 var tc = cases.create("deduplicate undeclared identifier",2983 \\export fn a() void {
2851 \\export fn a() void {2984 \\ x += 1;
2852 \\ x += 1;2985 \\}
2853 \\}2986 \\export fn b() void {
2854 \\export fn b() void {2987 \\ x += 1;
2855 \\ x += 1;2988 \\}
2856 \\}2989 , &[_][]const u8{
2857 , &[_][]const u8{2990 "tmp.zig:2:5: error: use of undeclared identifier 'x'",
2858 "tmp.zig:2:5: error: use of undeclared identifier 'x'",
2859 });
2860 tc.expect_exact = true;
2861 break :x tc;
2862 });2991 });
28632992
2864 cases.add("export generic function",2993 ctx.objErrStage1("export generic function",
2865 \\export fn foo(num: anytype) i32 {2994 \\export fn foo(num: anytype) i32 {
2995 \\ _ = num;
2866 \\ return 0;2996 \\ return 0;
2867 \\}2997 \\}
2868 , &[_][]const u8{2998 , &[_][]const u8{
2869 "tmp.zig:1:15: error: parameter of type 'anytype' not allowed in function with calling convention 'C'",2999 "tmp.zig:1:15: error: parameter of type 'anytype' not allowed in function with calling convention 'C'",
2870 });3000 });
28713001
2872 cases.add("C pointer to c_void",3002 ctx.objErrStage1("C pointer to c_void",
2873 \\export fn a() void {3003 \\export fn a() void {
2874 \\ var x: *c_void = undefined;3004 \\ var x: *c_void = undefined;
2875 \\ var y: [*c]c_void = x;3005 \\ var y: [*c]c_void = x;
3006 \\ _ = y;
2876 \\}3007 \\}
2877 , &[_][]const u8{3008 , &[_][]const u8{
2878 "tmp.zig:3:16: error: C pointers cannot point to opaque types",3009 "tmp.zig:3:16: error: C pointers cannot point to opaque types",
2879 });3010 });
28803011
2881 cases.add("directly embedding opaque type in struct and union",3012 ctx.objErrStage1("directly embedding opaque type in struct and union",
2882 \\const O = opaque {};3013 \\const O = opaque {};
2883 \\const Foo = struct {3014 \\const Foo = struct {
2884 \\ o: O,3015 \\ o: O,
...@@ -2889,74 +3020,85 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2889,74 +3020,85 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2889 \\};3020 \\};
2890 \\export fn a() void {3021 \\export fn a() void {
2891 \\ var foo: Foo = undefined;3022 \\ var foo: Foo = undefined;
3023 \\ _ = foo;
2892 \\}3024 \\}
2893 \\export fn b() void {3025 \\export fn b() void {
2894 \\ var bar: Bar = undefined;3026 \\ var bar: Bar = undefined;
3027 \\ _ = bar;
2895 \\}3028 \\}
2896 \\export fn c() void {3029 \\export fn c() void {
2897 \\ var baz: *opaque {} = undefined;3030 \\ var baz: *opaque {} = undefined;
2898 \\ const qux = .{baz.*};3031 \\ const qux = .{baz.*};
3032 \\ _ = qux;
2899 \\}3033 \\}
2900 , &[_][]const u8{3034 , &[_][]const u8{
2901 "tmp.zig:3:5: error: opaque types have unknown size and therefore cannot be directly embedded in structs",3035 "tmp.zig:3:5: error: opaque types have unknown size and therefore cannot be directly embedded in structs",
2902 "tmp.zig:7:5: error: opaque types have unknown size and therefore cannot be directly embedded in unions",3036 "tmp.zig:7:5: error: opaque types have unknown size and therefore cannot be directly embedded in unions",
2903 "tmp.zig:17:22: error: opaque types have unknown size and therefore cannot be directly embedded in structs",3037 "tmp.zig:19:22: error: opaque types have unknown size and therefore cannot be directly embedded in structs",
2904 });3038 });
29053039
2906 cases.add("implicit cast between C pointer and Zig pointer - bad const/align/child",3040 ctx.objErrStage1("implicit cast between C pointer and Zig pointer - bad const/align/child",
2907 \\export fn a() void {3041 \\export fn a() void {
2908 \\ var x: [*c]u8 = undefined;3042 \\ var x: [*c]u8 = undefined;
2909 \\ var y: *align(4) u8 = x;3043 \\ var y: *align(4) u8 = x;
3044 \\ _ = y;
2910 \\}3045 \\}
2911 \\export fn b() void {3046 \\export fn b() void {
2912 \\ var x: [*c]const u8 = undefined;3047 \\ var x: [*c]const u8 = undefined;
2913 \\ var y: *u8 = x;3048 \\ var y: *u8 = x;
3049 \\ _ = y;
2914 \\}3050 \\}
2915 \\export fn c() void {3051 \\export fn c() void {
2916 \\ var x: [*c]u8 = undefined;3052 \\ var x: [*c]u8 = undefined;
2917 \\ var y: *u32 = x;3053 \\ var y: *u32 = x;
3054 \\ _ = y;
2918 \\}3055 \\}
2919 \\export fn d() void {3056 \\export fn d() void {
2920 \\ var y: *align(1) u32 = undefined;3057 \\ var y: *align(1) u32 = undefined;
2921 \\ var x: [*c]u32 = y;3058 \\ var x: [*c]u32 = y;
3059 \\ _ = x;
2922 \\}3060 \\}
2923 \\export fn e() void {3061 \\export fn e() void {
2924 \\ var y: *const u8 = undefined;3062 \\ var y: *const u8 = undefined;
2925 \\ var x: [*c]u8 = y;3063 \\ var x: [*c]u8 = y;
3064 \\ _ = x;
2926 \\}3065 \\}
2927 \\export fn f() void {3066 \\export fn f() void {
2928 \\ var y: *u8 = undefined;3067 \\ var y: *u8 = undefined;
2929 \\ var x: [*c]u32 = y;3068 \\ var x: [*c]u32 = y;
3069 \\ _ = x;
2930 \\}3070 \\}
2931 , &[_][]const u8{3071 , &[_][]const u8{
2932 "tmp.zig:3:27: error: cast increases pointer alignment",3072 "tmp.zig:3:27: error: cast increases pointer alignment",
2933 "tmp.zig:7:18: error: cast discards const qualifier",3073 "tmp.zig:8:18: error: cast discards const qualifier",
2934 "tmp.zig:11:19: error: expected type '*u32', found '[*c]u8'",3074 "tmp.zig:13:19: error: expected type '*u32', found '[*c]u8'",
2935 "tmp.zig:11:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'",3075 "tmp.zig:13:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'",
2936 "tmp.zig:15:22: error: cast increases pointer alignment",3076 "tmp.zig:18:22: error: cast increases pointer alignment",
2937 "tmp.zig:19:21: error: cast discards const qualifier",3077 "tmp.zig:23:21: error: cast discards const qualifier",
2938 "tmp.zig:23:22: error: expected type '[*c]u32', found '*u8'",3078 "tmp.zig:28:22: error: expected type '[*c]u32', found '*u8'",
2939 });3079 });
29403080
2941 cases.add("implicit casting null c pointer to zig pointer",3081 ctx.objErrStage1("implicit casting null c pointer to zig pointer",
2942 \\comptime {3082 \\comptime {
2943 \\ var c_ptr: [*c]u8 = 0;3083 \\ var c_ptr: [*c]u8 = 0;
2944 \\ var zig_ptr: *u8 = c_ptr;3084 \\ var zig_ptr: *u8 = c_ptr;
3085 \\ _ = zig_ptr;
2945 \\}3086 \\}
2946 , &[_][]const u8{3087 , &[_][]const u8{
2947 "tmp.zig:3:24: error: null pointer casted to type '*u8'",3088 "tmp.zig:3:24: error: null pointer casted to type '*u8'",
2948 });3089 });
29493090
2950 cases.add("implicit casting undefined c pointer to zig pointer",3091 ctx.objErrStage1("implicit casting undefined c pointer to zig pointer",
2951 \\comptime {3092 \\comptime {
2952 \\ var c_ptr: [*c]u8 = undefined;3093 \\ var c_ptr: [*c]u8 = undefined;
2953 \\ var zig_ptr: *u8 = c_ptr;3094 \\ var zig_ptr: *u8 = c_ptr;
3095 \\ _ = zig_ptr;
2954 \\}3096 \\}
2955 , &[_][]const u8{3097 , &[_][]const u8{
2956 "tmp.zig:3:24: error: use of undefined value here causes undefined behavior",3098 "tmp.zig:3:24: error: use of undefined value here causes undefined behavior",
2957 });3099 });
29583100
2959 cases.add("implicit casting C pointers which would mess up null semantics",3101 ctx.objErrStage1("implicit casting C pointers which would mess up null semantics",
2960 \\export fn entry() void {3102 \\export fn entry() void {
2961 \\ var slice: []const u8 = "aoeu";3103 \\ var slice: []const u8 = "aoeu";
2962 \\ const opt_many_ptr: [*]const u8 = slice.ptr;3104 \\ const opt_many_ptr: [*]const u8 = slice.ptr;
...@@ -2970,6 +3112,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2970,6 +3112,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2970 \\ var opt_many_ptr: [*]u8 = slice.ptr;3112 \\ var opt_many_ptr: [*]u8 = slice.ptr;
2971 \\ var ptr_opt_many_ptr = &opt_many_ptr;3113 \\ var ptr_opt_many_ptr = &opt_many_ptr;
2972 \\ var c_ptr: [*c][*c]const u8 = ptr_opt_many_ptr;3114 \\ var c_ptr: [*c][*c]const u8 = ptr_opt_many_ptr;
3115 \\ _ = c_ptr;
2973 \\}3116 \\}
2974 , &[_][]const u8{3117 , &[_][]const u8{
2975 "tmp.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",3118 "tmp.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
...@@ -2980,47 +3123,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2980,47 +3123,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2980 "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'",3123 "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'",
2981 });3124 });
29823125
2983 cases.add("implicit casting too big integers to C pointers",3126 ctx.objErrStage1("implicit casting too big integers to C pointers",
2984 \\export fn a() void {3127 \\export fn a() void {
2985 \\ var ptr: [*c]u8 = (1 << 64) + 1;3128 \\ var ptr: [*c]u8 = (1 << 64) + 1;
3129 \\ _ = ptr;
2986 \\}3130 \\}
2987 \\export fn b() void {3131 \\export fn b() void {
2988 \\ var x: u65 = 0x1234;3132 \\ var x: u65 = 0x1234;
2989 \\ var ptr: [*c]u8 = x;3133 \\ var ptr: [*c]u8 = x;
3134 \\ _ = ptr;
2990 \\}3135 \\}
2991 , &[_][]const u8{3136 , &[_][]const u8{
2992 "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'",3137 "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'",
2993 "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",3138 "tmp.zig:7:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",
2994 });3139 });
29953140
2996 cases.add("C pointer pointing to non C ABI compatible type or has align attr",3141 ctx.objErrStage1("C pointer pointing to non C ABI compatible type or has align attr",
2997 \\const Foo = struct {};3142 \\const Foo = struct {};
2998 \\export fn a() void {3143 \\export fn a() void {
2999 \\ const T = [*c]Foo;3144 \\ const T = [*c]Foo;
3000 \\ var t: T = undefined;3145 \\ var t: T = undefined;
3146 \\ _ = t;
3001 \\}3147 \\}
3002 , &[_][]const u8{3148 , &[_][]const u8{
3003 "tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",3149 "tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
3004 });3150 });
30053151
3006 cases.addCase(x: {3152 ctx.objErrStage1("compile log statement warning deduplication in generic fn",
3007 var tc = cases.create("compile log statement warning deduplication in generic fn",3153 \\export fn entry() void {
3008 \\export fn entry() void {3154 \\ inner(1);
3009 \\ inner(1);3155 \\ inner(2);
3010 \\ inner(2);3156 \\}
3011 \\}3157 \\fn inner(comptime n: usize) void {
3012 \\fn inner(comptime n: usize) void {3158 \\ comptime var i = 0;
3013 \\ comptime var i = 0;3159 \\ inline while (i < n) : (i += 1) { @compileLog("!@#$"); }
3014 \\ inline while (i < n) : (i += 1) { @compileLog("!@#$"); }3160 \\}
3015 \\}3161 , &[_][]const u8{
3016 , &[_][]const u8{3162 "tmp.zig:7:39: error: found compile log statement",
3017 "tmp.zig:7:39: error: found compile log statement",
3018 });
3019 tc.expect_exact = true;
3020 break :x tc;
3021 });3163 });
30223164
3023 cases.add("assign to invalid dereference",3165 ctx.objErrStage1("assign to invalid dereference",
3024 \\export fn entry() void {3166 \\export fn entry() void {
3025 \\ 'a'.* = 1;3167 \\ 'a'.* = 1;
3026 \\}3168 \\}
...@@ -3028,54 +3170,58 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3028,54 +3170,58 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3028 "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'",3170 "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'",
3029 });3171 });
30303172
3031 cases.add("take slice of invalid dereference",3173 ctx.objErrStage1("take slice of invalid dereference",
3032 \\export fn entry() void {3174 \\export fn entry() void {
3033 \\ const x = 'a'.*[0..];3175 \\ const x = 'a'.*[0..];
3176 \\ _ = x;
3034 \\}3177 \\}
3035 , &[_][]const u8{3178 , &[_][]const u8{
3036 "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'",3179 "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'",
3037 });3180 });
30383181
3039 cases.add("@truncate undefined value",3182 ctx.objErrStage1("@truncate undefined value",
3040 \\export fn entry() void {3183 \\export fn entry() void {
3041 \\ var z = @truncate(u8, @as(u16, undefined));3184 \\ var z = @truncate(u8, @as(u16, undefined));
3185 \\ _ = z;
3042 \\}3186 \\}
3043 , &[_][]const u8{3187 , &[_][]const u8{
3044 "tmp.zig:2:27: error: use of undefined value here causes undefined behavior",3188 "tmp.zig:2:27: error: use of undefined value here causes undefined behavior",
3045 });3189 });
30463190
3047 cases.addTest("return invalid type from test",3191 ctx.testErrStage1("return invalid type from test",
3048 \\test "example" { return 1; }3192 \\test "example" { return 1; }
3049 , &[_][]const u8{3193 , &[_][]const u8{
3050 "tmp.zig:1:25: error: expected type 'void', found 'comptime_int'",3194 "tmp.zig:1:25: error: expected type 'void', found 'comptime_int'",
3051 });3195 });
30523196
3053 cases.add("threadlocal qualifier on const",3197 ctx.objErrStage1("threadlocal qualifier on const",
3054 \\threadlocal const x: i32 = 1234;3198 \\threadlocal const x: i32 = 1234;
3055 \\export fn entry() i32 {3199 \\export fn entry() i32 {
3056 \\ return x;3200 \\ return x;
3057 \\}3201 \\}
3058 , &[_][]const u8{3202 , &[_][]const u8{
3059 "tmp.zig:1:13: error: threadlocal variable cannot be constant",3203 "tmp.zig:1:1: error: threadlocal variable cannot be constant",
3060 });3204 });
30613205
3062 cases.add("@bitCast same size but bit count mismatch",3206 ctx.objErrStage1("@bitCast same size but bit count mismatch",
3063 \\export fn entry(byte: u8) void {3207 \\export fn entry(byte: u8) void {
3064 \\ var oops = @bitCast(u7, byte);3208 \\ var oops = @bitCast(u7, byte);
3209 \\ _ = oops;
3065 \\}3210 \\}
3066 , &[_][]const u8{3211 , &[_][]const u8{
3067 "tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",3212 "tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
3068 });3213 });
30693214
3070 cases.add("@bitCast with different sizes inside an expression",3215 ctx.objErrStage1("@bitCast with different sizes inside an expression",
3071 \\export fn entry() void {3216 \\export fn entry() void {
3072 \\ var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf);3217 \\ var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf);
3218 \\ _ = foo;
3073 \\}3219 \\}
3074 , &[_][]const u8{3220 , &[_][]const u8{
3075 "tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4",3221 "tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4",
3076 });3222 });
30773223
3078 cases.add("attempted `&&`",3224 ctx.objErrStage1("attempted `&&`",
3079 \\export fn entry(a: bool, b: bool) i32 {3225 \\export fn entry(a: bool, b: bool) i32 {
3080 \\ if (a && b) {3226 \\ if (a && b) {
3081 \\ return 1234;3227 \\ return 1234;
...@@ -3083,10 +3229,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3083,10 +3229,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3083 \\ return 5678;3229 \\ return 5678;
3084 \\}3230 \\}
3085 , &[_][]const u8{3231 , &[_][]const u8{
3086 "tmp.zig:2:12: error: `&&` is invalid. Note that `and` is boolean AND",3232 "tmp.zig:2:11: error: `&&` is invalid; note that `and` is boolean AND",
3087 });3233 });
30883234
3089 cases.add("attempted `||` on boolean values",3235 ctx.objErrStage1("attempted `||` on boolean values",
3090 \\export fn entry(a: bool, b: bool) i32 {3236 \\export fn entry(a: bool, b: bool) i32 {
3091 \\ if (a || b) {3237 \\ if (a || b) {
3092 \\ return 1234;3238 \\ return 1234;
...@@ -3098,7 +3244,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3098,7 +3244,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3098 "tmp.zig:2:11: note: `||` merges error sets; `or` performs boolean OR",3244 "tmp.zig:2:11: note: `||` merges error sets; `or` performs boolean OR",
3099 });3245 });
31003246
3101 cases.add("compile log a pointer to an opaque value",3247 ctx.objErrStage1("compile log a pointer to an opaque value",
3102 \\export fn entry() void {3248 \\export fn entry() void {
3103 \\ @compileLog(@ptrCast(*const c_void, &entry));3249 \\ @compileLog(@ptrCast(*const c_void, &entry));
3104 \\}3250 \\}
...@@ -3106,13 +3252,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3106,13 +3252,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3106 "tmp.zig:2:5: error: found compile log statement",3252 "tmp.zig:2:5: error: found compile log statement",
3107 });3253 });
31083254
3109 cases.add("duplicate boolean switch value",3255 ctx.objErrStage1("duplicate boolean switch value",
3110 \\comptime {3256 \\comptime {
3111 \\ const x = switch (true) {3257 \\ const x = switch (true) {
3112 \\ true => false,3258 \\ true => false,
3113 \\ false => true,3259 \\ false => true,
3114 \\ true => false,3260 \\ true => false,
3115 \\ };3261 \\ };
3262 \\ _ = x;
3116 \\}3263 \\}
3117 \\comptime {3264 \\comptime {
3118 \\ const x = switch (true) {3265 \\ const x = switch (true) {
...@@ -3120,42 +3267,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3120,42 +3267,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3120 \\ true => false,3267 \\ true => false,
3121 \\ false => true,3268 \\ false => true,
3122 \\ };3269 \\ };
3270 \\ _ = x;
3123 \\}3271 \\}
3124 , &[_][]const u8{3272 , &[_][]const u8{
3125 "tmp.zig:5:9: error: duplicate switch value",3273 "tmp.zig:5:9: error: duplicate switch value",
3126 "tmp.zig:12:9: error: duplicate switch value",3274 "tmp.zig:13:9: error: duplicate switch value",
3127 });3275 });
31283276
3129 cases.add("missing boolean switch value",3277 ctx.objErrStage1("missing boolean switch value",
3130 \\comptime {3278 \\comptime {
3131 \\ const x = switch (true) {3279 \\ const x = switch (true) {
3132 \\ true => false,3280 \\ true => false,
3133 \\ };3281 \\ };
3282 \\ _ = x;
3134 \\}3283 \\}
3135 \\comptime {3284 \\comptime {
3136 \\ const x = switch (true) {3285 \\ const x = switch (true) {
3137 \\ false => true,3286 \\ false => true,
3138 \\ };3287 \\ };
3288 \\ _ = x;
3139 \\}3289 \\}
3140 , &[_][]const u8{3290 , &[_][]const u8{
3141 "tmp.zig:2:15: error: switch must handle all possibilities",3291 "tmp.zig:2:15: error: switch must handle all possibilities",
3142 "tmp.zig:7:15: error: switch must handle all possibilities",3292 "tmp.zig:8:15: error: switch must handle all possibilities",
3143 });3293 });
31443294
3145 cases.add("reading past end of pointer casted array",3295 ctx.objErrStage1("reading past end of pointer casted array",
3146 \\comptime {3296 \\comptime {
3147 \\ const array: [4]u8 = "aoeu".*;3297 \\ const array: [4]u8 = "aoeu".*;
3148 \\ const sub_array = array[1..];3298 \\ const sub_array = array[1..];
3149 \\ const int_ptr = @ptrCast(*const u24, sub_array);3299 \\ const int_ptr = @ptrCast(*const u24, sub_array);
3150 \\ const deref = int_ptr.*;3300 \\ const deref = int_ptr.*;
3301 \\ _ = deref;
3151 \\}3302 \\}
3152 , &[_][]const u8{3303 , &[_][]const u8{
3153 "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes",3304 "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes",
3154 });3305 });
31553306
3156 cases.add("error note for function parameter incompatibility",3307 ctx.objErrStage1("error note for function parameter incompatibility",
3157 \\fn do_the_thing(func: fn (arg: i32) void) void {}3308 \\fn do_the_thing(func: fn (arg: i32) void) void { _ = func; }
3158 \\fn bar(arg: bool) void {}3309 \\fn bar(arg: bool) void { _ = arg; }
3159 \\export fn entry() void {3310 \\export fn entry() void {
3160 \\ do_the_thing(bar);3311 \\ do_the_thing(bar);
3161 \\}3312 \\}
...@@ -3163,56 +3314,63 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3163,56 +3314,63 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3163 "tmp.zig:4:18: error: expected type 'fn(i32) void', found 'fn(bool) void",3314 "tmp.zig:4:18: error: expected type 'fn(i32) void', found 'fn(bool) void",
3164 "tmp.zig:4:18: note: parameter 0: 'bool' cannot cast into 'i32'",3315 "tmp.zig:4:18: note: parameter 0: 'bool' cannot cast into 'i32'",
3165 });3316 });
3166 cases.add("cast negative value to unsigned integer",3317 ctx.objErrStage1("cast negative value to unsigned integer",
3167 \\comptime {3318 \\comptime {
3168 \\ const value: i32 = -1;3319 \\ const value: i32 = -1;
3169 \\ const unsigned = @intCast(u32, value);3320 \\ const unsigned = @intCast(u32, value);
3321 \\ _ = unsigned;
3170 \\}3322 \\}
3171 \\export fn entry1() void {3323 \\export fn entry1() void {
3172 \\ const value: i32 = -1;3324 \\ const value: i32 = -1;
3173 \\ const unsigned: u32 = value;3325 \\ const unsigned: u32 = value;
3326 \\ _ = unsigned;
3174 \\}3327 \\}
3175 , &[_][]const u8{3328 , &[_][]const u8{
3176 "tmp.zig:3:22: error: attempt to cast negative value to unsigned integer",3329 "tmp.zig:3:22: error: attempt to cast negative value to unsigned integer",
3177 "tmp.zig:7:27: error: cannot cast negative value -1 to unsigned integer type 'u32'",3330 "tmp.zig:8:27: error: cannot cast negative value -1 to unsigned integer type 'u32'",
3178 });3331 });
31793332
3180 cases.add("integer cast truncates bits",3333 ctx.objErrStage1("integer cast truncates bits",
3181 \\export fn entry1() void {3334 \\export fn entry1() void {
3182 \\ const spartan_count: u16 = 300;3335 \\ const spartan_count: u16 = 300;
3183 \\ const byte = @intCast(u8, spartan_count);3336 \\ const byte = @intCast(u8, spartan_count);
3337 \\ _ = byte;
3184 \\}3338 \\}
3185 \\export fn entry2() void {3339 \\export fn entry2() void {
3186 \\ const spartan_count: u16 = 300;3340 \\ const spartan_count: u16 = 300;
3187 \\ const byte: u8 = spartan_count;3341 \\ const byte: u8 = spartan_count;
3342 \\ _ = byte;
3188 \\}3343 \\}
3189 \\export fn entry3() void {3344 \\export fn entry3() void {
3190 \\ var spartan_count: u16 = 300;3345 \\ var spartan_count: u16 = 300;
3191 \\ var byte: u8 = spartan_count;3346 \\ var byte: u8 = spartan_count;
3347 \\ _ = byte;
3192 \\}3348 \\}
3193 \\export fn entry4() void {3349 \\export fn entry4() void {
3194 \\ var signed: i8 = -1;3350 \\ var signed: i8 = -1;
3195 \\ var unsigned: u64 = signed;3351 \\ var unsigned: u64 = signed;
3352 \\ _ = unsigned;
3196 \\}3353 \\}
3197 , &[_][]const u8{3354 , &[_][]const u8{
3198 "tmp.zig:3:18: error: cast from 'u16' to 'u8' truncates bits",3355 "tmp.zig:3:18: error: cast from 'u16' to 'u8' truncates bits",
3199 "tmp.zig:7:22: error: integer value 300 cannot be coerced to type 'u8'",3356 "tmp.zig:8:22: error: integer value 300 cannot be coerced to type 'u8'",
3200 "tmp.zig:11:20: error: expected type 'u8', found 'u16'",3357 "tmp.zig:13:20: error: expected type 'u8', found 'u16'",
3201 "tmp.zig:11:20: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values",3358 "tmp.zig:13:20: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values",
3202 "tmp.zig:15:25: error: expected type 'u64', found 'i8'",3359 "tmp.zig:18:25: error: expected type 'u64', found 'i8'",
3203 "tmp.zig:15:25: note: unsigned 64-bit int cannot represent all possible signed 8-bit values",3360 "tmp.zig:18:25: note: unsigned 64-bit int cannot represent all possible signed 8-bit values",
3204 });3361 });
32053362
3206 cases.add("comptime implicit cast f64 to f32",3363 ctx.objErrStage1("comptime implicit cast f64 to f32",
3207 \\export fn entry() void {3364 \\export fn entry() void {
3208 \\ const x: f64 = 16777217;3365 \\ const x: f64 = 16777217;
3209 \\ const y: f32 = x;3366 \\ const y: f32 = x;
3367 \\ _ = y;
3210 \\}3368 \\}
3211 , &[_][]const u8{3369 , &[_][]const u8{
3212 "tmp.zig:3:20: error: cast of value 16777217.000000 to type 'f32' loses information",3370 "tmp.zig:3:20: error: cast of value 16777217.000000 to type 'f32' loses information",
3213 });3371 });
32143372
3215 cases.add("implicit cast from f64 to f32",3373 ctx.objErrStage1("implicit cast from f64 to f32",
3216 \\var x: f64 = 1.0;3374 \\var x: f64 = 1.0;
3217 \\var y: f32 = x;3375 \\var y: f32 = x;
3218 \\3376 \\
...@@ -3221,41 +3379,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3221,41 +3379,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3221 "tmp.zig:2:14: error: expected type 'f32', found 'f64'",3379 "tmp.zig:2:14: error: expected type 'f32', found 'f64'",
3222 });3380 });
32233381
3224 cases.add("exceeded maximum bit width of integer",3382 ctx.objErrStage1("exceeded maximum bit width of integer",
3225 \\export fn entry1() void {3383 \\export fn entry1() void {
3226 \\ const T = u65536;3384 \\ const T = u65536;
3385 \\ _ = T;
3227 \\}3386 \\}
3228 \\export fn entry2() void {3387 \\export fn entry2() void {
3229 \\ var x: i65536 = 1;3388 \\ var x: i65536 = 1;
3389 \\ _ = x;
3230 \\}3390 \\}
3231 , &[_][]const u8{3391 , &[_][]const u8{
3232 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",3392 "tmp.zig:2:15: error: primitive integer type 'u65536' exceeds maximum bit width of 65535",
3393 "tmp.zig:6:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",
3233 });3394 });
32343395
3235 cases.add("compile error when evaluating return type of inferred error set",3396 ctx.objErrStage1("compile error when evaluating return type of inferred error set",
3236 \\const Car = struct {3397 \\const Car = struct {
3237 \\ foo: *SymbolThatDoesNotExist,3398 \\ foo: *SymbolThatDoesNotExist,
3238 \\ pub fn init() !Car {}3399 \\ pub fn init() !Car {}
3239 \\};3400 \\};
3240 \\export fn entry() void {3401 \\export fn entry() void {
3241 \\ const car = Car.init();3402 \\ const car = Car.init();
3403 \\ _ = car;
3242 \\}3404 \\}
3243 , &[_][]const u8{3405 , &[_][]const u8{
3244 "tmp.zig:2:11: error: use of undeclared identifier 'SymbolThatDoesNotExist'",3406 "tmp.zig:2:11: error: use of undeclared identifier 'SymbolThatDoesNotExist'",
3245 });3407 });
32463408
3247 cases.add("don't implicit cast double pointer to *c_void",3409 ctx.objErrStage1("don't implicit cast double pointer to *c_void",
3248 \\export fn entry() void {3410 \\export fn entry() void {
3249 \\ var a: u32 = 1;3411 \\ var a: u32 = 1;
3250 \\ var ptr: *align(@alignOf(u32)) c_void = &a;3412 \\ var ptr: *align(@alignOf(u32)) c_void = &a;
3251 \\ var b: *u32 = @ptrCast(*u32, ptr);3413 \\ var b: *u32 = @ptrCast(*u32, ptr);
3252 \\ var ptr2: *c_void = &b;3414 \\ var ptr2: *c_void = &b;
3415 \\ _ = ptr2;
3253 \\}3416 \\}
3254 , &[_][]const u8{3417 , &[_][]const u8{
3255 "tmp.zig:5:26: error: expected type '*c_void', found '**u32'",3418 "tmp.zig:5:26: error: expected type '*c_void', found '**u32'",
3256 });3419 });
32573420
3258 cases.add("runtime index into comptime type slice",3421 ctx.objErrStage1("runtime index into comptime type slice",
3259 \\const Struct = struct {3422 \\const Struct = struct {
3260 \\ a: u32,3423 \\ a: u32,
3261 \\};3424 \\};
...@@ -3265,12 +3428,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3265,12 +3428,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3265 \\export fn entry() void {3428 \\export fn entry() void {
3266 \\ const index = getIndex();3429 \\ const index = getIndex();
3267 \\ const field = @typeInfo(Struct).Struct.fields[index];3430 \\ const field = @typeInfo(Struct).Struct.fields[index];
3431 \\ _ = field;
3268 \\}3432 \\}
3269 , &[_][]const u8{3433 , &[_][]const u8{
3270 "tmp.zig:9:51: error: values of type 'std.builtin.StructField' must be comptime known, but index value is runtime known",3434 "tmp.zig:9:51: error: values of type 'std.builtin.StructField' must be comptime known, but index value is runtime known",
3271 });3435 });
32723436
3273 cases.add("compile log statement inside function which must be comptime evaluated",3437 ctx.objErrStage1("compile log statement inside function which must be comptime evaluated",
3274 \\fn Foo(comptime T: type) type {3438 \\fn Foo(comptime T: type) type {
3275 \\ @compileLog(@typeName(T));3439 \\ @compileLog(@typeName(T));
3276 \\ return T;3440 \\ return T;
...@@ -3283,25 +3447,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3283,25 +3447,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3283 "tmp.zig:2:5: error: found compile log statement",3447 "tmp.zig:2:5: error: found compile log statement",
3284 });3448 });
32853449
3286 cases.add("comptime slice of an undefined slice",3450 ctx.objErrStage1("comptime slice of an undefined slice",
3287 \\comptime {3451 \\comptime {
3288 \\ var a: []u8 = undefined;3452 \\ var a: []u8 = undefined;
3289 \\ var b = a[0..10];3453 \\ var b = a[0..10];
3454 \\ _ = b;
3290 \\}3455 \\}
3291 , &[_][]const u8{3456 , &[_][]const u8{
3292 "tmp.zig:3:14: error: slice of undefined",3457 "tmp.zig:3:14: error: slice of undefined",
3293 });3458 });
32943459
3295 cases.add("implicit cast const array to mutable slice",3460 ctx.objErrStage1("implicit cast const array to mutable slice",
3296 \\export fn entry() void {3461 \\export fn entry() void {
3297 \\ const buffer: [1]u8 = [_]u8{8};3462 \\ const buffer: [1]u8 = [_]u8{8};
3298 \\ const sliceA: []u8 = &buffer;3463 \\ const sliceA: []u8 = &buffer;
3464 \\ _ = sliceA;
3299 \\}3465 \\}
3300 , &[_][]const u8{3466 , &[_][]const u8{
3301 "tmp.zig:3:27: error: expected type '[]u8', found '*const [1]u8'",3467 "tmp.zig:3:27: error: expected type '[]u8', found '*const [1]u8'",
3302 });3468 });
33033469
3304 cases.add("deref slice and get len field",3470 ctx.objErrStage1("deref slice and get len field",
3305 \\export fn entry() void {3471 \\export fn entry() void {
3306 \\ var a: []u8 = undefined;3472 \\ var a: []u8 = undefined;
3307 \\ _ = a.*.len;3473 \\ _ = a.*.len;
...@@ -3310,7 +3476,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3310,7 +3476,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3310 "tmp.zig:3:10: error: attempt to dereference non-pointer type '[]u8'",3476 "tmp.zig:3:10: error: attempt to dereference non-pointer type '[]u8'",
3311 });3477 });
33123478
3313 cases.add("@ptrCast a 0 bit type to a non- 0 bit type",3479 ctx.objErrStage1("@ptrCast a 0 bit type to a non- 0 bit type",
3314 \\export fn entry() bool {3480 \\export fn entry() bool {
3315 \\ var x: u0 = 0;3481 \\ var x: u0 = 0;
3316 \\ const p = @ptrCast(?*u0, &x);3482 \\ const p = @ptrCast(?*u0, &x);
...@@ -3322,7 +3488,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3322,7 +3488,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3322 "tmp.zig:3:24: note: '?*u0' has in-memory bits",3488 "tmp.zig:3:24: note: '?*u0' has in-memory bits",
3323 });3489 });
33243490
3325 cases.add("comparing a non-optional pointer against null",3491 ctx.objErrStage1("comparing a non-optional pointer against null",
3326 \\export fn entry() void {3492 \\export fn entry() void {
3327 \\ var x: i32 = 1;3493 \\ var x: i32 = 1;
3328 \\ _ = &x == null;3494 \\ _ = &x == null;
...@@ -3331,21 +3497,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3331,21 +3497,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3331 "tmp.zig:3:12: error: comparison of '*i32' with null",3497 "tmp.zig:3:12: error: comparison of '*i32' with null",
3332 });3498 });
33333499
3334 cases.add("non error sets used in merge error sets operator",3500 ctx.objErrStage1("non error sets used in merge error sets operator",
3335 \\export fn foo() void {3501 \\export fn foo() void {
3336 \\ const Errors = u8 || u16;3502 \\ const Errors = u8 || u16;
3503 \\ _ = Errors;
3337 \\}3504 \\}
3338 \\export fn bar() void {3505 \\export fn bar() void {
3339 \\ const Errors = error{} || u16;3506 \\ const Errors = error{} || u16;
3507 \\ _ = Errors;
3340 \\}3508 \\}
3341 , &[_][]const u8{3509 , &[_][]const u8{
3342 "tmp.zig:2:20: error: expected error set type, found type 'u8'",3510 "tmp.zig:2:20: error: expected error set type, found type 'u8'",
3343 "tmp.zig:2:23: note: `||` merges error sets; `or` performs boolean OR",3511 "tmp.zig:2:23: note: `||` merges error sets; `or` performs boolean OR",
3344 "tmp.zig:5:31: error: expected error set type, found type 'u16'",3512 "tmp.zig:6:31: error: expected error set type, found type 'u16'",
3345 "tmp.zig:5:28: note: `||` merges error sets; `or` performs boolean OR",3513 "tmp.zig:6:28: note: `||` merges error sets; `or` performs boolean OR",
3346 });3514 });
33473515
3348 cases.add("variable initialization compile error then referenced",3516 ctx.objErrStage1("variable initialization compile error then referenced",
3349 \\fn Undeclared() type {3517 \\fn Undeclared() type {
3350 \\ return T;3518 \\ return T;
3351 \\}3519 \\}
...@@ -3357,12 +3525,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3357,12 +3525,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3357 \\}3525 \\}
3358 \\export fn entry() void {3526 \\export fn entry() void {
3359 \\ const S = Gen();3527 \\ const S = Gen();
3528 \\ _ = S;
3360 \\}3529 \\}
3361 , &[_][]const u8{3530 , &[_][]const u8{
3362 "tmp.zig:2:12: error: use of undeclared identifier 'T'",3531 "tmp.zig:2:12: error: use of undeclared identifier 'T'",
3363 });3532 });
33643533
3365 cases.add("refer to the type of a generic function",3534 ctx.objErrStage1("refer to the type of a generic function",
3366 \\export fn entry() void {3535 \\export fn entry() void {
3367 \\ const Func = fn (type) void;3536 \\ const Func = fn (type) void;
3368 \\ const f: Func = undefined;3537 \\ const f: Func = undefined;
...@@ -3372,7 +3541,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3372,7 +3541,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3372 "tmp.zig:4:5: error: use of undefined value here causes undefined behavior",3541 "tmp.zig:4:5: error: use of undefined value here causes undefined behavior",
3373 });3542 });
33743543
3375 cases.add("accessing runtime parameter from outer function",3544 ctx.objErrStage1("accessing runtime parameter from outer function",
3376 \\fn outer(y: u32) fn (u32) u32 {3545 \\fn outer(y: u32) fn (u32) u32 {
3377 \\ const st = struct {3546 \\ const st = struct {
3378 \\ fn get(z: u32) u32 {3547 \\ fn get(z: u32) u32 {
...@@ -3384,6 +3553,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3384,6 +3553,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3384 \\export fn entry() void {3553 \\export fn entry() void {
3385 \\ var func = outer(10);3554 \\ var func = outer(10);
3386 \\ var x = func(3);3555 \\ var x = func(3);
3556 \\ _ = x;
3387 \\}3557 \\}
3388 , &[_][]const u8{3558 , &[_][]const u8{
3389 "tmp.zig:4:24: error: 'y' not accessible from inner function",3559 "tmp.zig:4:24: error: 'y' not accessible from inner function",
...@@ -3391,69 +3561,74 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3391,69 +3561,74 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3391 "tmp.zig:1:10: note: declared here",3561 "tmp.zig:1:10: note: declared here",
3392 });3562 });
33933563
3394 cases.add("non int passed to @intToFloat",3564 ctx.objErrStage1("non int passed to @intToFloat",
3395 \\export fn entry() void {3565 \\export fn entry() void {
3396 \\ const x = @intToFloat(f32, 1.1);3566 \\ const x = @intToFloat(f32, 1.1);
3567 \\ _ = x;
3397 \\}3568 \\}
3398 , &[_][]const u8{3569 , &[_][]const u8{
3399 "tmp.zig:2:32: error: expected int type, found 'comptime_float'",3570 "tmp.zig:2:32: error: expected int type, found 'comptime_float'",
3400 });3571 });
34013572
3402 cases.add("non float passed to @floatToInt",3573 ctx.objErrStage1("non float passed to @floatToInt",
3403 \\export fn entry() void {3574 \\export fn entry() void {
3404 \\ const x = @floatToInt(i32, @as(i32, 54));3575 \\ const x = @floatToInt(i32, @as(i32, 54));
3576 \\ _ = x;
3405 \\}3577 \\}
3406 , &[_][]const u8{3578 , &[_][]const u8{
3407 "tmp.zig:2:32: error: expected float type, found 'i32'",3579 "tmp.zig:2:32: error: expected float type, found 'i32'",
3408 });3580 });
34093581
3410 cases.add("out of range comptime_int passed to @floatToInt",3582 ctx.objErrStage1("out of range comptime_int passed to @floatToInt",
3411 \\export fn entry() void {3583 \\export fn entry() void {
3412 \\ const x = @floatToInt(i8, 200);3584 \\ const x = @floatToInt(i8, 200);
3585 \\ _ = x;
3413 \\}3586 \\}
3414 , &[_][]const u8{3587 , &[_][]const u8{
3415 "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'",3588 "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'",
3416 });3589 });
34173590
3418 cases.add("load too many bytes from comptime reinterpreted pointer",3591 ctx.objErrStage1("load too many bytes from comptime reinterpreted pointer",
3419 \\export fn entry() void {3592 \\export fn entry() void {
3420 \\ const float: f32 = 5.99999999999994648725e-01;3593 \\ const float: f32 = 5.99999999999994648725e-01;
3421 \\ const float_ptr = &float;3594 \\ const float_ptr = &float;
3422 \\ const int_ptr = @ptrCast(*const i64, float_ptr);3595 \\ const int_ptr = @ptrCast(*const i64, float_ptr);
3423 \\ const int_val = int_ptr.*;3596 \\ const int_val = int_ptr.*;
3597 \\ _ = int_val;
3424 \\}3598 \\}
3425 , &[_][]const u8{3599 , &[_][]const u8{
3426 "tmp.zig:5:28: error: attempt to read 8 bytes from pointer to f32 which is 4 bytes",3600 "tmp.zig:5:28: error: attempt to read 8 bytes from pointer to f32 which is 4 bytes",
3427 });3601 });
34283602
3429 cases.add("invalid type used in array type",3603 ctx.objErrStage1("invalid type used in array type",
3430 \\const Item = struct {3604 \\const Item = struct {
3431 \\ field: SomeNonexistentType,3605 \\ field: SomeNonexistentType,
3432 \\};3606 \\};
3433 \\var items: [100]Item = undefined;3607 \\var items: [100]Item = undefined;
3434 \\export fn entry() void {3608 \\export fn entry() void {
3435 \\ const a = items[0];3609 \\ const a = items[0];
3610 \\ _ = a;
3436 \\}3611 \\}
3437 , &[_][]const u8{3612 , &[_][]const u8{
3438 "tmp.zig:2:12: error: use of undeclared identifier 'SomeNonexistentType'",3613 "tmp.zig:2:12: error: use of undeclared identifier 'SomeNonexistentType'",
3439 });3614 });
34403615
3441 cases.add("comptime continue inside runtime catch",3616 ctx.objErrStage1("comptime continue inside runtime catch",
3442 \\export fn entry(c: bool) void {3617 \\export fn entry() void {
3443 \\ const ints = [_]u8{ 1, 2 };3618 \\ const ints = [_]u8{ 1, 2 };
3444 \\ inline for (ints) |_| {3619 \\ inline for (ints) |_| {
3445 \\ bad() catch |_| continue;3620 \\ bad() catch continue;
3446 \\ }3621 \\ }
3447 \\}3622 \\}
3448 \\fn bad() !void {3623 \\fn bad() !void {
3449 \\ return error.Bad;3624 \\ return error.Bad;
3450 \\}3625 \\}
3451 , &[_][]const u8{3626 , &[_][]const u8{
3452 "tmp.zig:4:25: error: comptime control flow inside runtime block",3627 "tmp.zig:4:21: error: comptime control flow inside runtime block",
3453 "tmp.zig:4:15: note: runtime block created here",3628 "tmp.zig:4:15: note: runtime block created here",
3454 });3629 });
34553630
3456 cases.add("comptime continue inside runtime switch",3631 ctx.objErrStage1("comptime continue inside runtime switch",
3457 \\export fn entry() void {3632 \\export fn entry() void {
3458 \\ var p: i32 = undefined;3633 \\ var p: i32 = undefined;
3459 \\ comptime var q = true;3634 \\ comptime var q = true;
...@@ -3470,7 +3645,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3470,7 +3645,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3470 "tmp.zig:5:9: note: runtime block created here",3645 "tmp.zig:5:9: note: runtime block created here",
3471 });3646 });
34723647
3473 cases.add("comptime continue inside runtime while error",3648 ctx.objErrStage1("comptime continue inside runtime while error",
3474 \\export fn entry() void {3649 \\export fn entry() void {
3475 \\ var p: anyerror!usize = undefined;3650 \\ var p: anyerror!usize = undefined;
3476 \\ comptime var q = true;3651 \\ comptime var q = true;
...@@ -3486,7 +3661,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3486,7 +3661,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3486 "tmp.zig:5:9: note: runtime block created here",3661 "tmp.zig:5:9: note: runtime block created here",
3487 });3662 });
34883663
3489 cases.add("comptime continue inside runtime while optional",3664 ctx.objErrStage1("comptime continue inside runtime while optional",
3490 \\export fn entry() void {3665 \\export fn entry() void {
3491 \\ var p: ?usize = undefined;3666 \\ var p: ?usize = undefined;
3492 \\ comptime var q = true;3667 \\ comptime var q = true;
...@@ -3500,7 +3675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3500,7 +3675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3500 "tmp.zig:5:9: note: runtime block created here",3675 "tmp.zig:5:9: note: runtime block created here",
3501 });3676 });
35023677
3503 cases.add("comptime continue inside runtime while bool",3678 ctx.objErrStage1("comptime continue inside runtime while bool",
3504 \\export fn entry() void {3679 \\export fn entry() void {
3505 \\ var p: usize = undefined;3680 \\ var p: usize = undefined;
3506 \\ comptime var q = true;3681 \\ comptime var q = true;
...@@ -3514,7 +3689,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3514,7 +3689,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3514 "tmp.zig:5:9: note: runtime block created here",3689 "tmp.zig:5:9: note: runtime block created here",
3515 });3690 });
35163691
3517 cases.add("comptime continue inside runtime if error",3692 ctx.objErrStage1("comptime continue inside runtime if error",
3518 \\export fn entry() void {3693 \\export fn entry() void {
3519 \\ var p: anyerror!i32 = undefined;3694 \\ var p: anyerror!i32 = undefined;
3520 \\ comptime var q = true;3695 \\ comptime var q = true;
...@@ -3528,7 +3703,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3528,7 +3703,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3528 "tmp.zig:5:9: note: runtime block created here",3703 "tmp.zig:5:9: note: runtime block created here",
3529 });3704 });
35303705
3531 cases.add("comptime continue inside runtime if optional",3706 ctx.objErrStage1("comptime continue inside runtime if optional",
3532 \\export fn entry() void {3707 \\export fn entry() void {
3533 \\ var p: ?i32 = undefined;3708 \\ var p: ?i32 = undefined;
3534 \\ comptime var q = true;3709 \\ comptime var q = true;
...@@ -3542,7 +3717,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3542,7 +3717,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3542 "tmp.zig:5:9: note: runtime block created here",3717 "tmp.zig:5:9: note: runtime block created here",
3543 });3718 });
35443719
3545 cases.add("comptime continue inside runtime if bool",3720 ctx.objErrStage1("comptime continue inside runtime if bool",
3546 \\export fn entry() void {3721 \\export fn entry() void {
3547 \\ var p: usize = undefined;3722 \\ var p: usize = undefined;
3548 \\ comptime var q = true;3723 \\ comptime var q = true;
...@@ -3556,22 +3731,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3556,22 +3731,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3556 "tmp.zig:5:9: note: runtime block created here",3731 "tmp.zig:5:9: note: runtime block created here",
3557 });3732 });
35583733
3559 cases.add("switch with invalid expression parameter",3734 ctx.objErrStage1("switch with invalid expression parameter",
3560 \\export fn entry() void {3735 \\export fn entry() void {
3561 \\ Test(i32);3736 \\ Test(i32);
3562 \\}3737 \\}
3563 \\fn Test(comptime T: type) void {3738 \\fn Test(comptime T: type) void {
3564 \\ const x = switch (T) {3739 \\ const x = switch (T) {
3565 \\ []u8 => |x| 123,3740 \\ []u8 => |x| x,
3566 \\ i32 => |x| 456,3741 \\ i32 => |x| x,
3567 \\ else => unreachable,3742 \\ else => unreachable,
3568 \\ };3743 \\ };
3744 \\ _ = x;
3569 \\}3745 \\}
3570 , &[_][]const u8{3746 , &[_][]const u8{
3571 "tmp.zig:7:17: error: switch on type 'type' provides no expression parameter",3747 "tmp.zig:7:17: error: switch on type 'type' provides no expression parameter",
3572 });3748 });
35733749
3574 cases.add("function prototype with no body",3750 ctx.objErrStage1("function prototype with no body",
3575 \\fn foo() void;3751 \\fn foo() void;
3576 \\export fn entry() void {3752 \\export fn entry() void {
3577 \\ foo();3753 \\ foo();
...@@ -3580,7 +3756,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3580,7 +3756,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3580 "tmp.zig:1:1: error: non-extern function has no body",3756 "tmp.zig:1:1: error: non-extern function has no body",
3581 });3757 });
35823758
3583 cases.add("@frame() called outside of function definition",3759 ctx.objErrStage1("@frame() called outside of function definition",
3584 \\var handle_undef: anyframe = undefined;3760 \\var handle_undef: anyframe = undefined;
3585 \\var handle_dummy: anyframe = @frame();3761 \\var handle_dummy: anyframe = @frame();
3586 \\export fn entry() bool {3762 \\export fn entry() bool {
...@@ -3590,16 +3766,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3590,16 +3766,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3590 "tmp.zig:2:30: error: @frame() called outside of function definition",3766 "tmp.zig:2:30: error: @frame() called outside of function definition",
3591 });3767 });
35923768
3593 cases.add("`_` is not a declarable symbol",3769 ctx.objErrStage1("`_` is not a declarable symbol",
3594 \\export fn f1() usize {3770 \\export fn f1() usize {
3595 \\ var _: usize = 2;3771 \\ var _: usize = 2;
3596 \\ return _;3772 \\ return _;
3597 \\}3773 \\}
3598 , &[_][]const u8{3774 , &[_][]const u8{
3599 "tmp.zig:2:5: error: `_` is not a declarable symbol",3775 "tmp.zig:2:9: error: '_' used as an identifier without @\"_\" syntax",
3600 });3776 });
36013777
3602 cases.add("`_` should not be usable inside for",3778 ctx.objErrStage1("`_` should not be usable inside for",
3603 \\export fn returns() void {3779 \\export fn returns() void {
3604 \\ for ([_]void{}) |_, i| {3780 \\ for ([_]void{}) |_, i| {
3605 \\ for ([_]void{}) |_, j| {3781 \\ for ([_]void{}) |_, j| {
...@@ -3608,10 +3784,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3608,10 +3784,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3608 \\ }3784 \\ }
3609 \\}3785 \\}
3610 , &[_][]const u8{3786 , &[_][]const u8{
3611 "tmp.zig:4:20: error: `_` may only be used to assign things to",3787 "tmp.zig:4:20: error: '_' used as an identifier without @\"_\" syntax",
3612 });3788 });
36133789
3614 cases.add("`_` should not be usable inside while",3790 ctx.objErrStage1("`_` should not be usable inside while",
3615 \\export fn returns() void {3791 \\export fn returns() void {
3616 \\ while (optionalReturn()) |_| {3792 \\ while (optionalReturn()) |_| {
3617 \\ while (optionalReturn()) |_| {3793 \\ while (optionalReturn()) |_| {
...@@ -3623,10 +3799,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3623,10 +3799,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3623 \\ return 1;3799 \\ return 1;
3624 \\}3800 \\}
3625 , &[_][]const u8{3801 , &[_][]const u8{
3626 "tmp.zig:4:20: error: `_` may only be used to assign things to",3802 "tmp.zig:4:20: error: '_' used as an identifier without @\"_\" syntax",
3627 });3803 });
36283804
3629 cases.add("`_` should not be usable inside while else",3805 ctx.objErrStage1("`_` should not be usable inside while else",
3630 \\export fn returns() void {3806 \\export fn returns() void {
3631 \\ while (optionalReturnError()) |_| {3807 \\ while (optionalReturnError()) |_| {
3632 \\ while (optionalReturnError()) |_| {3808 \\ while (optionalReturnError()) |_| {
...@@ -3640,10 +3816,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3640,10 +3816,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3640 \\ return error.optionalReturnError;3816 \\ return error.optionalReturnError;
3641 \\}3817 \\}
3642 , &[_][]const u8{3818 , &[_][]const u8{
3643 "tmp.zig:6:17: error: `_` may only be used to assign things to",3819 "tmp.zig:6:17: error: '_' used as an identifier without @\"_\" syntax",
3644 });3820 });
36453821
3646 cases.add("while loop body expression ignored",3822 ctx.objErrStage1("while loop body expression ignored",
3647 \\fn returns() usize {3823 \\fn returns() usize {
3648 \\ return 2;3824 \\ return 2;
3649 \\}3825 \\}
...@@ -3664,7 +3840,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3664,7 +3840,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3664 "tmp.zig:13:26: error: expression value is ignored",3840 "tmp.zig:13:26: error: expression value is ignored",
3665 });3841 });
36663842
3667 cases.add("missing parameter name of generic function",3843 ctx.objErrStage1("missing parameter name of generic function",
3668 \\fn dump(anytype) void {}3844 \\fn dump(anytype) void {}
3669 \\export fn entry() void {3845 \\export fn entry() void {
3670 \\ var a: u8 = 9;3846 \\ var a: u8 = 9;
...@@ -3674,20 +3850,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3674,20 +3850,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3674 "tmp.zig:1:9: error: missing parameter name",3850 "tmp.zig:1:9: error: missing parameter name",
3675 });3851 });
36763852
3677 cases.add("non-inline for loop on a type that requires comptime",3853 ctx.objErrStage1("non-inline for loop on a type that requires comptime",
3678 \\const Foo = struct {3854 \\const Foo = struct {
3679 \\ name: []const u8,3855 \\ name: []const u8,
3680 \\ T: type,3856 \\ T: type,
3681 \\};3857 \\};
3682 \\export fn entry() void {3858 \\export fn entry() void {
3683 \\ const xx: [2]Foo = undefined;3859 \\ const xx: [2]Foo = undefined;
3684 \\ for (xx) |f| {}3860 \\ for (xx) |f| { _ = f;}
3685 \\}3861 \\}
3686 , &[_][]const u8{3862 , &[_][]const u8{
3687 "tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known",3863 "tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known",
3688 });3864 });
36893865
3690 cases.add("generic fn as parameter without comptime keyword",3866 ctx.objErrStage1("generic fn as parameter without comptime keyword",
3691 \\fn f(_: fn (anytype) void) void {}3867 \\fn f(_: fn (anytype) void) void {}
3692 \\fn g(_: anytype) void {}3868 \\fn g(_: anytype) void {}
3693 \\export fn entry() void {3869 \\export fn entry() void {
...@@ -3697,7 +3873,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3697,7 +3873,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3697 "tmp.zig:1:9: error: parameter of type 'fn(anytype) anytype' must be declared comptime",3873 "tmp.zig:1:9: error: parameter of type 'fn(anytype) anytype' must be declared comptime",
3698 });3874 });
36993875
3700 cases.add("optional pointer to void in extern struct",3876 ctx.objErrStage1("optional pointer to void in extern struct",
3701 \\const Foo = extern struct {3877 \\const Foo = extern struct {
3702 \\ x: ?*const void,3878 \\ x: ?*const void,
3703 \\};3879 \\};
...@@ -3705,12 +3881,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3705,12 +3881,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3705 \\ foo: Foo,3881 \\ foo: Foo,
3706 \\ y: i32,3882 \\ y: i32,
3707 \\};3883 \\};
3708 \\export fn entry(bar: *Bar) void {}3884 \\export fn entry(bar: *Bar) void {_ = bar;}
3709 , &[_][]const u8{3885 , &[_][]const u8{
3710 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void'",3886 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void'",
3711 });3887 });
37123888
3713 cases.add("use of comptime-known undefined function value",3889 ctx.objErrStage1("use of comptime-known undefined function value",
3714 \\const Cmd = struct {3890 \\const Cmd = struct {
3715 \\ exec: fn () void,3891 \\ exec: fn () void,
3716 \\};3892 \\};
...@@ -3722,7 +3898,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3722,7 +3898,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3722 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior",3898 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior",
3723 });3899 });
37243900
3725 cases.add("use of comptime-known undefined function value",3901 ctx.objErrStage1("use of comptime-known undefined function value",
3726 \\const Cmd = struct {3902 \\const Cmd = struct {
3727 \\ exec: fn () void,3903 \\ exec: fn () void,
3728 \\};3904 \\};
...@@ -3734,16 +3910,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3734,16 +3910,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3734 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior",3910 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior",
3735 });3911 });
37363912
3737 cases.add("bad @alignCast at comptime",3913 ctx.objErrStage1("bad @alignCast at comptime",
3738 \\comptime {3914 \\comptime {
3739 \\ const ptr = @intToPtr(*align(1) i32, 0x1);3915 \\ const ptr = @intToPtr(*align(1) i32, 0x1);
3740 \\ const aligned = @alignCast(4, ptr);3916 \\ const aligned = @alignCast(4, ptr);
3917 \\ _ = aligned;
3741 \\}3918 \\}
3742 , &[_][]const u8{3919 , &[_][]const u8{
3743 "tmp.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes",3920 "tmp.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes",
3744 });3921 });
37453922
3746 cases.add("@ptrToInt on *void",3923 ctx.objErrStage1("@ptrToInt on *void",
3747 \\export fn entry() bool {3924 \\export fn entry() bool {
3748 \\ return @ptrToInt(&{}) == @ptrToInt(&{});3925 \\ return @ptrToInt(&{}) == @ptrToInt(&{});
3749 \\}3926 \\}
...@@ -3751,7 +3928,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3751,7 +3928,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3751 "tmp.zig:2:23: error: pointer to size 0 type has no address",3928 "tmp.zig:2:23: error: pointer to size 0 type has no address",
3752 });3929 });
37533930
3754 cases.add("@popCount - non-integer",3931 ctx.objErrStage1("@popCount - non-integer",
3755 \\export fn entry(x: f32) u32 {3932 \\export fn entry(x: f32) u32 {
3756 \\ return @popCount(f32, x);3933 \\ return @popCount(f32, x);
3757 \\}3934 \\}
...@@ -3759,8 +3936,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3759,8 +3936,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3759 "tmp.zig:2:22: error: expected integer type, found 'f32'",3936 "tmp.zig:2:22: error: expected integer type, found 'f32'",
3760 });3937 });
37613938
3762 cases.addCase(x: {3939 {
3763 const tc = cases.create("wrong same named struct",3940 const case = ctx.obj("wrong same named struct", .{});
3941 case.backend = .stage1;
3942
3943 case.addSourceFile("a.zig",
3944 \\pub const Foo = struct {
3945 \\ x: i32,
3946 \\};
3947 );
3948
3949 case.addSourceFile("b.zig",
3950 \\pub const Foo = struct {
3951 \\ z: f64,
3952 \\};
3953 );
3954
3955 case.addError(
3764 \\const a = @import("a.zig");3956 \\const a = @import("a.zig");
3765 \\const b = @import("b.zig");3957 \\const b = @import("b.zig");
3766 \\3958 \\
...@@ -3769,30 +3961,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3769,30 +3961,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3769 \\ bar(&a1);3961 \\ bar(&a1);
3770 \\}3962 \\}
3771 \\3963 \\
3772 \\fn bar(x: *b.Foo) void {}3964 \\fn bar(x: *b.Foo) void {_ = x;}
3773 , &[_][]const u8{3965 , &[_][]const u8{
3774 "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'",3966 "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'",
3775 "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",3967 "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
3776 "a.zig:1:17: note: a.Foo declared here",3968 "a.zig:1:17: note: a.Foo declared here",
3777 "b.zig:1:17: note: b.Foo declared here",3969 "b.zig:1:17: note: b.Foo declared here",
3778 });3970 });
3971 }
37793972
3780 tc.addSourceFile("a.zig",3973 ctx.objErrStage1("@floatToInt comptime safety",
3781 \\pub const Foo = struct {
3782 \\ x: i32,
3783 \\};
3784 );
3785
3786 tc.addSourceFile("b.zig",
3787 \\pub const Foo = struct {
3788 \\ z: f64,
3789 \\};
3790 );
3791
3792 break :x tc;
3793 });
3794
3795 cases.add("@floatToInt comptime safety",
3796 \\comptime {3974 \\comptime {
3797 \\ _ = @floatToInt(i8, @as(f32, -129.1));3975 \\ _ = @floatToInt(i8, @as(f32, -129.1));
3798 \\}3976 \\}
...@@ -3808,35 +3986,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3808,35 +3986,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3808 "tmp.zig:8:9: error: integer value '256' cannot be stored in type 'u8'",3986 "tmp.zig:8:9: error: integer value '256' cannot be stored in type 'u8'",
3809 });3987 });
38103988
3811 cases.add("use c_void as return type of fn ptr",3989 ctx.objErrStage1("use c_void as return type of fn ptr",
3812 \\export fn entry() void {3990 \\export fn entry() void {
3813 \\ const a: fn () c_void = undefined;3991 \\ const a: fn () c_void = undefined;
3992 \\ _ = a;
3814 \\}3993 \\}
3815 , &[_][]const u8{3994 , &[_][]const u8{
3816 "tmp.zig:2:20: error: return type cannot be opaque",3995 "tmp.zig:2:20: error: return type cannot be opaque",
3817 });3996 });
38183997
3819 cases.add("use implicit casts to assign null to non-nullable pointer",3998 ctx.objErrStage1("use implicit casts to assign null to non-nullable pointer",
3820 \\export fn entry() void {3999 \\export fn entry() void {
3821 \\ var x: i32 = 1234;4000 \\ var x: i32 = 1234;
3822 \\ var p: *i32 = &x;4001 \\ var p: *i32 = &x;
3823 \\ var pp: *?*i32 = &p;4002 \\ var pp: *?*i32 = &p;
3824 \\ pp.* = null;4003 \\ pp.* = null;
3825 \\ var y = p.*;4004 \\ var y = p.*;
4005 \\ _ = y;
3826 \\}4006 \\}
3827 , &[_][]const u8{4007 , &[_][]const u8{
3828 "tmp.zig:4:23: error: expected type '*?*i32', found '**i32'",4008 "tmp.zig:4:23: error: expected type '*?*i32', found '**i32'",
3829 });4009 });
38304010
3831 cases.add("attempted implicit cast from T to [*]const T",4011 ctx.objErrStage1("attempted implicit cast from T to [*]const T",
3832 \\export fn entry() void {4012 \\export fn entry() void {
3833 \\ const x: [*]const bool = true;4013 \\ const x: [*]const bool = true;
4014 \\ _ = x;
3834 \\}4015 \\}
3835 , &[_][]const u8{4016 , &[_][]const u8{
3836 "tmp.zig:2:30: error: expected type '[*]const bool', found 'bool'",4017 "tmp.zig:2:30: error: expected type '[*]const bool', found 'bool'",
3837 });4018 });
38384019
3839 cases.add("dereference unknown length pointer",4020 ctx.objErrStage1("dereference unknown length pointer",
3840 \\export fn entry(x: [*]i32) i32 {4021 \\export fn entry(x: [*]i32) i32 {
3841 \\ return x.*;4022 \\ return x.*;
3842 \\}4023 \\}
...@@ -3844,7 +4025,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3844,7 +4025,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3844 "tmp.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32'",4025 "tmp.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32'",
3845 });4026 });
38464027
3847 cases.add("field access of unknown length pointer",4028 ctx.objErrStage1("field access of unknown length pointer",
3848 \\const Foo = extern struct {4029 \\const Foo = extern struct {
3849 \\ a: i32,4030 \\ a: i32,
3850 \\};4031 \\};
...@@ -3856,13 +4037,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3856,13 +4037,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3856 "tmp.zig:6:8: error: type '[*]Foo' does not support field access",4037 "tmp.zig:6:8: error: type '[*]Foo' does not support field access",
3857 });4038 });
38584039
3859 cases.add("unknown length pointer to opaque",4040 ctx.objErrStage1("unknown length pointer to opaque",
3860 \\export const T = [*]opaque {};4041 \\export const T = [*]opaque {};
3861 , &[_][]const u8{4042 , &[_][]const u8{
3862 "tmp.zig:1:21: error: unknown-length pointer to opaque",4043 "tmp.zig:1:21: error: unknown-length pointer to opaque",
3863 });4044 });
38644045
3865 cases.add("error when evaluating return type",4046 ctx.objErrStage1("error when evaluating return type",
3866 \\const Foo = struct {4047 \\const Foo = struct {
3867 \\ map: @as(i32, i32),4048 \\ map: @as(i32, i32),
3868 \\4049 \\
...@@ -3872,20 +4053,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3872,20 +4053,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3872 \\};4053 \\};
3873 \\export fn entry() void {4054 \\export fn entry() void {
3874 \\ var rule_set = try Foo.init();4055 \\ var rule_set = try Foo.init();
4056 \\ _ = rule_set;
3875 \\}4057 \\}
3876 , &[_][]const u8{4058 , &[_][]const u8{
3877 "tmp.zig:2:19: error: expected type 'i32', found 'type'",4059 "tmp.zig:2:19: error: expected type 'i32', found 'type'",
3878 });4060 });
38794061
3880 cases.add("slicing single-item pointer",4062 ctx.objErrStage1("slicing single-item pointer",
3881 \\export fn entry(ptr: *i32) void {4063 \\export fn entry(ptr: *i32) void {
3882 \\ const slice = ptr[0..2];4064 \\ const slice = ptr[0..2];
4065 \\ _ = slice;
3883 \\}4066 \\}
3884 , &[_][]const u8{4067 , &[_][]const u8{
3885 "tmp.zig:2:22: error: slice of single-item pointer",4068 "tmp.zig:2:22: error: slice of single-item pointer",
3886 });4069 });
38874070
3888 cases.add("indexing single-item pointer",4071 ctx.objErrStage1("indexing single-item pointer",
3889 \\export fn entry(ptr: *i32) i32 {4072 \\export fn entry(ptr: *i32) i32 {
3890 \\ return ptr[1];4073 \\ return ptr[1];
3891 \\}4074 \\}
...@@ -3893,12 +4076,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3893,12 +4076,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3893 "tmp.zig:2:15: error: index of single-item pointer",4076 "tmp.zig:2:15: error: index of single-item pointer",
3894 });4077 });
38954078
3896 cases.add("nested error set mismatch",4079 ctx.objErrStage1("nested error set mismatch",
3897 \\const NextError = error{NextError};4080 \\const NextError = error{NextError};
3898 \\const OtherError = error{OutOfMemory};4081 \\const OtherError = error{OutOfMemory};
3899 \\4082 \\
3900 \\export fn entry() void {4083 \\export fn entry() void {
3901 \\ const a: ?NextError!i32 = foo();4084 \\ const a: ?NextError!i32 = foo();
4085 \\ _ = a;
3902 \\}4086 \\}
3903 \\4087 \\
3904 \\fn foo() ?OtherError!i32 {4088 \\fn foo() ?OtherError!i32 {
...@@ -3911,7 +4095,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3911,7 +4095,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3911 "tmp.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set",4095 "tmp.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set",
3912 });4096 });
39134097
3914 cases.add("invalid deref on switch target",4098 ctx.objErrStage1("invalid deref on switch target",
3915 \\comptime {4099 \\comptime {
3916 \\ var tile = Tile.Empty;4100 \\ var tile = Tile.Empty;
3917 \\ switch (tile.*) {4101 \\ switch (tile.*) {
...@@ -3927,13 +4111,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3927,13 +4111,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3927 "tmp.zig:3:17: error: attempt to dereference non-pointer type 'Tile'",4111 "tmp.zig:3:17: error: attempt to dereference non-pointer type 'Tile'",
3928 });4112 });
39294113
3930 cases.add("invalid field access in comptime",4114 ctx.objErrStage1("invalid field access in comptime",
3931 \\comptime { var x = doesnt_exist.whatever; }4115 \\comptime { var x = doesnt_exist.whatever; _ = x; }
3932 , &[_][]const u8{4116 , &[_][]const u8{
3933 "tmp.zig:1:20: error: use of undeclared identifier 'doesnt_exist'",4117 "tmp.zig:1:20: error: use of undeclared identifier 'doesnt_exist'",
3934 });4118 });
39354119
3936 cases.add("suspend inside suspend block",4120 ctx.objErrStage1("suspend inside suspend block",
3937 \\export fn entry() void {4121 \\export fn entry() void {
3938 \\ _ = async foo();4122 \\ _ = async foo();
3939 \\}4123 \\}
...@@ -3948,17 +4132,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3948,17 +4132,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3948 "tmp.zig:5:5: note: other suspend block here",4132 "tmp.zig:5:5: note: other suspend block here",
3949 });4133 });
39504134
3951 cases.add("assign inline fn to non-comptime var",4135 ctx.objErrStage1("assign inline fn to non-comptime var",
3952 \\export fn entry() void {4136 \\export fn entry() void {
3953 \\ var a = b;4137 \\ var a = b;
4138 \\ _ = a;
3954 \\}4139 \\}
3955 \\fn b() callconv(.Inline) void { }4140 \\fn b() callconv(.Inline) void { }
3956 , &[_][]const u8{4141 , &[_][]const u8{
3957 "tmp.zig:2:5: error: functions marked inline must be stored in const or comptime var",4142 "tmp.zig:2:5: error: functions marked inline must be stored in const or comptime var",
3958 "tmp.zig:4:1: note: declared here",4143 "tmp.zig:5:1: note: declared here",
3959 });4144 });
39604145
3961 cases.add("wrong type passed to @panic",4146 ctx.objErrStage1("wrong type passed to @panic",
3962 \\export fn entry() void {4147 \\export fn entry() void {
3963 \\ var e = error.Foo;4148 \\ var e = error.Foo;
3964 \\ @panic(e);4149 \\ @panic(e);
...@@ -3967,7 +4152,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3967,7 +4152,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3967 "tmp.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'",4152 "tmp.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'",
3968 });4153 });
39694154
3970 cases.add("@tagName used on union with no associated enum tag",4155 ctx.objErrStage1("@tagName used on union with no associated enum tag",
3971 \\const FloatInt = extern union {4156 \\const FloatInt = extern union {
3972 \\ Float: f32,4157 \\ Float: f32,
3973 \\ Int: i32,4158 \\ Int: i32,
...@@ -3975,13 +4160,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3975,13 +4160,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3975 \\export fn entry() void {4160 \\export fn entry() void {
3976 \\ var fi = FloatInt{.Float = 123.45};4161 \\ var fi = FloatInt{.Float = 123.45};
3977 \\ var tagName = @tagName(fi);4162 \\ var tagName = @tagName(fi);
4163 \\ _ = tagName;
3978 \\}4164 \\}
3979 , &[_][]const u8{4165 , &[_][]const u8{
3980 "tmp.zig:7:19: error: union has no associated enum",4166 "tmp.zig:7:19: error: union has no associated enum",
3981 "tmp.zig:1:18: note: declared here",4167 "tmp.zig:1:18: note: declared here",
3982 });4168 });
39834169
3984 cases.add("returning error from void async function",4170 ctx.objErrStage1("returning error from void async function",
3985 \\export fn entry() void {4171 \\export fn entry() void {
3986 \\ _ = async amain();4172 \\ _ = async amain();
3987 \\}4173 \\}
...@@ -3992,37 +4178,40 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3992,37 +4178,40 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3992 "tmp.zig:5:17: error: expected type 'void', found 'error{ShouldBeCompileError}'",4178 "tmp.zig:5:17: error: expected type 'void', found 'error{ShouldBeCompileError}'",
3993 });4179 });
39944180
3995 cases.add("var makes structs required to be comptime known",4181 ctx.objErrStage1("var makes structs required to be comptime known",
3996 \\export fn entry() void {4182 \\export fn entry() void {
3997 \\ const S = struct{v: anytype};4183 \\ const S = struct{v: anytype};
3998 \\ var s = S{.v=@as(i32, 10)};4184 \\ var s = S{.v=@as(i32, 10)};
4185 \\ _ = s;
3999 \\}4186 \\}
4000 , &[_][]const u8{4187 , &[_][]const u8{
4001 "tmp.zig:3:4: error: variable of type 'S' must be const or comptime",4188 "tmp.zig:3:4: error: variable of type 'S' must be const or comptime",
4002 });4189 });
40034190
4004 cases.add("@ptrCast discards const qualifier",4191 ctx.objErrStage1("@ptrCast discards const qualifier",
4005 \\export fn entry() void {4192 \\export fn entry() void {
4006 \\ const x: i32 = 1234;4193 \\ const x: i32 = 1234;
4007 \\ const y = @ptrCast(*i32, &x);4194 \\ const y = @ptrCast(*i32, &x);
4195 \\ _ = y;
4008 \\}4196 \\}
4009 , &[_][]const u8{4197 , &[_][]const u8{
4010 "tmp.zig:3:15: error: cast discards const qualifier",4198 "tmp.zig:3:15: error: cast discards const qualifier",
4011 });4199 });
40124200
4013 cases.add("comptime slice of undefined pointer non-zero len",4201 ctx.objErrStage1("comptime slice of undefined pointer non-zero len",
4014 \\export fn entry() void {4202 \\export fn entry() void {
4015 \\ const slice = @as([*]i32, undefined)[0..1];4203 \\ const slice = @as([*]i32, undefined)[0..1];
4204 \\ _ = slice;
4016 \\}4205 \\}
4017 , &[_][]const u8{4206 , &[_][]const u8{
4018 "tmp.zig:2:41: error: non-zero length slice of undefined pointer",4207 "tmp.zig:2:41: error: non-zero length slice of undefined pointer",
4019 });4208 });
40204209
4021 cases.add("type checking function pointers",4210 ctx.objErrStage1("type checking function pointers",
4022 \\fn a(b: fn (*const u8) void) void {4211 \\fn a(b: fn (*const u8) void) void {
4023 \\ b('a');4212 \\ b('a');
4024 \\}4213 \\}
4025 \\fn c(d: u8) void {}4214 \\fn c(d: u8) void {_ = d;}
4026 \\export fn entry() void {4215 \\export fn entry() void {
4027 \\ a(c);4216 \\ a(c);
4028 \\}4217 \\}
...@@ -4030,7 +4219,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4030,7 +4219,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4030 "tmp.zig:6:7: error: expected type 'fn(*const u8) void', found 'fn(u8) void'",4219 "tmp.zig:6:7: error: expected type 'fn(*const u8) void', found 'fn(u8) void'",
4031 });4220 });
40324221
4033 cases.add("no else prong on switch on global error set",4222 ctx.objErrStage1("no else prong on switch on global error set",
4034 \\export fn entry() void {4223 \\export fn entry() void {
4035 \\ foo(error.A);4224 \\ foo(error.A);
4036 \\}4225 \\}
...@@ -4043,7 +4232,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4043,7 +4232,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4043 "tmp.zig:5:5: error: else prong required when switching on type 'anyerror'",4232 "tmp.zig:5:5: error: else prong required when switching on type 'anyerror'",
4044 });4233 });
40454234
4046 cases.add("error not handled in switch",4235 ctx.objErrStage1("error not handled in switch",
4047 \\export fn entry() void {4236 \\export fn entry() void {
4048 \\ foo(452) catch |err| switch (err) {4237 \\ foo(452) catch |err| switch (err) {
4049 \\ error.Foo => {},4238 \\ error.Foo => {},
...@@ -4062,7 +4251,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4062,7 +4251,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4062 "tmp.zig:2:26: error: error.Bar not handled in switch",4251 "tmp.zig:2:26: error: error.Bar not handled in switch",
4063 });4252 });
40644253
4065 cases.add("duplicate error in switch",4254 ctx.objErrStage1("duplicate error in switch",
4066 \\export fn entry() void {4255 \\export fn entry() void {
4067 \\ foo(452) catch |err| switch (err) {4256 \\ foo(452) catch |err| switch (err) {
4068 \\ error.Foo => {},4257 \\ error.Foo => {},
...@@ -4080,10 +4269,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4080,10 +4269,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4080 \\}4269 \\}
4081 , &[_][]const u8{4270 , &[_][]const u8{
4082 "tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'",4271 "tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'",
4083 "tmp.zig:3:14: note: other value is here",4272 "tmp.zig:3:14: note: other value here",
4084 });4273 });
40854274
4086 cases.add("invalid cast from integral type to enum",4275 ctx.objErrStage1("invalid cast from integral type to enum",
4087 \\const E = enum(usize) { One, Two };4276 \\const E = enum(usize) { One, Two };
4088 \\4277 \\
4089 \\export fn entry() void {4278 \\export fn entry() void {
...@@ -4099,7 +4288,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4099,7 +4288,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4099 "tmp.zig:9:10: error: expected type 'usize', found 'E'",4288 "tmp.zig:9:10: error: expected type 'usize', found 'E'",
4100 });4289 });
41014290
4102 cases.add("range operator in switch used on error set",4291 ctx.objErrStage1("range operator in switch used on error set",
4103 \\export fn entry() void {4292 \\export fn entry() void {
4104 \\ try foo(452) catch |err| switch (err) {4293 \\ try foo(452) catch |err| switch (err) {
4105 \\ error.A ... error.B => {},4294 \\ error.A ... error.B => {},
...@@ -4117,33 +4306,35 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4117,33 +4306,35 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4117 "tmp.zig:3:17: error: operator not allowed for errors",4306 "tmp.zig:3:17: error: operator not allowed for errors",
4118 });4307 });
41194308
4120 cases.add("inferring error set of function pointer",4309 ctx.objErrStage1("inferring error set of function pointer",
4121 \\comptime {4310 \\comptime {
4122 \\ const z: ?fn()!void = null;4311 \\ const z: ?fn()!void = null;
4123 \\}4312 \\}
4124 , &[_][]const u8{4313 , &[_][]const u8{
4125 "tmp.zig:2:15: error: inferring error set of return type valid only for function definitions",4314 "tmp.zig:2:19: error: function prototype may not have inferred error set",
4126 });4315 });
41274316
4128 cases.add("access non-existent member of error set",4317 ctx.objErrStage1("access non-existent member of error set",
4129 \\const Foo = error{A};4318 \\const Foo = error{A};
4130 \\comptime {4319 \\comptime {
4131 \\ const z = Foo.Bar;4320 \\ const z = Foo.Bar;
4321 \\ _ = z;
4132 \\}4322 \\}
4133 , &[_][]const u8{4323 , &[_][]const u8{
4134 "tmp.zig:3:18: error: no error named 'Bar' in 'Foo'",4324 "tmp.zig:3:18: error: no error named 'Bar' in 'Foo'",
4135 });4325 });
41364326
4137 cases.add("error union operator with non error set LHS",4327 ctx.objErrStage1("error union operator with non error set LHS",
4138 \\comptime {4328 \\comptime {
4139 \\ const z = i32!i32;4329 \\ const z = i32!i32;
4140 \\ var x: z = undefined;4330 \\ var x: z = undefined;
4331 \\ _ = x;
4141 \\}4332 \\}
4142 , &[_][]const u8{4333 , &[_][]const u8{
4143 "tmp.zig:2:15: error: expected error set type, found type 'i32'",4334 "tmp.zig:2:15: error: expected error set type, found type 'i32'",
4144 });4335 });
41454336
4146 cases.add("error equality but sets have no common members",4337 ctx.objErrStage1("error equality but sets have no common members",
4147 \\const Set1 = error{A, C};4338 \\const Set1 = error{A, C};
4148 \\const Set2 = error{B, D};4339 \\const Set2 = error{B, D};
4149 \\export fn entry() void {4340 \\export fn entry() void {
...@@ -4158,29 +4349,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4158,29 +4349,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4158 "tmp.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors",4349 "tmp.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors",
4159 });4350 });
41604351
4161 cases.add("only equality binary operator allowed for error sets",4352 ctx.objErrStage1("only equality binary operator allowed for error sets",
4162 \\comptime {4353 \\comptime {
4163 \\ const z = error.A > error.B;4354 \\ const z = error.A > error.B;
4355 \\ _ = z;
4164 \\}4356 \\}
4165 , &[_][]const u8{4357 , &[_][]const u8{
4166 "tmp.zig:2:23: error: operator not allowed for errors",4358 "tmp.zig:2:23: error: operator not allowed for errors",
4167 });4359 });
41684360
4169 cases.add("explicit error set cast known at comptime violates error sets",4361 ctx.objErrStage1("explicit error set cast known at comptime violates error sets",
4170 \\const Set1 = error {A, B};4362 \\const Set1 = error {A, B};
4171 \\const Set2 = error {A, C};4363 \\const Set2 = error {A, C};
4172 \\comptime {4364 \\comptime {
4173 \\ var x = Set1.B;4365 \\ var x = Set1.B;
4174 \\ var y = @errSetCast(Set2, x);4366 \\ var y = @errSetCast(Set2, x);
4367 \\ _ = y;
4175 \\}4368 \\}
4176 , &[_][]const u8{4369 , &[_][]const u8{
4177 "tmp.zig:5:13: error: error.B not a member of error set 'Set2'",4370 "tmp.zig:5:13: error: error.B not a member of error set 'Set2'",
4178 });4371 });
41794372
4180 cases.add("cast error union of global error set to error union of smaller error set",4373 ctx.objErrStage1("cast error union of global error set to error union of smaller error set",
4181 \\const SmallErrorSet = error{A};4374 \\const SmallErrorSet = error{A};
4182 \\export fn entry() void {4375 \\export fn entry() void {
4183 \\ var x: SmallErrorSet!i32 = foo();4376 \\ var x: SmallErrorSet!i32 = foo();
4377 \\ _ = x;
4184 \\}4378 \\}
4185 \\fn foo() anyerror!i32 {4379 \\fn foo() anyerror!i32 {
4186 \\ return error.B;4380 \\ return error.B;
...@@ -4191,10 +4385,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4191,10 +4385,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4191 "tmp.zig:3:35: note: cannot cast global error set into smaller set",4385 "tmp.zig:3:35: note: cannot cast global error set into smaller set",
4192 });4386 });
41934387
4194 cases.add("cast global error set to error set",4388 ctx.objErrStage1("cast global error set to error set",
4195 \\const SmallErrorSet = error{A};4389 \\const SmallErrorSet = error{A};
4196 \\export fn entry() void {4390 \\export fn entry() void {
4197 \\ var x: SmallErrorSet = foo();4391 \\ var x: SmallErrorSet = foo();
4392 \\ _ = x;
4198 \\}4393 \\}
4199 \\fn foo() anyerror {4394 \\fn foo() anyerror {
4200 \\ return error.B;4395 \\ return error.B;
...@@ -4203,7 +4398,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4203,7 +4398,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4203 "tmp.zig:3:31: error: expected type 'SmallErrorSet', found 'anyerror'",4398 "tmp.zig:3:31: error: expected type 'SmallErrorSet', found 'anyerror'",
4204 "tmp.zig:3:31: note: cannot cast global error set into smaller set",4399 "tmp.zig:3:31: note: cannot cast global error set into smaller set",
4205 });4400 });
4206 cases.add("recursive inferred error set",4401 ctx.objErrStage1("recursive inferred error set",
4207 \\export fn entry() void {4402 \\export fn entry() void {
4208 \\ foo() catch unreachable;4403 \\ foo() catch unreachable;
4209 \\}4404 \\}
...@@ -4214,7 +4409,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4214,7 +4409,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4214 "tmp.zig:5:5: error: cannot resolve inferred error set '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set': function 'foo' not fully analyzed yet",4409 "tmp.zig:5:5: error: cannot resolve inferred error set '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set': function 'foo' not fully analyzed yet",
4215 });4410 });
42164411
4217 cases.add("implicit cast of error set not a subset",4412 ctx.objErrStage1("implicit cast of error set not a subset",
4218 \\const Set1 = error{A, B};4413 \\const Set1 = error{A, B};
4219 \\const Set2 = error{A, C};4414 \\const Set2 = error{A, C};
4220 \\export fn entry() void {4415 \\export fn entry() void {
...@@ -4222,13 +4417,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4222,13 +4417,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4222 \\}4417 \\}
4223 \\fn foo(set1: Set1) void {4418 \\fn foo(set1: Set1) void {
4224 \\ var x: Set2 = set1;4419 \\ var x: Set2 = set1;
4420 \\ _ = x;
4225 \\}4421 \\}
4226 , &[_][]const u8{4422 , &[_][]const u8{
4227 "tmp.zig:7:19: error: expected type 'Set2', found 'Set1'",4423 "tmp.zig:7:19: error: expected type 'Set2', found 'Set1'",
4228 "tmp.zig:1:23: note: 'error.B' not a member of destination error set",4424 "tmp.zig:1:23: note: 'error.B' not a member of destination error set",
4229 });4425 });
42304426
4231 cases.add("int to err global invalid number",4427 ctx.objErrStage1("int to err global invalid number",
4232 \\const Set1 = error{4428 \\const Set1 = error{
4233 \\ A,4429 \\ A,
4234 \\ B,4430 \\ B,
...@@ -4236,12 +4432,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4236,12 +4432,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4236 \\comptime {4432 \\comptime {
4237 \\ var x: u16 = 3;4433 \\ var x: u16 = 3;
4238 \\ var y = @intToError(x);4434 \\ var y = @intToError(x);
4435 \\ _ = y;
4239 \\}4436 \\}
4240 , &[_][]const u8{4437 , &[_][]const u8{
4241 "tmp.zig:7:13: error: integer value 3 represents no error",4438 "tmp.zig:7:13: error: integer value 3 represents no error",
4242 });4439 });
42434440
4244 cases.add("int to err non global invalid number",4441 ctx.objErrStage1("int to err non global invalid number",
4245 \\const Set1 = error{4442 \\const Set1 = error{
4246 \\ A,4443 \\ A,
4247 \\ B,4444 \\ B,
...@@ -4253,68 +4450,74 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4253,68 +4450,74 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4253 \\comptime {4450 \\comptime {
4254 \\ var x = @errorToInt(Set1.B);4451 \\ var x = @errorToInt(Set1.B);
4255 \\ var y = @errSetCast(Set2, @intToError(x));4452 \\ var y = @errSetCast(Set2, @intToError(x));
4453 \\ _ = y;
4256 \\}4454 \\}
4257 , &[_][]const u8{4455 , &[_][]const u8{
4258 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'",4456 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'",
4259 });4457 });
42604458
4261 cases.add("duplicate error value in error set",4459 ctx.objErrStage1("duplicate error value in error set",
4262 \\const Foo = error {4460 \\const Foo = error {
4263 \\ Bar,4461 \\ Bar,
4264 \\ Bar,4462 \\ Bar,
4265 \\};4463 \\};
4266 \\export fn entry() void {4464 \\export fn entry() void {
4267 \\ const a: Foo = undefined;4465 \\ const a: Foo = undefined;
4466 \\ _ = a;
4268 \\}4467 \\}
4269 , &[_][]const u8{4468 , &[_][]const u8{
4270 "tmp.zig:3:5: error: duplicate error: 'Bar'",4469 "tmp.zig:3:5: error: duplicate error: 'Bar'",
4271 "tmp.zig:2:5: note: other error here",4470 "tmp.zig:2:5: note: other error here",
4272 });4471 });
42734472
4274 cases.add("cast negative integer literal to usize",4473 ctx.objErrStage1("cast negative integer literal to usize",
4275 \\export fn entry() void {4474 \\export fn entry() void {
4276 \\ const x = @as(usize, -10);4475 \\ const x = @as(usize, -10);
4476 \\ _ = x;
4277 \\}4477 \\}
4278 , &[_][]const u8{4478 , &[_][]const u8{
4279 "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'",4479 "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'",
4280 });4480 });
42814481
4282 cases.add("use invalid number literal as array index",4482 ctx.objErrStage1("use invalid number literal as array index",
4283 \\var v = 25;4483 \\var v = 25;
4284 \\export fn entry() void {4484 \\export fn entry() void {
4285 \\ var arr: [v]u8 = undefined;4485 \\ var arr: [v]u8 = undefined;
4486 \\ _ = arr;
4286 \\}4487 \\}
4287 , &[_][]const u8{4488 , &[_][]const u8{
4288 "tmp.zig:1:1: error: unable to infer variable type",4489 "tmp.zig:1:1: error: unable to infer variable type",
4289 });4490 });
42904491
4291 cases.add("duplicate struct field",4492 ctx.objErrStage1("duplicate struct field",
4292 \\const Foo = struct {4493 \\const Foo = struct {
4293 \\ Bar: i32,4494 \\ Bar: i32,
4294 \\ Bar: usize,4495 \\ Bar: usize,
4295 \\};4496 \\};
4296 \\export fn entry() void {4497 \\export fn entry() void {
4297 \\ const a: Foo = undefined;4498 \\ const a: Foo = undefined;
4499 \\ _ = a;
4298 \\}4500 \\}
4299 , &[_][]const u8{4501 , &[_][]const u8{
4300 "tmp.zig:3:5: error: duplicate struct field: 'Bar'",4502 "tmp.zig:3:5: error: duplicate struct field: 'Bar'",
4301 "tmp.zig:2:5: note: other field here",4503 "tmp.zig:2:5: note: other field here",
4302 });4504 });
43034505
4304 cases.add("duplicate union field",4506 ctx.objErrStage1("duplicate union field",
4305 \\const Foo = union {4507 \\const Foo = union {
4306 \\ Bar: i32,4508 \\ Bar: i32,
4307 \\ Bar: usize,4509 \\ Bar: usize,
4308 \\};4510 \\};
4309 \\export fn entry() void {4511 \\export fn entry() void {
4310 \\ const a: Foo = undefined;4512 \\ const a: Foo = undefined;
4513 \\ _ = a;
4311 \\}4514 \\}
4312 , &[_][]const u8{4515 , &[_][]const u8{
4313 "tmp.zig:3:5: error: duplicate union field: 'Bar'",4516 "tmp.zig:3:5: error: duplicate union field: 'Bar'",
4314 "tmp.zig:2:5: note: other field here",4517 "tmp.zig:2:5: note: other field here",
4315 });4518 });
43164519
4317 cases.add("duplicate enum field",4520 ctx.objErrStage1("duplicate enum field",
4318 \\const Foo = enum {4521 \\const Foo = enum {
4319 \\ Bar,4522 \\ Bar,
4320 \\ Bar,4523 \\ Bar,
...@@ -4322,13 +4525,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4322,13 +4525,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4322 \\4525 \\
4323 \\export fn entry() void {4526 \\export fn entry() void {
4324 \\ const a: Foo = undefined;4527 \\ const a: Foo = undefined;
4528 \\ _ = a;
4325 \\}4529 \\}
4326 , &[_][]const u8{4530 , &[_][]const u8{
4327 "tmp.zig:3:5: error: duplicate enum field: 'Bar'",4531 "tmp.zig:3:5: error: duplicate enum field: 'Bar'",
4328 "tmp.zig:2:5: note: other field here",4532 "tmp.zig:2:5: note: other field here",
4329 });4533 });
43304534
4331 cases.add("calling function with naked calling convention",4535 ctx.objErrStage1("calling function with naked calling convention",
4332 \\export fn entry() void {4536 \\export fn entry() void {
4333 \\ foo();4537 \\ foo();
4334 \\}4538 \\}
...@@ -4338,42 +4542,42 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4338,42 +4542,42 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4338 "tmp.zig:4:1: note: declared here",4542 "tmp.zig:4:1: note: declared here",
4339 });4543 });
43404544
4341 cases.add("function with invalid return type",4545 ctx.objErrStage1("function with invalid return type",
4342 \\export fn foo() boid {}4546 \\export fn foo() boid {}
4343 , &[_][]const u8{4547 , &[_][]const u8{
4344 "tmp.zig:1:17: error: use of undeclared identifier 'boid'",4548 "tmp.zig:1:17: error: use of undeclared identifier 'boid'",
4345 });4549 });
43464550
4347 cases.add("function with non-extern non-packed enum parameter",4551 ctx.objErrStage1("function with non-extern non-packed enum parameter",
4348 \\const Foo = enum { A, B, C };4552 \\const Foo = enum { A, B, C };
4349 \\export fn entry(foo: Foo) void { }4553 \\export fn entry(foo: Foo) void { _ = foo; }
4350 , &[_][]const u8{4554 , &[_][]const u8{
4351 "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",4555 "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
4352 });4556 });
43534557
4354 cases.add("function with non-extern non-packed struct parameter",4558 ctx.objErrStage1("function with non-extern non-packed struct parameter",
4355 \\const Foo = struct {4559 \\const Foo = struct {
4356 \\ A: i32,4560 \\ A: i32,
4357 \\ B: f32,4561 \\ B: f32,
4358 \\ C: bool,4562 \\ C: bool,
4359 \\};4563 \\};
4360 \\export fn entry(foo: Foo) void { }4564 \\export fn entry(foo: Foo) void { _ = foo; }
4361 , &[_][]const u8{4565 , &[_][]const u8{
4362 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",4566 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
4363 });4567 });
43644568
4365 cases.add("function with non-extern non-packed union parameter",4569 ctx.objErrStage1("function with non-extern non-packed union parameter",
4366 \\const Foo = union {4570 \\const Foo = union {
4367 \\ A: i32,4571 \\ A: i32,
4368 \\ B: f32,4572 \\ B: f32,
4369 \\ C: bool,4573 \\ C: bool,
4370 \\};4574 \\};
4371 \\export fn entry(foo: Foo) void { }4575 \\export fn entry(foo: Foo) void { _ = foo; }
4372 , &[_][]const u8{4576 , &[_][]const u8{
4373 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",4577 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
4374 });4578 });
43754579
4376 cases.add("switch on enum with 1 field with no prongs",4580 ctx.objErrStage1("switch on enum with 1 field with no prongs",
4377 \\const Foo = enum { M };4581 \\const Foo = enum { M };
4378 \\4582 \\
4379 \\export fn entry() void {4583 \\export fn entry() void {
...@@ -4384,15 +4588,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4384,15 +4588,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4384 "tmp.zig:5:5: error: enumeration value 'Foo.M' not handled in switch",4588 "tmp.zig:5:5: error: enumeration value 'Foo.M' not handled in switch",
4385 });4589 });
43864590
4387 cases.add("shift by negative comptime integer",4591 ctx.objErrStage1("shift by negative comptime integer",
4388 \\comptime {4592 \\comptime {
4389 \\ var a = 1 >> -1;4593 \\ var a = 1 >> -1;
4594 \\ _ = a;
4390 \\}4595 \\}
4391 , &[_][]const u8{4596 , &[_][]const u8{
4392 "tmp.zig:2:18: error: shift by negative value -1",4597 "tmp.zig:2:18: error: shift by negative value -1",
4393 });4598 });
43944599
4395 cases.add("@panic called at compile time",4600 ctx.objErrStage1("@panic called at compile time",
4396 \\export fn entry() void {4601 \\export fn entry() void {
4397 \\ comptime {4602 \\ comptime {
4398 \\ @panic("aoeu",);4603 \\ @panic("aoeu",);
...@@ -4402,20 +4607,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4402,20 +4607,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4402 "tmp.zig:3:9: error: encountered @panic at compile-time",4607 "tmp.zig:3:9: error: encountered @panic at compile-time",
4403 });4608 });
44044609
4405 cases.add("wrong return type for main",4610 ctx.objErrStage1("wrong return type for main",
4406 \\pub fn main() f32 { }4611 \\pub fn main() f32 { }
4407 , &[_][]const u8{4612 , &[_][]const u8{
4408 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",4613 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",
4409 });4614 });
44104615
4411 cases.add("double ?? on main return value",4616 ctx.objErrStage1("double ?? on main return value",
4412 \\pub fn main() ??void {4617 \\pub fn main() ??void {
4413 \\}4618 \\}
4414 , &[_][]const u8{4619 , &[_][]const u8{
4415 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",4620 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",
4416 });4621 });
44174622
4418 cases.add("bad identifier in function with struct defined inside function which references local const",4623 ctx.objErrStage1("bad identifier in function with struct defined inside function which references local const",
4419 \\export fn entry() void {4624 \\export fn entry() void {
4420 \\ const BlockKind = u32;4625 \\ const BlockKind = u32;
4421 \\4626 \\
...@@ -4424,12 +4629,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4424,12 +4629,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4424 \\ };4629 \\ };
4425 \\4630 \\
4426 \\ bogus;4631 \\ bogus;
4632 \\
4633 \\ _ = Block;
4427 \\}4634 \\}
4428 , &[_][]const u8{4635 , &[_][]const u8{
4429 "tmp.zig:8:5: error: use of undeclared identifier 'bogus'",4636 "tmp.zig:8:5: error: use of undeclared identifier 'bogus'",
4430 });4637 });
44314638
4432 cases.add("labeled break not found",4639 ctx.objErrStage1("labeled break not found",
4433 \\export fn entry() void {4640 \\export fn entry() void {
4434 \\ blah: while (true) {4641 \\ blah: while (true) {
4435 \\ while (true) {4642 \\ while (true) {
...@@ -4438,10 +4645,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4438,10 +4645,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4438 \\ }4645 \\ }
4439 \\}4646 \\}
4440 , &[_][]const u8{4647 , &[_][]const u8{
4441 "tmp.zig:4:13: error: label not found: 'outer'",4648 "tmp.zig:4:20: error: label not found: 'outer'",
4442 });4649 });
44434650
4444 cases.add("labeled continue not found",4651 ctx.objErrStage1("labeled continue not found",
4445 \\export fn entry() void {4652 \\export fn entry() void {
4446 \\ var i: usize = 0;4653 \\ var i: usize = 0;
4447 \\ blah: while (i < 10) : (i += 1) {4654 \\ blah: while (i < 10) : (i += 1) {
...@@ -4451,17 +4658,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4451,17 +4658,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4451 \\ }4658 \\ }
4452 \\}4659 \\}
4453 , &[_][]const u8{4660 , &[_][]const u8{
4454 "tmp.zig:5:13: error: labeled loop not found: 'outer'",4661 "tmp.zig:5:23: error: label not found: 'outer'",
4455 });4662 });
44564663
4457 cases.add("attempt to use 0 bit type in extern fn",4664 ctx.objErrStage1("attempt to use 0 bit type in extern fn",
4458 \\extern fn foo(ptr: fn(*void) callconv(.C) void) void;4665 \\extern fn foo(ptr: fn(*void) callconv(.C) void) void;
4459 \\4666 \\
4460 \\export fn entry() void {4667 \\export fn entry() void {
4461 \\ foo(bar);4668 \\ foo(bar);
4462 \\}4669 \\}
4463 \\4670 \\
4464 \\fn bar(x: *void) callconv(.C) void { }4671 \\fn bar(x: *void) callconv(.C) void { _ = x; }
4465 \\export fn entry2() void {4672 \\export fn entry2() void {
4466 \\ bar(&{});4673 \\ bar(&{});
4467 \\}4674 \\}
...@@ -4470,7 +4677,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4470,7 +4677,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4470 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",4677 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
4471 });4678 });
44724679
4473 cases.add("implicit semicolon - block statement",4680 ctx.objErrStage1("implicit semicolon - block statement",
4474 \\export fn entry() void {4681 \\export fn entry() void {
4475 \\ {}4682 \\ {}
4476 \\ var good = {};4683 \\ var good = {};
...@@ -4478,10 +4685,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4478,10 +4685,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4478 \\ var bad = {};4685 \\ var bad = {};
4479 \\}4686 \\}
4480 , &[_][]const u8{4687 , &[_][]const u8{
4481 "tmp.zig:5:5: error: expected token ';', found 'var'",4688 "tmp.zig:5:5: error: expected ';', found 'var'",
4482 });4689 });
44834690
4484 cases.add("implicit semicolon - block expr",4691 ctx.objErrStage1("implicit semicolon - block expr",
4485 \\export fn entry() void {4692 \\export fn entry() void {
4486 \\ _ = {};4693 \\ _ = {};
4487 \\ var good = {};4694 \\ var good = {};
...@@ -4489,10 +4696,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4489,10 +4696,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4489 \\ var bad = {};4696 \\ var bad = {};
4490 \\}4697 \\}
4491 , &[_][]const u8{4698 , &[_][]const u8{
4492 "tmp.zig:5:5: error: expected token ';', found 'var'",4699 "tmp.zig:5:5: error: expected ';', found 'var'",
4493 });4700 });
44944701
4495 cases.add("implicit semicolon - comptime statement",4702 ctx.objErrStage1("implicit semicolon - comptime statement",
4496 \\export fn entry() void {4703 \\export fn entry() void {
4497 \\ comptime {}4704 \\ comptime {}
4498 \\ var good = {};4705 \\ var good = {};
...@@ -4500,10 +4707,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4500,10 +4707,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4500 \\ var bad = {};4707 \\ var bad = {};
4501 \\}4708 \\}
4502 , &[_][]const u8{4709 , &[_][]const u8{
4503 "tmp.zig:5:5: error: expected token ';', found 'var'",4710 "tmp.zig:5:5: error: expected ';', found 'var'",
4504 });4711 });
45054712
4506 cases.add("implicit semicolon - comptime expression",4713 ctx.objErrStage1("implicit semicolon - comptime expression",
4507 \\export fn entry() void {4714 \\export fn entry() void {
4508 \\ _ = comptime {};4715 \\ _ = comptime {};
4509 \\ var good = {};4716 \\ var good = {};
...@@ -4511,10 +4718,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4511,10 +4718,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4511 \\ var bad = {};4718 \\ var bad = {};
4512 \\}4719 \\}
4513 , &[_][]const u8{4720 , &[_][]const u8{
4514 "tmp.zig:5:5: error: expected token ';', found 'var'",4721 "tmp.zig:5:5: error: expected ';', found 'var'",
4515 });4722 });
45164723
4517 cases.add("implicit semicolon - defer",4724 ctx.objErrStage1("implicit semicolon - defer",
4518 \\export fn entry() void {4725 \\export fn entry() void {
4519 \\ defer {}4726 \\ defer {}
4520 \\ var good = {};4727 \\ var good = {};
...@@ -4522,10 +4729,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4522,10 +4729,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4522 \\ var bad = {};4729 \\ var bad = {};
4523 \\}4730 \\}
4524 , &[_][]const u8{4731 , &[_][]const u8{
4525 "tmp.zig:5:5: error: expected token ';', found 'var'",4732 "tmp.zig:5:5: error: expected ';', found 'var'",
4526 });4733 });
45274734
4528 cases.add("implicit semicolon - if statement",4735 ctx.objErrStage1("implicit semicolon - if statement",
4529 \\export fn entry() void {4736 \\export fn entry() void {
4530 \\ if(true) {}4737 \\ if(true) {}
4531 \\ var good = {};4738 \\ var good = {};
...@@ -4533,10 +4740,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4533,10 +4740,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4533 \\ var bad = {};4740 \\ var bad = {};
4534 \\}4741 \\}
4535 , &[_][]const u8{4742 , &[_][]const u8{
4536 "tmp.zig:5:5: error: expected token ';', found 'var'",4743 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
4537 });4744 });
45384745
4539 cases.add("implicit semicolon - if expression",4746 ctx.objErrStage1("implicit semicolon - if expression",
4540 \\export fn entry() void {4747 \\export fn entry() void {
4541 \\ _ = if(true) {};4748 \\ _ = if(true) {};
4542 \\ var good = {};4749 \\ var good = {};
...@@ -4544,10 +4751,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4544,10 +4751,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4544 \\ var bad = {};4751 \\ var bad = {};
4545 \\}4752 \\}
4546 , &[_][]const u8{4753 , &[_][]const u8{
4547 "tmp.zig:5:5: error: expected token ';', found 'var'",4754 "tmp.zig:5:5: error: expected ';', found 'var'",
4548 });4755 });
45494756
4550 cases.add("implicit semicolon - if-else statement",4757 ctx.objErrStage1("implicit semicolon - if-else statement",
4551 \\export fn entry() void {4758 \\export fn entry() void {
4552 \\ if(true) {} else {}4759 \\ if(true) {} else {}
4553 \\ var good = {};4760 \\ var good = {};
...@@ -4555,10 +4762,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4555,10 +4762,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4555 \\ var bad = {};4762 \\ var bad = {};
4556 \\}4763 \\}
4557 , &[_][]const u8{4764 , &[_][]const u8{
4558 "tmp.zig:5:5: error: expected token ';', found 'var'",4765 "tmp.zig:5:5: error: expected ';', found 'var'",
4559 });4766 });
45604767
4561 cases.add("implicit semicolon - if-else expression",4768 ctx.objErrStage1("implicit semicolon - if-else expression",
4562 \\export fn entry() void {4769 \\export fn entry() void {
4563 \\ _ = if(true) {} else {};4770 \\ _ = if(true) {} else {};
4564 \\ var good = {};4771 \\ var good = {};
...@@ -4566,10 +4773,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4566,10 +4773,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4566 \\ var bad = {};4773 \\ var bad = {};
4567 \\}4774 \\}
4568 , &[_][]const u8{4775 , &[_][]const u8{
4569 "tmp.zig:5:5: error: expected token ';', found 'var'",4776 "tmp.zig:5:5: error: expected ';', found 'var'",
4570 });4777 });
45714778
4572 cases.add("implicit semicolon - if-else-if statement",4779 ctx.objErrStage1("implicit semicolon - if-else-if statement",
4573 \\export fn entry() void {4780 \\export fn entry() void {
4574 \\ if(true) {} else if(true) {}4781 \\ if(true) {} else if(true) {}
4575 \\ var good = {};4782 \\ var good = {};
...@@ -4577,10 +4784,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4577,10 +4784,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4577 \\ var bad = {};4784 \\ var bad = {};
4578 \\}4785 \\}
4579 , &[_][]const u8{4786 , &[_][]const u8{
4580 "tmp.zig:5:5: error: expected token ';', found 'var'",4787 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
4581 });4788 });
45824789
4583 cases.add("implicit semicolon - if-else-if expression",4790 ctx.objErrStage1("implicit semicolon - if-else-if expression",
4584 \\export fn entry() void {4791 \\export fn entry() void {
4585 \\ _ = if(true) {} else if(true) {};4792 \\ _ = if(true) {} else if(true) {};
4586 \\ var good = {};4793 \\ var good = {};
...@@ -4588,10 +4795,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4588,10 +4795,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4588 \\ var bad = {};4795 \\ var bad = {};
4589 \\}4796 \\}
4590 , &[_][]const u8{4797 , &[_][]const u8{
4591 "tmp.zig:5:5: error: expected token ';', found 'var'",4798 "tmp.zig:5:5: error: expected ';', found 'var'",
4592 });4799 });
45934800
4594 cases.add("implicit semicolon - if-else-if-else statement",4801 ctx.objErrStage1("implicit semicolon - if-else-if-else statement",
4595 \\export fn entry() void {4802 \\export fn entry() void {
4596 \\ if(true) {} else if(true) {} else {}4803 \\ if(true) {} else if(true) {} else {}
4597 \\ var good = {};4804 \\ var good = {};
...@@ -4599,10 +4806,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4599,10 +4806,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4599 \\ var bad = {};4806 \\ var bad = {};
4600 \\}4807 \\}
4601 , &[_][]const u8{4808 , &[_][]const u8{
4602 "tmp.zig:5:5: error: expected token ';', found 'var'",4809 "tmp.zig:5:5: error: expected ';', found 'var'",
4603 });4810 });
46044811
4605 cases.add("implicit semicolon - if-else-if-else expression",4812 ctx.objErrStage1("implicit semicolon - if-else-if-else expression",
4606 \\export fn entry() void {4813 \\export fn entry() void {
4607 \\ _ = if(true) {} else if(true) {} else {};4814 \\ _ = if(true) {} else if(true) {} else {};
4608 \\ var good = {};4815 \\ var good = {};
...@@ -4610,10 +4817,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4610,10 +4817,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4610 \\ var bad = {};4817 \\ var bad = {};
4611 \\}4818 \\}
4612 , &[_][]const u8{4819 , &[_][]const u8{
4613 "tmp.zig:5:5: error: expected token ';', found 'var'",4820 "tmp.zig:5:5: error: expected ';', found 'var'",
4614 });4821 });
46154822
4616 cases.add("implicit semicolon - test statement",4823 ctx.objErrStage1("implicit semicolon - test statement",
4617 \\export fn entry() void {4824 \\export fn entry() void {
4618 \\ if (foo()) |_| {}4825 \\ if (foo()) |_| {}
4619 \\ var good = {};4826 \\ var good = {};
...@@ -4621,10 +4828,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4621,10 +4828,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4621 \\ var bad = {};4828 \\ var bad = {};
4622 \\}4829 \\}
4623 , &[_][]const u8{4830 , &[_][]const u8{
4624 "tmp.zig:5:5: error: expected token ';', found 'var'",4831 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
4625 });4832 });
46264833
4627 cases.add("implicit semicolon - test expression",4834 ctx.objErrStage1("implicit semicolon - test expression",
4628 \\export fn entry() void {4835 \\export fn entry() void {
4629 \\ _ = if (foo()) |_| {};4836 \\ _ = if (foo()) |_| {};
4630 \\ var good = {};4837 \\ var good = {};
...@@ -4632,10 +4839,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4632,10 +4839,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4632 \\ var bad = {};4839 \\ var bad = {};
4633 \\}4840 \\}
4634 , &[_][]const u8{4841 , &[_][]const u8{
4635 "tmp.zig:5:5: error: expected token ';', found 'var'",4842 "tmp.zig:5:5: error: expected ';', found 'var'",
4636 });4843 });
46374844
4638 cases.add("implicit semicolon - while statement",4845 ctx.objErrStage1("implicit semicolon - while statement",
4639 \\export fn entry() void {4846 \\export fn entry() void {
4640 \\ while(true) {}4847 \\ while(true) {}
4641 \\ var good = {};4848 \\ var good = {};
...@@ -4643,10 +4850,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4643,10 +4850,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4643 \\ var bad = {};4850 \\ var bad = {};
4644 \\}4851 \\}
4645 , &[_][]const u8{4852 , &[_][]const u8{
4646 "tmp.zig:5:5: error: expected token ';', found 'var'",4853 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
4647 });4854 });
46484855
4649 cases.add("implicit semicolon - while expression",4856 ctx.objErrStage1("implicit semicolon - while expression",
4650 \\export fn entry() void {4857 \\export fn entry() void {
4651 \\ _ = while(true) {};4858 \\ _ = while(true) {};
4652 \\ var good = {};4859 \\ var good = {};
...@@ -4654,10 +4861,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4654,10 +4861,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4654 \\ var bad = {};4861 \\ var bad = {};
4655 \\}4862 \\}
4656 , &[_][]const u8{4863 , &[_][]const u8{
4657 "tmp.zig:5:5: error: expected token ';', found 'var'",4864 "tmp.zig:5:5: error: expected ';', found 'var'",
4658 });4865 });
46594866
4660 cases.add("implicit semicolon - while-continue statement",4867 ctx.objErrStage1("implicit semicolon - while-continue statement",
4661 \\export fn entry() void {4868 \\export fn entry() void {
4662 \\ while(true):({}) {}4869 \\ while(true):({}) {}
4663 \\ var good = {};4870 \\ var good = {};
...@@ -4665,10 +4872,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4665,10 +4872,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4665 \\ var bad = {};4872 \\ var bad = {};
4666 \\}4873 \\}
4667 , &[_][]const u8{4874 , &[_][]const u8{
4668 "tmp.zig:5:5: error: expected token ';', found 'var'",4875 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
4669 });4876 });
46704877
4671 cases.add("implicit semicolon - while-continue expression",4878 ctx.objErrStage1("implicit semicolon - while-continue expression",
4672 \\export fn entry() void {4879 \\export fn entry() void {
4673 \\ _ = while(true):({}) {};4880 \\ _ = while(true):({}) {};
4674 \\ var good = {};4881 \\ var good = {};
...@@ -4676,10 +4883,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4676,10 +4883,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4676 \\ var bad = {};4883 \\ var bad = {};
4677 \\}4884 \\}
4678 , &[_][]const u8{4885 , &[_][]const u8{
4679 "tmp.zig:5:5: error: expected token ';', found 'var'",4886 "tmp.zig:5:5: error: expected ';', found 'var'",
4680 });4887 });
46814888
4682 cases.add("implicit semicolon - for statement",4889 ctx.objErrStage1("implicit semicolon - for statement",
4683 \\export fn entry() void {4890 \\export fn entry() void {
4684 \\ for(foo()) |_| {}4891 \\ for(foo()) |_| {}
4685 \\ var good = {};4892 \\ var good = {};
...@@ -4687,10 +4894,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4687,10 +4894,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4687 \\ var bad = {};4894 \\ var bad = {};
4688 \\}4895 \\}
4689 , &[_][]const u8{4896 , &[_][]const u8{
4690 "tmp.zig:5:5: error: expected token ';', found 'var'",4897 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
4691 });4898 });
46924899
4693 cases.add("implicit semicolon - for expression",4900 ctx.objErrStage1("implicit semicolon - for expression",
4694 \\export fn entry() void {4901 \\export fn entry() void {
4695 \\ _ = for(foo()) |_| {};4902 \\ _ = for(foo()) |_| {};
4696 \\ var good = {};4903 \\ var good = {};
...@@ -4698,32 +4905,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4698,32 +4905,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4698 \\ var bad = {};4905 \\ var bad = {};
4699 \\}4906 \\}
4700 , &[_][]const u8{4907 , &[_][]const u8{
4701 "tmp.zig:5:5: error: expected token ';', found 'var'",4908 "tmp.zig:5:5: error: expected ';', found 'var'",
4702 });4909 });
47034910
4704 cases.add("multiple function definitions",4911 ctx.objErrStage1("multiple function definitions",
4705 \\fn a() void {}4912 \\fn a() void {}
4706 \\fn a() void {}4913 \\fn a() void {}
4707 \\export fn entry() void { a(); }4914 \\export fn entry() void { a(); }
4708 , &[_][]const u8{4915 , &[_][]const u8{
4709 "tmp.zig:2:1: error: redefinition of 'a'",4916 "tmp.zig:2:1: error: redeclaration of 'a'",
4917 "tmp.zig:1:1: note: other declaration here",
4710 });4918 });
47114919
4712 cases.add("unreachable with return",4920 ctx.objErrStage1("unreachable with return",
4713 \\fn a() noreturn {return;}4921 \\fn a() noreturn {return;}
4714 \\export fn entry() void { a(); }4922 \\export fn entry() void { a(); }
4715 , &[_][]const u8{4923 , &[_][]const u8{
4716 "tmp.zig:1:18: error: expected type 'noreturn', found 'void'",4924 "tmp.zig:1:18: error: expected type 'noreturn', found 'void'",
4717 });4925 });
47184926
4719 cases.add("control reaches end of non-void function",4927 ctx.objErrStage1("control reaches end of non-void function",
4720 \\fn a() i32 {}4928 \\fn a() i32 {}
4721 \\export fn entry() void { _ = a(); }4929 \\export fn entry() void { _ = a(); }
4722 , &[_][]const u8{4930 , &[_][]const u8{
4723 "tmp.zig:1:12: error: expected type 'i32', found 'void'",4931 "tmp.zig:1:12: error: expected type 'i32', found 'void'",
4724 });4932 });
47254933
4726 cases.add("undefined function call",4934 ctx.objErrStage1("undefined function call",
4727 \\export fn a() void {4935 \\export fn a() void {
4728 \\ b();4936 \\ b();
4729 \\}4937 \\}
...@@ -4731,30 +4939,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4731,30 +4939,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4731 "tmp.zig:2:5: error: use of undeclared identifier 'b'",4939 "tmp.zig:2:5: error: use of undeclared identifier 'b'",
4732 });4940 });
47334941
4734 cases.add("wrong number of arguments",4942 ctx.objErrStage1("wrong number of arguments",
4735 \\export fn a() void {4943 \\export fn a() void {
4736 \\ b(1);4944 \\ c(1);
4737 \\}4945 \\}
4738 \\fn b(a: i32, b: i32, c: i32) void { }4946 \\fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
4739 , &[_][]const u8{4947 , &[_][]const u8{
4740 "tmp.zig:2:6: error: expected 3 argument(s), found 1",4948 "tmp.zig:2:6: error: expected 3 argument(s), found 1",
4741 });4949 });
47424950
4743 cases.add("invalid type",4951 ctx.objErrStage1("invalid type",
4744 \\fn a() bogus {}4952 \\fn a() bogus {}
4745 \\export fn entry() void { _ = a(); }4953 \\export fn entry() void { _ = a(); }
4746 , &[_][]const u8{4954 , &[_][]const u8{
4747 "tmp.zig:1:8: error: use of undeclared identifier 'bogus'",4955 "tmp.zig:1:8: error: use of undeclared identifier 'bogus'",
4748 });4956 });
47494957
4750 cases.add("pointer to noreturn",4958 ctx.objErrStage1("pointer to noreturn",
4751 \\fn a() *noreturn {}4959 \\fn a() *noreturn {}
4752 \\export fn entry() void { _ = a(); }4960 \\export fn entry() void { _ = a(); }
4753 , &[_][]const u8{4961 , &[_][]const u8{
4754 "tmp.zig:1:9: error: pointer to noreturn not allowed",4962 "tmp.zig:1:9: error: pointer to noreturn not allowed",
4755 });4963 });
47564964
4757 cases.add("unreachable code",4965 ctx.objErrStage1("unreachable code",
4758 \\export fn a() void {4966 \\export fn a() void {
4759 \\ return;4967 \\ return;
4760 \\ b();4968 \\ b();
...@@ -4762,17 +4970,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4762,17 +4970,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4762 \\4970 \\
4763 \\fn b() void {}4971 \\fn b() void {}
4764 , &[_][]const u8{4972 , &[_][]const u8{
4765 "tmp.zig:3:5: error: unreachable code",4973 "tmp.zig:3:6: error: unreachable code",
4974 "tmp.zig:2:5: note: control flow is diverted here",
4766 });4975 });
47674976
4768 cases.add("bad import",4977 ctx.objErrStage1("bad import",
4769 \\const bogus = @import("bogus-does-not-exist.zig",);4978 \\const bogus = @import("bogus-does-not-exist.zig",);
4770 \\export fn entry() void { bogus.bogo(); }
4771 , &[_][]const u8{4979 , &[_][]const u8{
4772 "tmp.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'",4980 "tmp.zig:1:23: error: unable to load '${DIR}bogus-does-not-exist.zig': FileNotFound",
4773 });4981 });
47744982
4775 cases.add("undeclared identifier",4983 ctx.objErrStage1("undeclared identifier",
4776 \\export fn a() void {4984 \\export fn a() void {
4777 \\ return4985 \\ return
4778 \\ b +4986 \\ b +
...@@ -4782,33 +4990,36 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4782,33 +4990,36 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4782 "tmp.zig:3:5: error: use of undeclared identifier 'b'",4990 "tmp.zig:3:5: error: use of undeclared identifier 'b'",
4783 });4991 });
47844992
4785 cases.add("parameter redeclaration",4993 ctx.objErrStage1("parameter redeclaration",
4786 \\fn f(a : i32, a : i32) void {4994 \\fn f(a : i32, a : i32) void {
4787 \\}4995 \\}
4788 \\export fn entry() void { f(1, 2); }4996 \\export fn entry() void { f(1, 2); }
4789 , &[_][]const u8{4997 , &[_][]const u8{
4790 "tmp.zig:1:15: error: redeclaration of variable 'a'",4998 "tmp.zig:1:15: error: redeclaration of function parameter 'a'",
4999 "tmp.zig:1:6: note: previous declaration here",
4791 });5000 });
47925001
4793 cases.add("local variable redeclaration",5002 ctx.objErrStage1("local variable redeclaration",
4794 \\export fn f() void {5003 \\export fn f() void {
4795 \\ const a : i32 = 0;5004 \\ const a : i32 = 0;
4796 \\ const a = 0;5005 \\ var a = 0;
4797 \\}5006 \\}
4798 , &[_][]const u8{5007 , &[_][]const u8{
4799 "tmp.zig:3:5: error: redeclaration of variable 'a'",5008 "tmp.zig:3:9: error: redeclaration of local constant 'a'",
5009 "tmp.zig:2:11: note: previous declaration here",
4800 });5010 });
48015011
4802 cases.add("local variable redeclares parameter",5012 ctx.objErrStage1("local variable redeclares parameter",
4803 \\fn f(a : i32) void {5013 \\fn f(a : i32) void {
4804 \\ const a = 0;5014 \\ const a = 0;
4805 \\}5015 \\}
4806 \\export fn entry() void { f(1); }5016 \\export fn entry() void { f(1); }
4807 , &[_][]const u8{5017 , &[_][]const u8{
4808 "tmp.zig:2:5: error: redeclaration of variable 'a'",5018 "tmp.zig:2:11: error: redeclaration of function parameter 'a'",
5019 "tmp.zig:1:6: note: previous declaration here",
4809 });5020 });
48105021
4811 cases.add("variable has wrong type",5022 ctx.objErrStage1("variable has wrong type",
4812 \\export fn f() i32 {5023 \\export fn f() i32 {
4813 \\ const a = "a";5024 \\ const a = "a";
4814 \\ return a;5025 \\ return a;
...@@ -4817,7 +5028,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4817,7 +5028,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4817 "tmp.zig:3:12: error: expected type 'i32', found '*const [1:0]u8'",5028 "tmp.zig:3:12: error: expected type 'i32', found '*const [1:0]u8'",
4818 });5029 });
48195030
4820 cases.add("if condition is bool, not int",5031 ctx.objErrStage1("if condition is bool, not int",
4821 \\export fn f() void {5032 \\export fn f() void {
4822 \\ if (0) {}5033 \\ if (0) {}
4823 \\}5034 \\}
...@@ -4825,30 +5036,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4825,30 +5036,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4825 "tmp.zig:2:9: error: expected type 'bool', found 'comptime_int'",5036 "tmp.zig:2:9: error: expected type 'bool', found 'comptime_int'",
4826 });5037 });
48275038
4828 cases.add("assign unreachable",5039 ctx.objErrStage1("assign unreachable",
4829 \\export fn f() void {5040 \\export fn f() void {
4830 \\ const a = return;5041 \\ const a = return;
4831 \\}5042 \\}
4832 , &[_][]const u8{5043 , &[_][]const u8{
4833 "tmp.zig:2:5: error: unreachable code",5044 "tmp.zig:2:5: error: unreachable code",
5045 "tmp.zig:2:15: note: control flow is diverted here",
4834 });5046 });
48355047
4836 cases.add("unreachable variable",5048 ctx.objErrStage1("unreachable variable",
4837 \\export fn f() void {5049 \\export fn f() void {
4838 \\ const a: noreturn = {};5050 \\ const a: noreturn = {};
5051 \\ _ = a;
4839 \\}5052 \\}
4840 , &[_][]const u8{5053 , &[_][]const u8{
4841 "tmp.zig:2:25: error: expected type 'noreturn', found 'void'",5054 "tmp.zig:2:25: error: expected type 'noreturn', found 'void'",
4842 });5055 });
48435056
4844 cases.add("unreachable parameter",5057 ctx.objErrStage1("unreachable parameter",
4845 \\fn f(a: noreturn) void {}5058 \\fn f(a: noreturn) void { _ = a; }
4846 \\export fn entry() void { f(); }5059 \\export fn entry() void { f(); }
4847 , &[_][]const u8{5060 , &[_][]const u8{
4848 "tmp.zig:1:9: error: parameter of type 'noreturn' not allowed",5061 "tmp.zig:1:9: error: parameter of type 'noreturn' not allowed",
4849 });5062 });
48505063
4851 cases.add("assign to constant variable",5064 ctx.objErrStage1("assign to constant variable",
4852 \\export fn f() void {5065 \\export fn f() void {
4853 \\ const a = 3;5066 \\ const a = 3;
4854 \\ a = 4;5067 \\ a = 4;
...@@ -4857,7 +5070,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4857,7 +5070,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4857 "tmp.zig:3:9: error: cannot assign to constant",5070 "tmp.zig:3:9: error: cannot assign to constant",
4858 });5071 });
48595072
4860 cases.add("use of undeclared identifier",5073 ctx.objErrStage1("use of undeclared identifier",
4861 \\export fn f() void {5074 \\export fn f() void {
4862 \\ b = 3;5075 \\ b = 3;
4863 \\}5076 \\}
...@@ -4865,15 +5078,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4865,15 +5078,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4865 "tmp.zig:2:5: error: use of undeclared identifier 'b'",5078 "tmp.zig:2:5: error: use of undeclared identifier 'b'",
4866 });5079 });
48675080
4868 cases.add("const is a statement, not an expression",5081 ctx.objErrStage1("const is a statement, not an expression",
4869 \\export fn f() void {5082 \\export fn f() void {
4870 \\ (const a = 0);5083 \\ (const a = 0);
4871 \\}5084 \\}
4872 , &[_][]const u8{5085 , &[_][]const u8{
4873 "tmp.zig:2:6: error: invalid token: 'const'",5086 "tmp.zig:2:6: error: expected expression, found 'const'",
4874 });5087 });
48755088
4876 cases.add("array access of undeclared identifier",5089 ctx.objErrStage1("array access of undeclared identifier",
4877 \\export fn f() void {5090 \\export fn f() void {
4878 \\ i[i] = i[i];5091 \\ i[i] = i[i];
4879 \\}5092 \\}
...@@ -4881,7 +5094,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4881,7 +5094,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4881 "tmp.zig:2:5: error: use of undeclared identifier 'i'",5094 "tmp.zig:2:5: error: use of undeclared identifier 'i'",
4882 });5095 });
48835096
4884 cases.add("array access of non array",5097 ctx.objErrStage1("array access of non array",
4885 \\export fn f() void {5098 \\export fn f() void {
4886 \\ var bad : bool = undefined;5099 \\ var bad : bool = undefined;
4887 \\ bad[0] = bad[0];5100 \\ bad[0] = bad[0];
...@@ -4895,7 +5108,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4895,7 +5108,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4895 "tmp.zig:7:12: error: array access of non-array type 'bool'",5108 "tmp.zig:7:12: error: array access of non-array type 'bool'",
4896 });5109 });
48975110
4898 cases.add("array access with non integer index",5111 ctx.objErrStage1("array access with non integer index",
4899 \\export fn f() void {5112 \\export fn f() void {
4900 \\ var array = "aoeu";5113 \\ var array = "aoeu";
4901 \\ var bad = false;5114 \\ var bad = false;
...@@ -4911,7 +5124,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4911,7 +5124,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4911 "tmp.zig:9:15: error: expected type 'usize', found 'bool'",5124 "tmp.zig:9:15: error: expected type 'usize', found 'bool'",
4912 });5125 });
49135126
4914 cases.add("write to const global variable",5127 ctx.objErrStage1("write to const global variable",
4915 \\const x : i32 = 99;5128 \\const x : i32 = 99;
4916 \\fn f() void {5129 \\fn f() void {
4917 \\ x = 1;5130 \\ x = 1;
...@@ -4921,58 +5134,64 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4921,58 +5134,64 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4921 "tmp.zig:3:9: error: cannot assign to constant",5134 "tmp.zig:3:9: error: cannot assign to constant",
4922 });5135 });
49235136
4924 cases.add("missing else clause",5137 ctx.objErrStage1("missing else clause",
4925 \\fn f(b: bool) void {5138 \\fn f(b: bool) void {
4926 \\ const x : i32 = if (b) h: { break :h 1; };5139 \\ const x : i32 = if (b) h: { break :h 1; };
5140 \\ _ = x;
4927 \\}5141 \\}
4928 \\fn g(b: bool) void {5142 \\fn g(b: bool) void {
4929 \\ const y = if (b) h: { break :h @as(i32, 1); };5143 \\ const y = if (b) h: { break :h @as(i32, 1); };
5144 \\ _ = y;
4930 \\}5145 \\}
4931 \\export fn entry() void { f(true); g(true); }5146 \\export fn entry() void { f(true); g(true); }
4932 , &[_][]const u8{5147 , &[_][]const u8{
4933 "tmp.zig:2:21: error: expected type 'i32', found 'void'",5148 "tmp.zig:2:21: error: expected type 'i32', found 'void'",
4934 "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",5149 "tmp.zig:6:15: error: incompatible types: 'i32' and 'void'",
4935 });5150 });
49365151
4937 cases.add("invalid struct field",5152 ctx.objErrStage1("invalid struct field",
4938 \\const A = struct { x : i32, };5153 \\const A = struct { x : i32, };
4939 \\export fn f() void {5154 \\export fn f() void {
4940 \\ var a : A = undefined;5155 \\ var a : A = undefined;
4941 \\ a.foo = 1;5156 \\ a.foo = 1;
4942 \\ const y = a.bar;5157 \\ const y = a.bar;
5158 \\ _ = y;
4943 \\}5159 \\}
4944 \\export fn g() void {5160 \\export fn g() void {
4945 \\ var a : A = undefined;5161 \\ var a : A = undefined;
4946 \\ const y = a.bar;5162 \\ const y = a.bar;
5163 \\ _ = y;
4947 \\}5164 \\}
4948 , &[_][]const u8{5165 , &[_][]const u8{
4949 "tmp.zig:4:6: error: no member named 'foo' in struct 'A'",5166 "tmp.zig:4:6: error: no member named 'foo' in struct 'A'",
4950 "tmp.zig:9:16: error: no member named 'bar' in struct 'A'",5167 "tmp.zig:10:16: error: no member named 'bar' in struct 'A'",
4951 });5168 });
49525169
4953 cases.add("redefinition of struct",5170 ctx.objErrStage1("redefinition of struct",
4954 \\const A = struct { x : i32, };5171 \\const A = struct { x : i32, };
4955 \\const A = struct { y : i32, };5172 \\const A = struct { y : i32, };
4956 , &[_][]const u8{5173 , &[_][]const u8{
4957 "tmp.zig:2:1: error: redefinition of 'A'",5174 "tmp.zig:2:1: error: redeclaration of 'A'",
5175 "tmp.zig:1:1: note: other declaration here",
4958 });5176 });
49595177
4960 cases.add("redefinition of enums",5178 ctx.objErrStage1("redefinition of enums",
4961 \\const A = enum {};5179 \\const A = enum {x};
4962 \\const A = enum {};5180 \\const A = enum {x};
4963 , &[_][]const u8{5181 , &[_][]const u8{
4964 "tmp.zig:2:1: error: redefinition of 'A'",5182 "tmp.zig:2:1: error: redeclaration of 'A'",
5183 "tmp.zig:1:1: note: other declaration here",
4965 });5184 });
49665185
4967 cases.add("redefinition of global variables",5186 ctx.objErrStage1("redefinition of global variables",
4968 \\var a : i32 = 1;5187 \\var a : i32 = 1;
4969 \\var a : i32 = 2;5188 \\var a : i32 = 2;
4970 , &[_][]const u8{5189 , &[_][]const u8{
4971 "tmp.zig:2:1: error: redefinition of 'a'",5190 "tmp.zig:2:1: error: redeclaration of 'a'",
4972 "tmp.zig:1:1: note: previous definition is here",5191 "tmp.zig:1:1: note: other declaration here",
4973 });5192 });
49745193
4975 cases.add("duplicate field in struct value expression",5194 ctx.objErrStage1("duplicate field in struct value expression",
4976 \\const A = struct {5195 \\const A = struct {
4977 \\ x : i32,5196 \\ x : i32,
4978 \\ y : i32,5197 \\ y : i32,
...@@ -4985,12 +5204,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4985,12 +5204,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4985 \\ .x = 3,5204 \\ .x = 3,
4986 \\ .z = 4,5205 \\ .z = 4,
4987 \\ };5206 \\ };
5207 \\ _ = a;
4988 \\}5208 \\}
4989 , &[_][]const u8{5209 , &[_][]const u8{
4990 "tmp.zig:11:9: error: duplicate field",5210 "tmp.zig:11:9: error: duplicate field",
4991 });5211 });
49925212
4993 cases.add("missing field in struct value expression",5213 ctx.objErrStage1("missing field in struct value expression",
4994 \\const A = struct {5214 \\const A = struct {
4995 \\ x : i32,5215 \\ x : i32,
4996 \\ y : i32,5216 \\ y : i32,
...@@ -5003,12 +5223,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5003,12 +5223,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5003 \\ .z = 4,5223 \\ .z = 4,
5004 \\ .y = 2,5224 \\ .y = 2,
5005 \\ };5225 \\ };
5226 \\ _ = a;
5006 \\}5227 \\}
5007 , &[_][]const u8{5228 , &[_][]const u8{
5008 "tmp.zig:9:17: error: missing field: 'x'",5229 "tmp.zig:9:17: error: missing field: 'x'",
5009 });5230 });
50105231
5011 cases.add("invalid field in struct value expression",5232 ctx.objErrStage1("invalid field in struct value expression",
5012 \\const A = struct {5233 \\const A = struct {
5013 \\ x : i32,5234 \\ x : i32,
5014 \\ y : i32,5235 \\ y : i32,
...@@ -5020,12 +5241,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5020,12 +5241,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5020 \\ .y = 2,5241 \\ .y = 2,
5021 \\ .foo = 42,5242 \\ .foo = 42,
5022 \\ };5243 \\ };
5244 \\ _ = a;
5023 \\}5245 \\}
5024 , &[_][]const u8{5246 , &[_][]const u8{
5025 "tmp.zig:10:9: error: no member named 'foo' in struct 'A'",5247 "tmp.zig:10:9: error: no member named 'foo' in struct 'A'",
5026 });5248 });
50275249
5028 cases.add("invalid break expression",5250 ctx.objErrStage1("invalid break expression",
5029 \\export fn f() void {5251 \\export fn f() void {
5030 \\ break;5252 \\ break;
5031 \\}5253 \\}
...@@ -5033,7 +5255,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5033,7 +5255,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5033 "tmp.zig:2:5: error: break expression outside loop",5255 "tmp.zig:2:5: error: break expression outside loop",
5034 });5256 });
50355257
5036 cases.add("invalid continue expression",5258 ctx.objErrStage1("invalid continue expression",
5037 \\export fn f() void {5259 \\export fn f() void {
5038 \\ continue;5260 \\ continue;
5039 \\}5261 \\}
...@@ -5041,48 +5263,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5041,48 +5263,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5041 "tmp.zig:2:5: error: continue expression outside loop",5263 "tmp.zig:2:5: error: continue expression outside loop",
5042 });5264 });
50435265
5044 cases.add("invalid maybe type",5266 ctx.objErrStage1("invalid maybe type",
5045 \\export fn f() void {5267 \\export fn f() void {
5046 \\ if (true) |x| { }5268 \\ if (true) |x| { _ = x; }
5047 \\}5269 \\}
5048 , &[_][]const u8{5270 , &[_][]const u8{
5049 "tmp.zig:2:9: error: expected optional type, found 'bool'",5271 "tmp.zig:2:9: error: expected optional type, found 'bool'",
5050 });5272 });
50515273
5052 cases.add("cast unreachable",5274 ctx.objErrStage1("cast unreachable",
5053 \\fn f() i32 {5275 \\fn f() i32 {
5054 \\ return @as(i32, return 1);5276 \\ return @as(i32, return 1);
5055 \\}5277 \\}
5056 \\export fn entry() void { _ = f(); }5278 \\export fn entry() void { _ = f(); }
5057 , &[_][]const u8{5279 , &[_][]const u8{
5058 "tmp.zig:2:12: error: unreachable code",5280 "tmp.zig:2:12: error: unreachable code",
5281 "tmp.zig:2:21: note: control flow is diverted here",
5059 });5282 });
50605283
5061 cases.add("invalid builtin fn",5284 ctx.objErrStage1("invalid builtin fn",
5062 \\fn f() @bogus(foo) {5285 \\fn f() @bogus(foo) {
5063 \\}5286 \\}
5064 \\export fn entry() void { _ = f(); }5287 \\export fn entry() void { _ = f(); }
5065 , &[_][]const u8{5288 , &[_][]const u8{
5066 "tmp.zig:1:8: error: invalid builtin function: 'bogus'",5289 "tmp.zig:1:8: error: invalid builtin function: '@bogus'",
5067 });5290 });
50685291
5069 cases.add("noalias on non pointer param",5292 ctx.objErrStage1("noalias on non pointer param",
5070 \\fn f(noalias x: i32) void {}5293 \\fn f(noalias x: i32) void { _ = x; }
5071 \\export fn entry() void { f(1234); }5294 \\export fn entry() void { f(1234); }
5072 , &[_][]const u8{5295 , &[_][]const u8{
5073 "tmp.zig:1:6: error: noalias on non-pointer parameter",5296 "tmp.zig:1:6: error: noalias on non-pointer parameter",
5074 });5297 });
50755298
5076 cases.add("struct init syntax for array",5299 ctx.objErrStage1("struct init syntax for array",
5077 \\const foo = [3]u16{ .x = 1024 };5300 \\const foo = [3]u16{ .x = 1024 };
5078 \\comptime {5301 \\comptime {
5079 \\ _ = foo;5302 \\ _ = foo;
5080 \\}5303 \\}
5081 , &[_][]const u8{5304 , &[_][]const u8{
5082 "tmp.zig:1:21: error: type '[3]u16' does not support struct initialization syntax",5305 "tmp.zig:1:13: error: initializing array with struct syntax",
5083 });5306 });
50845307
5085 cases.add("type variables must be constant",5308 ctx.objErrStage1("type variables must be constant",
5086 \\var foo = u8;5309 \\var foo = u8;
5087 \\export fn entry() foo {5310 \\export fn entry() foo {
5088 \\ return 1;5311 \\ return 1;
...@@ -5091,25 +5314,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5091,25 +5314,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5091 "tmp.zig:1:1: error: variable of type 'type' must be constant",5314 "tmp.zig:1:1: error: variable of type 'type' must be constant",
5092 });5315 });
50935316
5094 cases.add("variables shadowing types",5317 ctx.objErrStage1("parameter shadowing global",
5095 \\const Foo = struct {};5318 \\const Foo = struct {};
5096 \\const Bar = struct {};5319 \\fn f(Foo: i32) void {}
5097 \\5320 \\export fn entry() void {
5098 \\fn f(Foo: i32) void {5321 \\ f(1234);
5099 \\ var Bar : i32 = undefined;
5100 \\}5322 \\}
5323 , &[_][]const u8{
5324 "tmp.zig:2:6: error: local shadows declaration of 'Foo'",
5325 "tmp.zig:1:1: note: declared here",
5326 });
5327
5328 ctx.objErrStage1("local variable shadowing global",
5329 \\const Foo = struct {};
5330 \\const Bar = struct {};
5101 \\5331 \\
5102 \\export fn entry() void {5332 \\export fn entry() void {
5103 \\ f(1234);5333 \\ var Bar : i32 = undefined;
5334 \\ _ = Bar;
5104 \\}5335 \\}
5105 , &[_][]const u8{5336 , &[_][]const u8{
5106 "tmp.zig:4:6: error: redefinition of 'Foo'",5337 "tmp.zig:5:9: error: local shadows declaration of 'Bar'",
5107 "tmp.zig:1:1: note: previous definition is here",5338 "tmp.zig:2:1: note: declared here",
5108 "tmp.zig:5:5: error: redefinition of 'Bar'",
5109 "tmp.zig:2:1: note: previous definition is here",
5110 });5339 });
51115340
5112 cases.add("switch expression - missing enumeration prong",5341 ctx.objErrStage1("switch expression - missing enumeration prong",
5113 \\const Number = enum {5342 \\const Number = enum {
5114 \\ One,5343 \\ One,
5115 \\ Two,5344 \\ Two,
...@@ -5129,7 +5358,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5129,7 +5358,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5129 "tmp.zig:8:5: error: enumeration value 'Number.Four' not handled in switch",5358 "tmp.zig:8:5: error: enumeration value 'Number.Four' not handled in switch",
5130 });5359 });
51315360
5132 cases.add("switch expression - duplicate enumeration prong",5361 ctx.objErrStage1("switch expression - duplicate enumeration prong",
5133 \\const Number = enum {5362 \\const Number = enum {
5134 \\ One,5363 \\ One,
5135 \\ Two,5364 \\ Two,
...@@ -5149,10 +5378,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5149,10 +5378,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5149 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }5378 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
5150 , &[_][]const u8{5379 , &[_][]const u8{
5151 "tmp.zig:13:15: error: duplicate switch value",5380 "tmp.zig:13:15: error: duplicate switch value",
5152 "tmp.zig:10:15: note: other value is here",5381 "tmp.zig:10:15: note: other value here",
5153 });5382 });
51545383
5155 cases.add("switch expression - duplicate enumeration prong when else present",5384 ctx.objErrStage1("switch expression - duplicate enumeration prong when else present",
5156 \\const Number = enum {5385 \\const Number = enum {
5157 \\ One,5386 \\ One,
5158 \\ Two,5387 \\ Two,
...@@ -5173,10 +5402,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5173,10 +5402,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5173 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }5402 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
5174 , &[_][]const u8{5403 , &[_][]const u8{
5175 "tmp.zig:13:15: error: duplicate switch value",5404 "tmp.zig:13:15: error: duplicate switch value",
5176 "tmp.zig:10:15: note: other value is here",5405 "tmp.zig:10:15: note: other value here",
5177 });5406 });
51785407
5179 cases.add("switch expression - multiple else prongs",5408 ctx.objErrStage1("switch expression - multiple else prongs",
5180 \\fn f(x: u32) void {5409 \\fn f(x: u32) void {
5181 \\ const value: bool = switch (x) {5410 \\ const value: bool = switch (x) {
5182 \\ 1234 => false,5411 \\ 1234 => false,
...@@ -5191,7 +5420,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5191,7 +5420,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5191 "tmp.zig:5:9: error: multiple else prongs in switch expression",5420 "tmp.zig:5:9: error: multiple else prongs in switch expression",
5192 });5421 });
51935422
5194 cases.add("switch expression - non exhaustive integer prongs",5423 ctx.objErrStage1("switch expression - non exhaustive integer prongs",
5195 \\fn foo(x: u8) void {5424 \\fn foo(x: u8) void {
5196 \\ switch (x) {5425 \\ switch (x) {
5197 \\ 0 => {},5426 \\ 0 => {},
...@@ -5202,7 +5431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5202,7 +5431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5202 "tmp.zig:2:5: error: switch must handle all possibilities",5431 "tmp.zig:2:5: error: switch must handle all possibilities",
5203 });5432 });
52045433
5205 cases.add("switch expression - duplicate or overlapping integer value",5434 ctx.objErrStage1("switch expression - duplicate or overlapping integer value",
5206 \\fn foo(x: u8) u8 {5435 \\fn foo(x: u8) u8 {
5207 \\ return switch (x) {5436 \\ return switch (x) {
5208 \\ 0 ... 100 => @as(u8, 0),5437 \\ 0 ... 100 => @as(u8, 0),
...@@ -5214,11 +5443,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5214,11 +5443,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5214 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }5443 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
5215 , &[_][]const u8{5444 , &[_][]const u8{
5216 "tmp.zig:6:9: error: duplicate switch value",5445 "tmp.zig:6:9: error: duplicate switch value",
5217 "tmp.zig:5:14: note: previous value is here",5446 "tmp.zig:5:14: note: previous value here",
5218 });5447 });
52195448
5220 cases.add("switch expression - duplicate type",5449 ctx.objErrStage1("switch expression - duplicate type",
5221 \\fn foo(comptime T: type, x: T) u8 {5450 \\fn foo(comptime T: type, x: T) u8 {
5451 \\ _ = x;
5222 \\ return switch (T) {5452 \\ return switch (T) {
5223 \\ u32 => 0,5453 \\ u32 => 0,
5224 \\ u64 => 1,5454 \\ u64 => 1,
...@@ -5228,16 +5458,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5228,16 +5458,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5228 \\}5458 \\}
5229 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); }5459 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); }
5230 , &[_][]const u8{5460 , &[_][]const u8{
5231 "tmp.zig:5:9: error: duplicate switch value",5461 "tmp.zig:6:9: error: duplicate switch value",
5232 "tmp.zig:3:9: note: previous value is here",5462 "tmp.zig:4:9: note: previous value here",
5233 });5463 });
52345464
5235 cases.add("switch expression - duplicate type (struct alias)",5465 ctx.objErrStage1("switch expression - duplicate type (struct alias)",
5236 \\const Test = struct {5466 \\const Test = struct {
5237 \\ bar: i32,5467 \\ bar: i32,
5238 \\};5468 \\};
5239 \\const Test2 = Test;5469 \\const Test2 = Test;
5240 \\fn foo(comptime T: type, x: T) u8 {5470 \\fn foo(comptime T: type, x: T) u8 {
5471 \\ _ = x;
5241 \\ return switch (T) {5472 \\ return switch (T) {
5242 \\ Test => 0,5473 \\ Test => 0,
5243 \\ u64 => 1,5474 \\ u64 => 1,
...@@ -5247,11 +5478,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5247,11 +5478,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5247 \\}5478 \\}
5248 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); }5479 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); }
5249 , &[_][]const u8{5480 , &[_][]const u8{
5250 "tmp.zig:9:9: error: duplicate switch value",5481 "tmp.zig:10:9: error: duplicate switch value",
5251 "tmp.zig:7:9: note: previous value is here",5482 "tmp.zig:8:9: note: previous value here",
5252 });5483 });
52535484
5254 cases.add("switch expression - switch on pointer type with no else",5485 ctx.objErrStage1("switch expression - switch on pointer type with no else",
5255 \\fn foo(x: *u8) void {5486 \\fn foo(x: *u8) void {
5256 \\ switch (x) {5487 \\ switch (x) {
5257 \\ &y => {},5488 \\ &y => {},
...@@ -5263,7 +5494,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5263,7 +5494,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5263 "tmp.zig:2:5: error: else prong required when switching on type '*u8'",5494 "tmp.zig:2:5: error: else prong required when switching on type '*u8'",
5264 });5495 });
52655496
5266 cases.add("global variable initializer must be constant expression",5497 ctx.objErrStage1("global variable initializer must be constant expression",
5267 \\extern fn foo() i32;5498 \\extern fn foo() i32;
5268 \\const x = foo();5499 \\const x = foo();
5269 \\export fn entry() i32 { return x; }5500 \\export fn entry() i32 { return x; }
...@@ -5271,7 +5502,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5271,7 +5502,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5271 "tmp.zig:2:11: error: unable to evaluate constant expression",5502 "tmp.zig:2:11: error: unable to evaluate constant expression",
5272 });5503 });
52735504
5274 cases.add("array concatenation with wrong type",5505 ctx.objErrStage1("array concatenation with wrong type",
5275 \\const src = "aoeu";5506 \\const src = "aoeu";
5276 \\const derp: usize = 1234;5507 \\const derp: usize = 1234;
5277 \\const a = derp ++ "foo";5508 \\const a = derp ++ "foo";
...@@ -5281,7 +5512,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5281,7 +5512,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5281 "tmp.zig:3:11: error: expected array, found 'usize'",5512 "tmp.zig:3:11: error: expected array, found 'usize'",
5282 });5513 });
52835514
5284 cases.add("non compile time array concatenation",5515 ctx.objErrStage1("non compile time array concatenation",
5285 \\fn f() []u8 {5516 \\fn f() []u8 {
5286 \\ return s ++ "foo";5517 \\ return s ++ "foo";
5287 \\}5518 \\}
...@@ -5291,7 +5522,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5291,7 +5522,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5291 "tmp.zig:2:12: error: unable to evaluate constant expression",5522 "tmp.zig:2:12: error: unable to evaluate constant expression",
5292 });5523 });
52935524
5294 cases.add("@cImport with bogus include",5525 ctx.objErrStage1("@cImport with bogus include",
5295 \\const c = @cImport(@cInclude("bogus.h"));5526 \\const c = @cImport(@cInclude("bogus.h"));
5296 \\export fn entry() usize { return @sizeOf(@TypeOf(c.bogo)); }5527 \\export fn entry() usize { return @sizeOf(@TypeOf(c.bogo)); }
5297 , &[_][]const u8{5528 , &[_][]const u8{
...@@ -5299,7 +5530,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5299,7 +5530,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5299 ".h:1:10: note: 'bogus.h' file not found",5530 ".h:1:10: note: 'bogus.h' file not found",
5300 });5531 });
53015532
5302 cases.add("address of number literal",5533 ctx.objErrStage1("address of number literal",
5303 \\const x = 3;5534 \\const x = 3;
5304 \\const y = &x;5535 \\const y = &x;
5305 \\fn foo() *const i32 { return y; }5536 \\fn foo() *const i32 { return y; }
...@@ -5308,14 +5539,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5308,14 +5539,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5308 "tmp.zig:3:30: error: expected type '*const i32', found '*const comptime_int'",5539 "tmp.zig:3:30: error: expected type '*const i32', found '*const comptime_int'",
5309 });5540 });
53105541
5311 cases.add("integer overflow error",5542 ctx.objErrStage1("integer overflow error",
5312 \\const x : u8 = 300;5543 \\const x : u8 = 300;
5313 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }5544 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }
5314 , &[_][]const u8{5545 , &[_][]const u8{
5315 "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'",5546 "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'",
5316 });5547 });
53175548
5318 cases.add("invalid shift amount error",5549 ctx.objErrStage1("invalid shift amount error",
5319 \\const x : u8 = 2;5550 \\const x : u8 = 2;
5320 \\fn f() u16 {5551 \\fn f() u16 {
5321 \\ return x << 8;5552 \\ return x << 8;
...@@ -5325,7 +5556,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5325,7 +5556,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5325 "tmp.zig:3:17: error: integer value 8 cannot be coerced to type 'u3'",5556 "tmp.zig:3:17: error: integer value 8 cannot be coerced to type 'u3'",
5326 });5557 });
53275558
5328 cases.add("missing function call param",5559 ctx.objErrStage1("missing function call param",
5329 \\const Foo = struct {5560 \\const Foo = struct {
5330 \\ a: i32,5561 \\ a: i32,
5331 \\ b: i32,5562 \\ b: i32,
...@@ -5346,6 +5577,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5346,6 +5577,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5346 \\5577 \\
5347 \\fn f(foo: *const Foo, index: usize) void {5578 \\fn f(foo: *const Foo, index: usize) void {
5348 \\ const result = members[index]();5579 \\ const result = members[index]();
5580 \\ _ = foo;
5581 \\ _ = result;
5349 \\}5582 \\}
5350 \\5583 \\
5351 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }5584 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
...@@ -5353,21 +5586,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5353,21 +5586,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5353 "tmp.zig:20:34: error: expected 1 argument(s), found 0",5586 "tmp.zig:20:34: error: expected 1 argument(s), found 0",
5354 });5587 });
53555588
5356 cases.add("missing function name",5589 ctx.objErrStage1("missing function name",
5357 \\fn () void {}5590 \\fn () void {}
5358 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }5591 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
5359 , &[_][]const u8{5592 , &[_][]const u8{
5360 "tmp.zig:1:1: error: missing function name",5593 "tmp.zig:1:1: error: missing function name",
5361 });5594 });
53625595
5363 cases.add("missing param name",5596 ctx.objErrStage1("missing param name",
5364 \\fn f(i32) void {}5597 \\fn f(i32) void {}
5365 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }5598 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
5366 , &[_][]const u8{5599 , &[_][]const u8{
5367 "tmp.zig:1:6: error: missing parameter name",5600 "tmp.zig:1:6: error: missing parameter name",
5368 });5601 });
53695602
5370 cases.add("wrong function type",5603 ctx.objErrStage1("wrong function type",
5371 \\const fns = [_]fn() void { a, b, c };5604 \\const fns = [_]fn() void { a, b, c };
5372 \\fn a() i32 {return 0;}5605 \\fn a() i32 {return 0;}
5373 \\fn b() i32 {return 1;}5606 \\fn b() i32 {return 1;}
...@@ -5377,7 +5610,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5377,7 +5610,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5377 "tmp.zig:1:28: error: expected type 'fn() void', found 'fn() i32'",5610 "tmp.zig:1:28: error: expected type 'fn() void', found 'fn() i32'",
5378 });5611 });
53795612
5380 cases.add("extern function pointer mismatch",5613 ctx.objErrStage1("extern function pointer mismatch",
5381 \\const fns = [_](fn(i32)i32) { a, b, c };5614 \\const fns = [_](fn(i32)i32) { a, b, c };
5382 \\pub fn a(x: i32) i32 {return x + 0;}5615 \\pub fn a(x: i32) i32 {return x + 0;}
5383 \\pub fn b(x: i32) i32 {return x + 1;}5616 \\pub fn b(x: i32) i32 {return x + 1;}
...@@ -5388,15 +5621,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5388,15 +5621,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5388 "tmp.zig:1:37: error: expected type 'fn(i32) i32', found 'fn(i32) callconv(.C) i32'",5621 "tmp.zig:1:37: error: expected type 'fn(i32) i32', found 'fn(i32) callconv(.C) i32'",
5389 });5622 });
53905623
5391 cases.add("colliding invalid top level functions",5624 ctx.objErrStage1("colliding invalid top level functions",
5392 \\fn func() bogus {}5625 \\fn func() bogus {}
5393 \\fn func() bogus {}5626 \\fn func() bogus {}
5394 \\export fn entry() usize { return @sizeOf(@TypeOf(func)); }5627 \\export fn entry() usize { return @sizeOf(@TypeOf(func)); }
5395 , &[_][]const u8{5628 , &[_][]const u8{
5396 "tmp.zig:2:1: error: redefinition of 'func'",5629 "tmp.zig:2:1: error: redeclaration of 'func'",
5630 "tmp.zig:1:1: note: other declaration here",
5397 });5631 });
53985632
5399 cases.add("non constant expression in array size",5633 ctx.objErrStage1("non constant expression in array size",
5400 \\const Foo = struct {5634 \\const Foo = struct {
5401 \\ y: [get()]u8,5635 \\ y: [get()]u8,
5402 \\};5636 \\};
...@@ -5409,7 +5643,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5409,7 +5643,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5409 "tmp.zig:2:12: note: called from here",5643 "tmp.zig:2:12: note: called from here",
5410 });5644 });
54115645
5412 cases.add("addition with non numbers",5646 ctx.objErrStage1("addition with non numbers",
5413 \\const Foo = struct {5647 \\const Foo = struct {
5414 \\ field: i32,5648 \\ field: i32,
5415 \\};5649 \\};
...@@ -5420,7 +5654,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5420,7 +5654,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5420 "tmp.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'",5654 "tmp.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'",
5421 });5655 });
54225656
5423 cases.add("division by zero",5657 ctx.objErrStage1("division by zero",
5424 \\const lit_int_x = 1 / 0;5658 \\const lit_int_x = 1 / 0;
5425 \\const lit_float_x = 1.0 / 0.0;5659 \\const lit_float_x = 1.0 / 0.0;
5426 \\const int_x = @as(u32, 1) / @as(u32, 0);5660 \\const int_x = @as(u32, 1) / @as(u32, 0);
...@@ -5437,16 +5671,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5437,16 +5671,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5437 "tmp.zig:4:31: error: division by zero",5671 "tmp.zig:4:31: error: division by zero",
5438 });5672 });
54395673
5440 cases.add("normal string with newline",5674 ctx.objErrStage1("normal string with newline",
5441 \\const foo = "a5675 \\const foo = "a
5442 \\b";5676 \\b";
5443 \\
5444 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
5445 , &[_][]const u8{5677 , &[_][]const u8{
5446 "tmp.zig:1:15: error: newline not allowed in string literal",5678 "tmp.zig:1:13: error: expected expression, found 'invalid'",
5679 "tmp.zig:1:15: note: invalid byte: '\\n'",
5447 });5680 });
54485681
5449 cases.add("invalid comparison for function pointers",5682 ctx.objErrStage1("invalid comparison for function pointers",
5450 \\fn foo() void {}5683 \\fn foo() void {}
5451 \\const invalid = foo > foo;5684 \\const invalid = foo > foo;
5452 \\5685 \\
...@@ -5455,7 +5688,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5455,7 +5688,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5455 "tmp.zig:2:21: error: operator not allowed for type 'fn() void'",5688 "tmp.zig:2:21: error: operator not allowed for type 'fn() void'",
5456 });5689 });
54575690
5458 cases.add("generic function instance with non-constant expression",5691 ctx.objErrStage1("generic function instance with non-constant expression",
5459 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }5692 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }
5460 \\fn test1(a: i32, b: i32) i32 {5693 \\fn test1(a: i32, b: i32) i32 {
5461 \\ return foo(a, b);5694 \\ return foo(a, b);
...@@ -5466,7 +5699,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5466,7 +5699,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5466 "tmp.zig:3:16: error: runtime value cannot be passed to comptime arg",5699 "tmp.zig:3:16: error: runtime value cannot be passed to comptime arg",
5467 });5700 });
54685701
5469 cases.add("assign null to non-optional pointer",5702 ctx.objErrStage1("assign null to non-optional pointer",
5470 \\const a: *u8 = null;5703 \\const a: *u8 = null;
5471 \\5704 \\
5472 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); }5705 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); }
...@@ -5474,26 +5707,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5474,26 +5707,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5474 "tmp.zig:1:16: error: expected type '*u8', found '(null)'",5707 "tmp.zig:1:16: error: expected type '*u8', found '(null)'",
5475 });5708 });
54765709
5477 cases.add("indexing an array of size zero",5710 ctx.objErrStage1("indexing an array of size zero",
5478 \\const array = [_]u8{};5711 \\const array = [_]u8{};
5479 \\export fn foo() void {5712 \\export fn foo() void {
5480 \\ const pointer = &array[0];5713 \\ const pointer = &array[0];
5714 \\ _ = pointer;
5481 \\}5715 \\}
5482 , &[_][]const u8{5716 , &[_][]const u8{
5483 "tmp.zig:3:27: error: accessing a zero length array is not allowed",5717 "tmp.zig:3:27: error: accessing a zero length array is not allowed",
5484 });5718 });
54855719
5486 cases.add("indexing an array of size zero with runtime index",5720 ctx.objErrStage1("indexing an array of size zero with runtime index",
5487 \\const array = [_]u8{};5721 \\const array = [_]u8{};
5488 \\export fn foo() void {5722 \\export fn foo() void {
5489 \\ var index: usize = 0;5723 \\ var index: usize = 0;
5490 \\ const pointer = &array[index];5724 \\ const pointer = &array[index];
5725 \\ _ = pointer;
5491 \\}5726 \\}
5492 , &[_][]const u8{5727 , &[_][]const u8{
5493 "tmp.zig:4:27: error: accessing a zero length array is not allowed",5728 "tmp.zig:4:27: error: accessing a zero length array is not allowed",
5494 });5729 });
54955730
5496 cases.add("compile time division by zero",5731 ctx.objErrStage1("compile time division by zero",
5497 \\const y = foo(0);5732 \\const y = foo(0);
5498 \\fn foo(x: u32) u32 {5733 \\fn foo(x: u32) u32 {
5499 \\ return 1 / x;5734 \\ return 1 / x;
...@@ -5505,7 +5740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5505,7 +5740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5505 "tmp.zig:1:14: note: referenced here",5740 "tmp.zig:1:14: note: referenced here",
5506 });5741 });
55075742
5508 cases.add("branch on undefined value",5743 ctx.objErrStage1("branch on undefined value",
5509 \\const x = if (undefined) true else false;5744 \\const x = if (undefined) true else false;
5510 \\5745 \\
5511 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }5746 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }
...@@ -5513,7 +5748,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5513,7 +5748,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5513 "tmp.zig:1:15: error: use of undefined value here causes undefined behavior",5748 "tmp.zig:1:15: error: use of undefined value here causes undefined behavior",
5514 });5749 });
55155750
5516 cases.add("div on undefined value",5751 ctx.objErrStage1("div on undefined value",
5517 \\comptime {5752 \\comptime {
5518 \\ var a: i64 = undefined;5753 \\ var a: i64 = undefined;
5519 \\ _ = a / a;5754 \\ _ = a / a;
...@@ -5522,7 +5757,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5522,7 +5757,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5522 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5757 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5523 });5758 });
55245759
5525 cases.add("div assign on undefined value",5760 ctx.objErrStage1("div assign on undefined value",
5526 \\comptime {5761 \\comptime {
5527 \\ var a: i64 = undefined;5762 \\ var a: i64 = undefined;
5528 \\ a /= a;5763 \\ a /= a;
...@@ -5531,7 +5766,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5531,7 +5766,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5531 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5766 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5532 });5767 });
55335768
5534 cases.add("mod on undefined value",5769 ctx.objErrStage1("mod on undefined value",
5535 \\comptime {5770 \\comptime {
5536 \\ var a: i64 = undefined;5771 \\ var a: i64 = undefined;
5537 \\ _ = a % a;5772 \\ _ = a % a;
...@@ -5540,7 +5775,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5540,7 +5775,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5540 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5775 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5541 });5776 });
55425777
5543 cases.add("mod assign on undefined value",5778 ctx.objErrStage1("mod assign on undefined value",
5544 \\comptime {5779 \\comptime {
5545 \\ var a: i64 = undefined;5780 \\ var a: i64 = undefined;
5546 \\ a %= a;5781 \\ a %= a;
...@@ -5549,7 +5784,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5549,7 +5784,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5549 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5784 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5550 });5785 });
55515786
5552 cases.add("add on undefined value",5787 ctx.objErrStage1("add on undefined value",
5553 \\comptime {5788 \\comptime {
5554 \\ var a: i64 = undefined;5789 \\ var a: i64 = undefined;
5555 \\ _ = a + a;5790 \\ _ = a + a;
...@@ -5558,7 +5793,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5558,7 +5793,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5558 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5793 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5559 });5794 });
55605795
5561 cases.add("add assign on undefined value",5796 ctx.objErrStage1("add assign on undefined value",
5562 \\comptime {5797 \\comptime {
5563 \\ var a: i64 = undefined;5798 \\ var a: i64 = undefined;
5564 \\ a += a;5799 \\ a += a;
...@@ -5567,7 +5802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5567,7 +5802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5567 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5802 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5568 });5803 });
55695804
5570 cases.add("add wrap on undefined value",5805 ctx.objErrStage1("add wrap on undefined value",
5571 \\comptime {5806 \\comptime {
5572 \\ var a: i64 = undefined;5807 \\ var a: i64 = undefined;
5573 \\ _ = a +% a;5808 \\ _ = a +% a;
...@@ -5576,7 +5811,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5576,7 +5811,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5576 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5811 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5577 });5812 });
55785813
5579 cases.add("add wrap assign on undefined value",5814 ctx.objErrStage1("add wrap assign on undefined value",
5580 \\comptime {5815 \\comptime {
5581 \\ var a: i64 = undefined;5816 \\ var a: i64 = undefined;
5582 \\ a +%= a;5817 \\ a +%= a;
...@@ -5585,7 +5820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5585,7 +5820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5585 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5820 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5586 });5821 });
55875822
5588 cases.add("sub on undefined value",5823 ctx.objErrStage1("sub on undefined value",
5589 \\comptime {5824 \\comptime {
5590 \\ var a: i64 = undefined;5825 \\ var a: i64 = undefined;
5591 \\ _ = a - a;5826 \\ _ = a - a;
...@@ -5594,7 +5829,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5594,7 +5829,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5594 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5829 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5595 });5830 });
55965831
5597 cases.add("sub assign on undefined value",5832 ctx.objErrStage1("sub assign on undefined value",
5598 \\comptime {5833 \\comptime {
5599 \\ var a: i64 = undefined;5834 \\ var a: i64 = undefined;
5600 \\ a -= a;5835 \\ a -= a;
...@@ -5603,7 +5838,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5603,7 +5838,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5603 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5838 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5604 });5839 });
56055840
5606 cases.add("sub wrap on undefined value",5841 ctx.objErrStage1("sub wrap on undefined value",
5607 \\comptime {5842 \\comptime {
5608 \\ var a: i64 = undefined;5843 \\ var a: i64 = undefined;
5609 \\ _ = a -% a;5844 \\ _ = a -% a;
...@@ -5612,7 +5847,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5612,7 +5847,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5612 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5847 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5613 });5848 });
56145849
5615 cases.add("sub wrap assign on undefined value",5850 ctx.objErrStage1("sub wrap assign on undefined value",
5616 \\comptime {5851 \\comptime {
5617 \\ var a: i64 = undefined;5852 \\ var a: i64 = undefined;
5618 \\ a -%= a;5853 \\ a -%= a;
...@@ -5621,7 +5856,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5621,7 +5856,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5621 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5856 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5622 });5857 });
56235858
5624 cases.add("mult on undefined value",5859 ctx.objErrStage1("mult on undefined value",
5625 \\comptime {5860 \\comptime {
5626 \\ var a: i64 = undefined;5861 \\ var a: i64 = undefined;
5627 \\ _ = a * a;5862 \\ _ = a * a;
...@@ -5630,7 +5865,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5630,7 +5865,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5630 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5865 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5631 });5866 });
56325867
5633 cases.add("mult assign on undefined value",5868 ctx.objErrStage1("mult assign on undefined value",
5634 \\comptime {5869 \\comptime {
5635 \\ var a: i64 = undefined;5870 \\ var a: i64 = undefined;
5636 \\ a *= a;5871 \\ a *= a;
...@@ -5639,7 +5874,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5639,7 +5874,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5639 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5874 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5640 });5875 });
56415876
5642 cases.add("mult wrap on undefined value",5877 ctx.objErrStage1("mult wrap on undefined value",
5643 \\comptime {5878 \\comptime {
5644 \\ var a: i64 = undefined;5879 \\ var a: i64 = undefined;
5645 \\ _ = a *% a;5880 \\ _ = a *% a;
...@@ -5648,7 +5883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5648,7 +5883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5648 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5883 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5649 });5884 });
56505885
5651 cases.add("mult wrap assign on undefined value",5886 ctx.objErrStage1("mult wrap assign on undefined value",
5652 \\comptime {5887 \\comptime {
5653 \\ var a: i64 = undefined;5888 \\ var a: i64 = undefined;
5654 \\ a *%= a;5889 \\ a *%= a;
...@@ -5657,7 +5892,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5657,7 +5892,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5657 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5892 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5658 });5893 });
56595894
5660 cases.add("shift left on undefined value",5895 ctx.objErrStage1("shift left on undefined value",
5661 \\comptime {5896 \\comptime {
5662 \\ var a: i64 = undefined;5897 \\ var a: i64 = undefined;
5663 \\ _ = a << 2;5898 \\ _ = a << 2;
...@@ -5666,7 +5901,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5666,7 +5901,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5666 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5901 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5667 });5902 });
56685903
5669 cases.add("shift left assign on undefined value",5904 ctx.objErrStage1("shift left assign on undefined value",
5670 \\comptime {5905 \\comptime {
5671 \\ var a: i64 = undefined;5906 \\ var a: i64 = undefined;
5672 \\ a <<= 2;5907 \\ a <<= 2;
...@@ -5675,7 +5910,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5675,7 +5910,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5675 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5910 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5676 });5911 });
56775912
5678 cases.add("shift right on undefined value",5913 ctx.objErrStage1("shift right on undefined value",
5679 \\comptime {5914 \\comptime {
5680 \\ var a: i64 = undefined;5915 \\ var a: i64 = undefined;
5681 \\ _ = a >> 2;5916 \\ _ = a >> 2;
...@@ -5684,7 +5919,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5684,7 +5919,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5684 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5919 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5685 });5920 });
56865921
5687 cases.add("shift left assign on undefined value",5922 ctx.objErrStage1("shift left assign on undefined value",
5688 \\comptime {5923 \\comptime {
5689 \\ var a: i64 = undefined;5924 \\ var a: i64 = undefined;
5690 \\ a >>= 2;5925 \\ a >>= 2;
...@@ -5693,7 +5928,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5693,7 +5928,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5693 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5928 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5694 });5929 });
56955930
5696 cases.add("bin and on undefined value",5931 ctx.objErrStage1("bin and on undefined value",
5697 \\comptime {5932 \\comptime {
5698 \\ var a: i64 = undefined;5933 \\ var a: i64 = undefined;
5699 \\ _ = a & a;5934 \\ _ = a & a;
...@@ -5702,7 +5937,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5702,7 +5937,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5702 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5937 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5703 });5938 });
57045939
5705 cases.add("bin and assign on undefined value",5940 ctx.objErrStage1("bin and assign on undefined value",
5706 \\comptime {5941 \\comptime {
5707 \\ var a: i64 = undefined;5942 \\ var a: i64 = undefined;
5708 \\ a &= a;5943 \\ a &= a;
...@@ -5711,7 +5946,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5711,7 +5946,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5711 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5946 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5712 });5947 });
57135948
5714 cases.add("bin or on undefined value",5949 ctx.objErrStage1("bin or on undefined value",
5715 \\comptime {5950 \\comptime {
5716 \\ var a: i64 = undefined;5951 \\ var a: i64 = undefined;
5717 \\ _ = a | a;5952 \\ _ = a | a;
...@@ -5720,7 +5955,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5720,7 +5955,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5720 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5955 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5721 });5956 });
57225957
5723 cases.add("bin or assign on undefined value",5958 ctx.objErrStage1("bin or assign on undefined value",
5724 \\comptime {5959 \\comptime {
5725 \\ var a: i64 = undefined;5960 \\ var a: i64 = undefined;
5726 \\ a |= a;5961 \\ a |= a;
...@@ -5729,7 +5964,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5729,7 +5964,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5729 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5964 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5730 });5965 });
57315966
5732 cases.add("bin xor on undefined value",5967 ctx.objErrStage1("bin xor on undefined value",
5733 \\comptime {5968 \\comptime {
5734 \\ var a: i64 = undefined;5969 \\ var a: i64 = undefined;
5735 \\ _ = a ^ a;5970 \\ _ = a ^ a;
...@@ -5738,7 +5973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5738,7 +5973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5738 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",5973 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5739 });5974 });
57405975
5741 cases.add("bin xor assign on undefined value",5976 ctx.objErrStage1("bin xor assign on undefined value",
5742 \\comptime {5977 \\comptime {
5743 \\ var a: i64 = undefined;5978 \\ var a: i64 = undefined;
5744 \\ a ^= a;5979 \\ a ^= a;
...@@ -5747,7 +5982,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5747,7 +5982,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5747 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",5982 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
5748 });5983 });
57495984
5750 cases.add("comparison operators with undefined value",5985 ctx.objErrStage1("comparison operators with undefined value",
5751 \\// operator ==5986 \\// operator ==
5752 \\comptime {5987 \\comptime {
5753 \\ var a: i64 = undefined;5988 \\ var a: i64 = undefined;
...@@ -5793,7 +6028,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5793,7 +6028,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5793 "tmp.zig:35:11: error: use of undefined value here causes undefined behavior",6028 "tmp.zig:35:11: error: use of undefined value here causes undefined behavior",
5794 });6029 });
57956030
5796 cases.add("and on undefined value",6031 ctx.objErrStage1("and on undefined value",
5797 \\comptime {6032 \\comptime {
5798 \\ var a: bool = undefined;6033 \\ var a: bool = undefined;
5799 \\ _ = a and a;6034 \\ _ = a and a;
...@@ -5802,7 +6037,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5802,7 +6037,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5802 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",6037 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5803 });6038 });
58046039
5805 cases.add("or on undefined value",6040 ctx.objErrStage1("or on undefined value",
5806 \\comptime {6041 \\comptime {
5807 \\ var a: bool = undefined;6042 \\ var a: bool = undefined;
5808 \\ _ = a or a;6043 \\ _ = a or a;
...@@ -5811,7 +6046,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5811,7 +6046,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5811 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",6046 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
5812 });6047 });
58136048
5814 cases.add("negate on undefined value",6049 ctx.objErrStage1("negate on undefined value",
5815 \\comptime {6050 \\comptime {
5816 \\ var a: i64 = undefined;6051 \\ var a: i64 = undefined;
5817 \\ _ = -a;6052 \\ _ = -a;
...@@ -5820,7 +6055,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5820,7 +6055,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5820 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",6055 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",
5821 });6056 });
58226057
5823 cases.add("negate wrap on undefined value",6058 ctx.objErrStage1("negate wrap on undefined value",
5824 \\comptime {6059 \\comptime {
5825 \\ var a: i64 = undefined;6060 \\ var a: i64 = undefined;
5826 \\ _ = -%a;6061 \\ _ = -%a;
...@@ -5829,7 +6064,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5829,7 +6064,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5829 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",6064 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",
5830 });6065 });
58316066
5832 cases.add("bin not on undefined value",6067 ctx.objErrStage1("bin not on undefined value",
5833 \\comptime {6068 \\comptime {
5834 \\ var a: i64 = undefined;6069 \\ var a: i64 = undefined;
5835 \\ _ = ~a;6070 \\ _ = ~a;
...@@ -5838,7 +6073,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5838,7 +6073,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5838 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",6073 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",
5839 });6074 });
58406075
5841 cases.add("bool not on undefined value",6076 ctx.objErrStage1("bool not on undefined value",
5842 \\comptime {6077 \\comptime {
5843 \\ var a: bool = undefined;6078 \\ var a: bool = undefined;
5844 \\ _ = !a;6079 \\ _ = !a;
...@@ -5847,7 +6082,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5847,7 +6082,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5847 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",6082 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",
5848 });6083 });
58496084
5850 cases.add("orelse on undefined value",6085 ctx.objErrStage1("orelse on undefined value",
5851 \\comptime {6086 \\comptime {
5852 \\ var a: ?bool = undefined;6087 \\ var a: ?bool = undefined;
5853 \\ _ = a orelse false;6088 \\ _ = a orelse false;
...@@ -5856,16 +6091,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5856,16 +6091,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5856 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",6091 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",
5857 });6092 });
58586093
5859 cases.add("catch on undefined value",6094 ctx.objErrStage1("catch on undefined value",
5860 \\comptime {6095 \\comptime {
5861 \\ var a: anyerror!bool = undefined;6096 \\ var a: anyerror!bool = undefined;
5862 \\ _ = a catch |err| false;6097 \\ _ = a catch false;
5863 \\}6098 \\}
5864 , &[_][]const u8{6099 , &[_][]const u8{
5865 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",6100 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",
5866 });6101 });
58676102
5868 cases.add("deref on undefined value",6103 ctx.objErrStage1("deref on undefined value",
5869 \\comptime {6104 \\comptime {
5870 \\ var a: *u8 = undefined;6105 \\ var a: *u8 = undefined;
5871 \\ _ = a.*;6106 \\ _ = a.*;
...@@ -5874,7 +6109,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5874,7 +6109,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5874 "tmp.zig:3:9: error: attempt to dereference undefined value",6109 "tmp.zig:3:9: error: attempt to dereference undefined value",
5875 });6110 });
58766111
5877 cases.add("endless loop in function evaluation",6112 ctx.objErrStage1("endless loop in function evaluation",
5878 \\const seventh_fib_number = fibbonaci(7);6113 \\const seventh_fib_number = fibbonaci(7);
5879 \\fn fibbonaci(x: i32) i32 {6114 \\fn fibbonaci(x: i32) i32 {
5880 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);6115 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
...@@ -5887,16 +6122,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5887,16 +6122,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5887 "tmp.zig:6:50: note: referenced here",6122 "tmp.zig:6:50: note: referenced here",
5888 });6123 });
58896124
5890 cases.add("@embedFile with bogus file",6125 ctx.objErrStage1("@embedFile with bogus file",
5891 \\const resource = @embedFile("bogus.txt",);6126 \\const resource = @embedFile("bogus.txt",);
5892 \\6127 \\
5893 \\export fn entry() usize { return @sizeOf(@TypeOf(resource)); }6128 \\export fn entry() usize { return @sizeOf(@TypeOf(resource)); }
5894 , &[_][]const u8{6129 , &[_][]const u8{
5895 "tmp.zig:1:29: error: unable to find '",6130 "tmp.zig:1:29: error: unable to find '",
5896 "bogus.txt'",
5897 });6131 });
58986132
5899 cases.add("non-const expression in struct literal outside function",6133 ctx.objErrStage1("non-const expression in struct literal outside function",
5900 \\const Foo = struct {6134 \\const Foo = struct {
5901 \\ x: i32,6135 \\ x: i32,
5902 \\};6136 \\};
...@@ -5908,7 +6142,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5908,7 +6142,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5908 "tmp.zig:4:21: error: unable to evaluate constant expression",6142 "tmp.zig:4:21: error: unable to evaluate constant expression",
5909 });6143 });
59106144
5911 cases.add("non-const expression function call with struct return value outside function",6145 ctx.objErrStage1("non-const expression function call with struct return value outside function",
5912 \\const Foo = struct {6146 \\const Foo = struct {
5913 \\ x: i32,6147 \\ x: i32,
5914 \\};6148 \\};
...@@ -5925,7 +6159,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5925,7 +6159,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5925 "tmp.zig:4:17: note: referenced here",6159 "tmp.zig:4:17: note: referenced here",
5926 });6160 });
59276161
5928 cases.add("undeclared identifier error should mark fn as impure",6162 ctx.objErrStage1("undeclared identifier error should mark fn as impure",
5929 \\export fn foo() void {6163 \\export fn foo() void {
5930 \\ test_a_thing();6164 \\ test_a_thing();
5931 \\}6165 \\}
...@@ -5936,7 +6170,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5936,7 +6170,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5936 "tmp.zig:5:5: error: use of undeclared identifier 'bad_fn_call'",6170 "tmp.zig:5:5: error: use of undeclared identifier 'bad_fn_call'",
5937 });6171 });
59386172
5939 cases.add("illegal comparison of types",6173 ctx.objErrStage1("illegal comparison of types",
5940 \\fn bad_eql_1(a: []u8, b: []u8) bool {6174 \\fn bad_eql_1(a: []u8, b: []u8) bool {
5941 \\ return a == b;6175 \\ return a == b;
5942 \\}6176 \\}
...@@ -5955,13 +6189,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5955,13 +6189,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5955 "tmp.zig:9:16: error: operator not allowed for type 'EnumWithData'",6189 "tmp.zig:9:16: error: operator not allowed for type 'EnumWithData'",
5956 });6190 });
59576191
5958 cases.add("non-const switch number literal",6192 ctx.objErrStage1("non-const switch number literal",
5959 \\export fn foo() void {6193 \\export fn foo() void {
5960 \\ const x = switch (bar()) {6194 \\ const x = switch (bar()) {
5961 \\ 1, 2 => 1,6195 \\ 1, 2 => 1,
5962 \\ 3, 4 => 2,6196 \\ 3, 4 => 2,
5963 \\ else => 3,6197 \\ else => 3,
5964 \\ };6198 \\ };
6199 \\ _ = x;
5965 \\}6200 \\}
5966 \\fn bar() i32 {6201 \\fn bar() i32 {
5967 \\ return 2;6202 \\ return 2;
...@@ -5970,7 +6205,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5970,7 +6205,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5970 "tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'",6205 "tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'",
5971 });6206 });
59726207
5973 cases.add("atomic orderings of cmpxchg - failure stricter than success",6208 ctx.objErrStage1("atomic orderings of cmpxchg - failure stricter than success",
5974 \\const AtomicOrder = @import("std").builtin.AtomicOrder;6209 \\const AtomicOrder = @import("std").builtin.AtomicOrder;
5975 \\export fn f() void {6210 \\export fn f() void {
5976 \\ var x: i32 = 1234;6211 \\ var x: i32 = 1234;
...@@ -5980,7 +6215,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5980,7 +6215,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5980 "tmp.zig:4:81: error: failure atomic ordering must be no stricter than success",6215 "tmp.zig:4:81: error: failure atomic ordering must be no stricter than success",
5981 });6216 });
59826217
5983 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",6218 ctx.objErrStage1("atomic orderings of cmpxchg - success Monotonic or stricter",
5984 \\const AtomicOrder = @import("std").builtin.AtomicOrder;6219 \\const AtomicOrder = @import("std").builtin.AtomicOrder;
5985 \\export fn f() void {6220 \\export fn f() void {
5986 \\ var x: i32 = 1234;6221 \\ var x: i32 = 1234;
...@@ -5990,7 +6225,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5990,7 +6225,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5990 "tmp.zig:4:58: error: success atomic ordering must be Monotonic or stricter",6225 "tmp.zig:4:58: error: success atomic ordering must be Monotonic or stricter",
5991 });6226 });
59926227
5993 cases.add("negation overflow in function evaluation",6228 ctx.objErrStage1("negation overflow in function evaluation",
5994 \\const y = neg(-128);6229 \\const y = neg(-128);
5995 \\fn neg(x: i8) i8 {6230 \\fn neg(x: i8) i8 {
5996 \\ return -x;6231 \\ return -x;
...@@ -6002,7 +6237,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6002,7 +6237,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6002 "tmp.zig:1:14: note: referenced here",6237 "tmp.zig:1:14: note: referenced here",
6003 });6238 });
60046239
6005 cases.add("add overflow in function evaluation",6240 ctx.objErrStage1("add overflow in function evaluation",
6006 \\const y = add(65530, 10);6241 \\const y = add(65530, 10);
6007 \\fn add(a: u16, b: u16) u16 {6242 \\fn add(a: u16, b: u16) u16 {
6008 \\ return a + b;6243 \\ return a + b;
...@@ -6014,7 +6249,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6014,7 +6249,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6014 "tmp.zig:1:14: note: referenced here",6249 "tmp.zig:1:14: note: referenced here",
6015 });6250 });
60166251
6017 cases.add("sub overflow in function evaluation",6252 ctx.objErrStage1("sub overflow in function evaluation",
6018 \\const y = sub(10, 20);6253 \\const y = sub(10, 20);
6019 \\fn sub(a: u16, b: u16) u16 {6254 \\fn sub(a: u16, b: u16) u16 {
6020 \\ return a - b;6255 \\ return a - b;
...@@ -6026,7 +6261,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6026,7 +6261,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6026 "tmp.zig:1:14: note: referenced here",6261 "tmp.zig:1:14: note: referenced here",
6027 });6262 });
60286263
6029 cases.add("mul overflow in function evaluation",6264 ctx.objErrStage1("mul overflow in function evaluation",
6030 \\const y = mul(300, 6000);6265 \\const y = mul(300, 6000);
6031 \\fn mul(a: u16, b: u16) u16 {6266 \\fn mul(a: u16, b: u16) u16 {
6032 \\ return a * b;6267 \\ return a * b;
...@@ -6038,7 +6273,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6038,7 +6273,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6038 "tmp.zig:1:14: note: referenced here",6273 "tmp.zig:1:14: note: referenced here",
6039 });6274 });
60406275
6041 cases.add("truncate sign mismatch",6276 ctx.objErrStage1("truncate sign mismatch",
6042 \\export fn entry1() i8 {6277 \\export fn entry1() i8 {
6043 \\ var x: u32 = 10;6278 \\ var x: u32 = 10;
6044 \\ return @truncate(i8, x);6279 \\ return @truncate(i8, x);
...@@ -6062,7 +6297,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6062,7 +6297,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6062 "tmp.zig:15:26: error: expected unsigned integer type, found 'i32'",6297 "tmp.zig:15:26: error: expected unsigned integer type, found 'i32'",
6063 });6298 });
60646299
6065 cases.add("try in function with non error return type",6300 ctx.objErrStage1("try in function with non error return type",
6066 \\export fn f() void {6301 \\export fn f() void {
6067 \\ try something();6302 \\ try something();
6068 \\}6303 \\}
...@@ -6071,7 +6306,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6071,7 +6306,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6071 "tmp.zig:2:5: error: expected type 'void', found 'anyerror'",6306 "tmp.zig:2:5: error: expected type 'void', found 'anyerror'",
6072 });6307 });
60736308
6074 cases.add("invalid pointer for var type",6309 ctx.objErrStage1("invalid pointer for var type",
6075 \\extern fn ext() usize;6310 \\extern fn ext() usize;
6076 \\var bytes: [ext()]u8 = undefined;6311 \\var bytes: [ext()]u8 = undefined;
6077 \\export fn f() void {6312 \\export fn f() void {
...@@ -6083,7 +6318,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6083,7 +6318,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6083 "tmp.zig:2:13: error: unable to evaluate constant expression",6318 "tmp.zig:2:13: error: unable to evaluate constant expression",
6084 });6319 });
60856320
6086 cases.add("export function with comptime parameter",6321 ctx.objErrStage1("export function with comptime parameter",
6087 \\export fn foo(comptime x: i32, y: i32) i32{6322 \\export fn foo(comptime x: i32, y: i32) i32{
6088 \\ return x + y;6323 \\ return x + y;
6089 \\}6324 \\}
...@@ -6091,7 +6326,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6091,7 +6326,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6091 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",6326 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
6092 });6327 });
60936328
6094 cases.add("extern function with comptime parameter",6329 ctx.objErrStage1("extern function with comptime parameter",
6095 \\extern fn foo(comptime x: i32, y: i32) i32;6330 \\extern fn foo(comptime x: i32, y: i32) i32;
6096 \\fn f() i32 {6331 \\fn f() i32 {
6097 \\ return foo(1, 2);6332 \\ return foo(1, 2);
...@@ -6101,7 +6336,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6101,7 +6336,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6101 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",6336 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
6102 });6337 });
61036338
6104 cases.add("non-pure function returns type",6339 ctx.objErrStage1("non-pure function returns type",
6105 \\var a: u32 = 0;6340 \\var a: u32 = 0;
6106 \\pub fn List(comptime T: type) type {6341 \\pub fn List(comptime T: type) type {
6107 \\ a += 1;6342 \\ a += 1;
...@@ -6125,7 +6360,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6125,7 +6360,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6125 "tmp.zig:16:19: note: referenced here",6360 "tmp.zig:16:19: note: referenced here",
6126 });6361 });
61276362
6128 cases.add("bogus method call on slice",6363 ctx.objErrStage1("bogus method call on slice",
6129 \\var self = "aoeu";6364 \\var self = "aoeu";
6130 \\fn f(m: []const u8) void {6365 \\fn f(m: []const u8) void {
6131 \\ m.copy(u8, self[0..], m);6366 \\ m.copy(u8, self[0..], m);
...@@ -6135,9 +6370,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6135,9 +6370,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6135 "tmp.zig:3:6: error: no member named 'copy' in '[]const u8'",6370 "tmp.zig:3:6: error: no member named 'copy' in '[]const u8'",
6136 });6371 });
61376372
6138 cases.add("wrong number of arguments for method fn call",6373 ctx.objErrStage1("wrong number of arguments for method fn call",
6139 \\const Foo = struct {6374 \\const Foo = struct {
6140 \\ fn method(self: *const Foo, a: i32) void {}6375 \\ fn method(self: *const Foo, a: i32) void {_ = self; _ = a;}
6141 \\};6376 \\};
6142 \\fn f(foo: *const Foo) void {6377 \\fn f(foo: *const Foo) void {
6143 \\6378 \\
...@@ -6148,7 +6383,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6148,7 +6383,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6148 "tmp.zig:6:15: error: expected 2 argument(s), found 3",6383 "tmp.zig:6:15: error: expected 2 argument(s), found 3",
6149 });6384 });
61506385
6151 cases.add("assign through constant pointer",6386 ctx.objErrStage1("assign through constant pointer",
6152 \\export fn f() void {6387 \\export fn f() void {
6153 \\ var cstr = "Hat";6388 \\ var cstr = "Hat";
6154 \\ cstr[0] = 'W';6389 \\ cstr[0] = 'W';
...@@ -6157,7 +6392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6157,7 +6392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6157 "tmp.zig:3:13: error: cannot assign to constant",6392 "tmp.zig:3:13: error: cannot assign to constant",
6158 });6393 });
61596394
6160 cases.add("assign through constant slice",6395 ctx.objErrStage1("assign through constant slice",
6161 \\export fn f() void {6396 \\export fn f() void {
6162 \\ var cstr: []const u8 = "Hat";6397 \\ var cstr: []const u8 = "Hat";
6163 \\ cstr[0] = 'W';6398 \\ cstr[0] = 'W';
...@@ -6166,13 +6401,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6166,13 +6401,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6166 "tmp.zig:3:13: error: cannot assign to constant",6401 "tmp.zig:3:13: error: cannot assign to constant",
6167 });6402 });
61686403
6169 cases.add("main function with bogus args type",6404 ctx.objErrStage1("main function with bogus args type",
6170 \\pub fn main(args: [][]bogus) !void {}6405 \\pub fn main(args: [][]bogus) !void {_ = args;}
6171 , &[_][]const u8{6406 , &[_][]const u8{
6172 "tmp.zig:1:23: error: use of undeclared identifier 'bogus'",6407 "tmp.zig:1:23: error: use of undeclared identifier 'bogus'",
6173 });6408 });
61746409
6175 cases.add("misspelled type with pointer only reference",6410 ctx.objErrStage1("misspelled type with pointer only reference",
6176 \\const JasonHM = u8;6411 \\const JasonHM = u8;
6177 \\const JasonList = *JsonNode;6412 \\const JasonList = *JsonNode;
6178 \\6413 \\
...@@ -6200,6 +6435,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6200,6 +6435,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6200 \\ var jll: JasonList = undefined;6435 \\ var jll: JasonList = undefined;
6201 \\ jll.init(1234);6436 \\ jll.init(1234);
6202 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };6437 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
6438 \\ _ = jd;
6203 \\}6439 \\}
6204 \\6440 \\
6205 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }6441 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
...@@ -6207,7 +6443,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6207,7 +6443,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6207 "tmp.zig:5:16: error: use of undeclared identifier 'JsonList'",6443 "tmp.zig:5:16: error: use of undeclared identifier 'JsonList'",
6208 });6444 });
62096445
6210 cases.add("method call with first arg type primitive",6446 ctx.objErrStage1("method call with first arg type primitive",
6211 \\const Foo = struct {6447 \\const Foo = struct {
6212 \\ x: i32,6448 \\ x: i32,
6213 \\6449 \\
...@@ -6227,7 +6463,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6227,7 +6463,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6227 "tmp.zig:14:5: error: expected type 'i32', found 'Foo'",6463 "tmp.zig:14:5: error: expected type 'i32', found 'Foo'",
6228 });6464 });
62296465
6230 cases.add("method call with first arg type wrong container",6466 ctx.objErrStage1("method call with first arg type wrong container",
6231 \\pub const List = struct {6467 \\pub const List = struct {
6232 \\ len: usize,6468 \\ len: usize,
6233 \\ allocator: *Allocator,6469 \\ allocator: *Allocator,
...@@ -6256,7 +6492,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6256,7 +6492,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6256 "tmp.zig:23:5: error: expected type '*Allocator', found '*List'",6492 "tmp.zig:23:5: error: expected type '*Allocator', found '*List'",
6257 });6493 });
62586494
6259 cases.add("binary not on number literal",6495 ctx.objErrStage1("binary not on number literal",
6260 \\const TINY_QUANTUM_SHIFT = 4;6496 \\const TINY_QUANTUM_SHIFT = 4;
6261 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;6497 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
6262 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);6498 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
...@@ -6266,8 +6502,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6266,8 +6502,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6266 "tmp.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'",6502 "tmp.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'",
6267 });6503 });
62686504
6269 cases.addCase(x: {6505 {
6270 const tc = cases.create("multiple files with private function error",6506 const case = ctx.obj("multiple files with private function error", .{});
6507 case.backend = .stage1;
6508
6509 case.addSourceFile("foo.zig",
6510 \\fn privateFunction() void { }
6511 );
6512
6513 case.addError(
6271 \\const foo = @import("foo.zig",);6514 \\const foo = @import("foo.zig",);
6272 \\6515 \\
6273 \\export fn callPrivFunction() void {6516 \\export fn callPrivFunction() void {
...@@ -6277,16 +6520,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6277,16 +6520,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6277 "tmp.zig:4:8: error: 'privateFunction' is private",6520 "tmp.zig:4:8: error: 'privateFunction' is private",
6278 "foo.zig:1:1: note: declared here",6521 "foo.zig:1:1: note: declared here",
6279 });6522 });
6523 }
62806524
6281 tc.addSourceFile("foo.zig",6525 {
6282 \\fn privateFunction() void { }6526 const case = ctx.obj("multiple files with private member instance function (canonical invocation) error", .{});
6283 );6527 case.backend = .stage1;
62846528
6285 break :x tc;6529 case.addSourceFile("foo.zig",
6286 });6530 \\pub const Foo = struct {
6531 \\ fn privateFunction(self: *Foo) void { _ = self; }
6532 \\};
6533 );
62876534
6288 cases.addCase(x: {6535 case.addError(
6289 const tc = cases.create("multiple files with private member instance function (canonical invocation) error",
6290 \\const Foo = @import("foo.zig",).Foo;6536 \\const Foo = @import("foo.zig",).Foo;
6291 \\6537 \\
6292 \\export fn callPrivFunction() void {6538 \\export fn callPrivFunction() void {
...@@ -6297,18 +6543,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6297,18 +6543,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6297 "tmp.zig:5:8: error: 'privateFunction' is private",6543 "tmp.zig:5:8: error: 'privateFunction' is private",
6298 "foo.zig:2:5: note: declared here",6544 "foo.zig:2:5: note: declared here",
6299 });6545 });
6546 }
6547
6548 {
6549 const case = ctx.obj("multiple files with private member instance function error", .{});
6550 case.backend = .stage1;
63006551
6301 tc.addSourceFile("foo.zig",6552 case.addSourceFile("foo.zig",
6302 \\pub const Foo = struct {6553 \\pub const Foo = struct {
6303 \\ fn privateFunction(self: *Foo) void { }6554 \\ fn privateFunction(self: *Foo) void { _ = self; }
6304 \\};6555 \\};
6305 );6556 );
63066557
6307 break :x tc;6558 case.addError(
6308 });
6309
6310 cases.addCase(x: {
6311 const tc = cases.create("multiple files with private member instance function error",
6312 \\const Foo = @import("foo.zig",).Foo;6559 \\const Foo = @import("foo.zig",).Foo;
6313 \\6560 \\
6314 \\export fn callPrivFunction() void {6561 \\export fn callPrivFunction() void {
...@@ -6319,17 +6566,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6319,17 +6566,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6319 "tmp.zig:5:8: error: 'privateFunction' is private",6566 "tmp.zig:5:8: error: 'privateFunction' is private",
6320 "foo.zig:2:5: note: declared here",6567 "foo.zig:2:5: note: declared here",
6321 });6568 });
6569 }
63226570
6323 tc.addSourceFile("foo.zig",6571 ctx.objErrStage1("container init with non-type",
6324 \\pub const Foo = struct {
6325 \\ fn privateFunction(self: *Foo) void { }
6326 \\};
6327 );
6328
6329 break :x tc;
6330 });
6331
6332 cases.add("container init with non-type",
6333 \\const zero: i32 = 0;6572 \\const zero: i32 = 0;
6334 \\const a = zero{1};6573 \\const a = zero{1};
6335 \\6574 \\
...@@ -6338,7 +6577,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6338,7 +6577,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6338 "tmp.zig:2:11: error: expected type 'type', found 'i32'",6577 "tmp.zig:2:11: error: expected type 'type', found 'i32'",
6339 });6578 });
63406579
6341 cases.add("assign to constant field",6580 ctx.objErrStage1("assign to constant field",
6342 \\const Foo = struct {6581 \\const Foo = struct {
6343 \\ field: i32,6582 \\ field: i32,
6344 \\};6583 \\};
...@@ -6350,7 +6589,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6350,7 +6589,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6350 "tmp.zig:6:15: error: cannot assign to constant",6589 "tmp.zig:6:15: error: cannot assign to constant",
6351 });6590 });
63526591
6353 cases.add("return from defer expression",6592 ctx.objErrStage1("return from defer expression",
6354 \\pub fn testTrickyDefer() !void {6593 \\pub fn testTrickyDefer() !void {
6355 \\ defer canFail() catch {};6594 \\ defer canFail() catch {};
6356 \\6595 \\
...@@ -6367,32 +6606,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6367,32 +6606,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6367 \\6606 \\
6368 \\export fn entry() usize { return @sizeOf(@TypeOf(testTrickyDefer)); }6607 \\export fn entry() usize { return @sizeOf(@TypeOf(testTrickyDefer)); }
6369 , &[_][]const u8{6608 , &[_][]const u8{
6370 "tmp.zig:4:11: error: cannot return from defer expression",6609 "tmp.zig:4:11: error: 'try' not allowed inside defer expression",
6371 });6610 });
63726611
6373 cases.add("assign too big number to u16",6612 ctx.objErrStage1("assign too big number to u16",
6374 \\export fn foo() void {6613 \\export fn foo() void {
6375 \\ var vga_mem: u16 = 0xB8000;6614 \\ var vga_mem: u16 = 0xB8000;
6615 \\ _ = vga_mem;
6376 \\}6616 \\}
6377 , &[_][]const u8{6617 , &[_][]const u8{
6378 "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'",6618 "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'",
6379 });6619 });
63806620
6381 cases.add("global variable alignment non power of 2",6621 ctx.objErrStage1("global variable alignment non power of 2",
6382 \\const some_data: [100]u8 align(3) = undefined;6622 \\const some_data: [100]u8 align(3) = undefined;
6383 \\export fn entry() usize { return @sizeOf(@TypeOf(some_data)); }6623 \\export fn entry() usize { return @sizeOf(@TypeOf(some_data)); }
6384 , &[_][]const u8{6624 , &[_][]const u8{
6385 "tmp.zig:1:32: error: alignment value 3 is not a power of 2",6625 "tmp.zig:1:32: error: alignment value 3 is not a power of 2",
6386 });6626 });
63876627
6388 cases.add("function alignment non power of 2",6628 ctx.objErrStage1("function alignment non power of 2",
6389 \\extern fn foo() align(3) void;6629 \\extern fn foo() align(3) void;
6390 \\export fn entry() void { return foo(); }6630 \\export fn entry() void { return foo(); }
6391 , &[_][]const u8{6631 , &[_][]const u8{
6392 "tmp.zig:1:23: error: alignment value 3 is not a power of 2",6632 "tmp.zig:1:23: error: alignment value 3 is not a power of 2",
6393 });6633 });
63946634
6395 cases.add("compile log",6635 ctx.objErrStage1("compile log",
6396 \\export fn foo() void {6636 \\export fn foo() void {
6397 \\ comptime bar(12, "hi",);6637 \\ comptime bar(12, "hi",);
6398 \\}6638 \\}
...@@ -6407,7 +6647,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6407,7 +6647,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6407 "tmp.zig:7:5: error: found compile log statement",6647 "tmp.zig:7:5: error: found compile log statement",
6408 });6648 });
64096649
6410 cases.add("casting bit offset pointer to regular pointer",6650 ctx.objErrStage1("casting bit offset pointer to regular pointer",
6411 \\const BitField = packed struct {6651 \\const BitField = packed struct {
6412 \\ a: u3,6652 \\ a: u3,
6413 \\ b: u3,6653 \\ b: u3,
...@@ -6427,7 +6667,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6427,7 +6667,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6427 "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",6667 "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",
6428 });6668 });
64296669
6430 cases.add("referring to a struct that is invalid",6670 ctx.objErrStage1("referring to a struct that is invalid",
6431 \\const UsbDeviceRequest = struct {6671 \\const UsbDeviceRequest = struct {
6432 \\ Type: u8,6672 \\ Type: u8,
6433 \\};6673 \\};
...@@ -6444,7 +6684,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6444,7 +6684,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6444 "tmp.zig:6:20: note: referenced here",6684 "tmp.zig:6:20: note: referenced here",
6445 });6685 });
64466686
6447 cases.add("control flow uses comptime var at runtime",6687 ctx.objErrStage1("control flow uses comptime var at runtime",
6448 \\export fn foo() void {6688 \\export fn foo() void {
6449 \\ comptime var i = 0;6689 \\ comptime var i = 0;
6450 \\ while (i < 5) : (i += 1) {6690 \\ while (i < 5) : (i += 1) {
...@@ -6458,7 +6698,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6458,7 +6698,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6458 "tmp.zig:3:24: note: compile-time variable assigned here",6698 "tmp.zig:3:24: note: compile-time variable assigned here",
6459 });6699 });
64606700
6461 cases.add("ignored return value",6701 ctx.objErrStage1("ignored return value",
6462 \\export fn foo() void {6702 \\export fn foo() void {
6463 \\ bar();6703 \\ bar();
6464 \\}6704 \\}
...@@ -6467,7 +6707,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6467,7 +6707,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6467 "tmp.zig:2:8: error: expression value is ignored",6707 "tmp.zig:2:8: error: expression value is ignored",
6468 });6708 });
64696709
6470 cases.add("ignored assert-err-ok return value",6710 ctx.objErrStage1("ignored assert-err-ok return value",
6471 \\export fn foo() void {6711 \\export fn foo() void {
6472 \\ bar() catch unreachable;6712 \\ bar() catch unreachable;
6473 \\}6713 \\}
...@@ -6476,7 +6716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6476,7 +6716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6476 "tmp.zig:2:11: error: expression value is ignored",6716 "tmp.zig:2:11: error: expression value is ignored",
6477 });6717 });
64786718
6479 cases.add("ignored statement value",6719 ctx.objErrStage1("ignored statement value",
6480 \\export fn foo() void {6720 \\export fn foo() void {
6481 \\ 1;6721 \\ 1;
6482 \\}6722 \\}
...@@ -6484,7 +6724,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6484,7 +6724,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6484 "tmp.zig:2:5: error: expression value is ignored",6724 "tmp.zig:2:5: error: expression value is ignored",
6485 });6725 });
64866726
6487 cases.add("ignored comptime statement value",6727 ctx.objErrStage1("ignored comptime statement value",
6488 \\export fn foo() void {6728 \\export fn foo() void {
6489 \\ comptime {1;}6729 \\ comptime {1;}
6490 \\}6730 \\}
...@@ -6492,7 +6732,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6492,7 +6732,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6492 "tmp.zig:2:15: error: expression value is ignored",6732 "tmp.zig:2:15: error: expression value is ignored",
6493 });6733 });
64946734
6495 cases.add("ignored comptime value",6735 ctx.objErrStage1("ignored comptime value",
6496 \\export fn foo() void {6736 \\export fn foo() void {
6497 \\ comptime 1;6737 \\ comptime 1;
6498 \\}6738 \\}
...@@ -6500,7 +6740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6500,7 +6740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6500 "tmp.zig:2:5: error: expression value is ignored",6740 "tmp.zig:2:5: error: expression value is ignored",
6501 });6741 });
65026742
6503 cases.add("ignored defered statement value",6743 ctx.objErrStage1("ignored defered statement value",
6504 \\export fn foo() void {6744 \\export fn foo() void {
6505 \\ defer {1;}6745 \\ defer {1;}
6506 \\}6746 \\}
...@@ -6508,7 +6748,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6508,7 +6748,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6508 "tmp.zig:2:12: error: expression value is ignored",6748 "tmp.zig:2:12: error: expression value is ignored",
6509 });6749 });
65106750
6511 cases.add("ignored defered function call",6751 ctx.objErrStage1("ignored defered function call",
6512 \\export fn foo() void {6752 \\export fn foo() void {
6513 \\ defer bar();6753 \\ defer bar();
6514 \\}6754 \\}
...@@ -6517,7 +6757,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6517,7 +6757,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6517 "tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if`",6757 "tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if`",
6518 });6758 });
65196759
6520 cases.add("dereference an array",6760 ctx.objErrStage1("dereference an array",
6521 \\var s_buffer: [10]u8 = undefined;6761 \\var s_buffer: [10]u8 = undefined;
6522 \\pub fn pass(in: []u8) []u8 {6762 \\pub fn pass(in: []u8) []u8 {
6523 \\ var out = &s_buffer;6763 \\ var out = &s_buffer;
...@@ -6530,13 +6770,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6530,13 +6770,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6530 "tmp.zig:4:10: error: attempt to dereference non-pointer type '[10]u8'",6770 "tmp.zig:4:10: error: attempt to dereference non-pointer type '[10]u8'",
6531 });6771 });
65326772
6533 cases.add("pass const ptr to mutable ptr fn",6773 ctx.objErrStage1("pass const ptr to mutable ptr fn",
6534 \\fn foo() bool {6774 \\fn foo() bool {
6535 \\ const a = @as([]const u8, "a",);6775 \\ const a = @as([]const u8, "a",);
6536 \\ const b = &a;6776 \\ const b = &a;
6537 \\ return ptrEql(b, b);6777 \\ return ptrEql(b, b);
6538 \\}6778 \\}
6539 \\fn ptrEql(a: *[]const u8, b: *[]const u8) bool {6779 \\fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
6780 \\ _ = a; _ = b;
6540 \\ return true;6781 \\ return true;
6541 \\}6782 \\}
6542 \\6783 \\
...@@ -6545,8 +6786,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6545,8 +6786,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6545 "tmp.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'",6786 "tmp.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'",
6546 });6787 });
65476788
6548 cases.addCase(x: {6789 {
6549 const tc = cases.create("export collision",6790 const case = ctx.obj("export collision", .{});
6791 case.backend = .stage1;
6792
6793 case.addSourceFile("foo.zig",
6794 \\export fn bar() void {}
6795 \\pub const baz = 1234;
6796 );
6797
6798 case.addError(
6550 \\const foo = @import("foo.zig",);6799 \\const foo = @import("foo.zig",);
6551 \\6800 \\
6552 \\export fn bar() usize {6801 \\export fn bar() usize {
...@@ -6556,18 +6805,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6556,18 +6805,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6556 "foo.zig:1:1: error: exported symbol collision: 'bar'",6805 "foo.zig:1:1: error: exported symbol collision: 'bar'",
6557 "tmp.zig:3:1: note: other symbol here",6806 "tmp.zig:3:1: note: other symbol here",
6558 });6807 });
6808 }
65596809
6560 tc.addSourceFile("foo.zig",6810 ctx.objErrStage1("implicit cast from array to mutable slice",
6561 \\export fn bar() void {}
6562 \\pub const baz = 1234;
6563 );
6564
6565 break :x tc;
6566 });
6567
6568 cases.add("implicit cast from array to mutable slice",
6569 \\var global_array: [10]i32 = undefined;6811 \\var global_array: [10]i32 = undefined;
6570 \\fn foo(param: []i32) void {}6812 \\fn foo(param: []i32) void {_ = param;}
6571 \\export fn entry() void {6813 \\export fn entry() void {
6572 \\ foo(global_array);6814 \\ foo(global_array);
6573 \\}6815 \\}
...@@ -6575,7 +6817,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6575,7 +6817,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6575 "tmp.zig:4:9: error: expected type '[]i32', found '[10]i32'",6817 "tmp.zig:4:9: error: expected type '[]i32', found '[10]i32'",
6576 });6818 });
65776819
6578 cases.add("ptrcast to non-pointer",6820 ctx.objErrStage1("ptrcast to non-pointer",
6579 \\export fn entry(a: *i32) usize {6821 \\export fn entry(a: *i32) usize {
6580 \\ return @ptrCast(usize, a);6822 \\ return @ptrCast(usize, a);
6581 \\}6823 \\}
...@@ -6583,7 +6825,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6583,7 +6825,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6583 "tmp.zig:2:21: error: expected pointer, found 'usize'",6825 "tmp.zig:2:21: error: expected pointer, found 'usize'",
6584 });6826 });
65856827
6586 cases.add("asm at compile time",6828 ctx.objErrStage1("asm at compile time",
6587 \\comptime {6829 \\comptime {
6588 \\ doSomeAsm();6830 \\ doSomeAsm();
6589 \\}6831 \\}
...@@ -6599,25 +6841,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6599,25 +6841,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6599 "tmp.zig:6:5: error: unable to evaluate constant expression",6841 "tmp.zig:6:5: error: unable to evaluate constant expression",
6600 });6842 });
66016843
6602 cases.add("invalid member of builtin enum",6844 ctx.objErrStage1("invalid member of builtin enum",
6603 \\const builtin = @import("std").builtin;6845 \\const builtin = @import("std").builtin;
6604 \\export fn entry() void {6846 \\export fn entry() void {
6605 \\ const foo = builtin.Mode.x86;6847 \\ const foo = builtin.Mode.x86;
6848 \\ _ = foo;
6606 \\}6849 \\}
6607 , &[_][]const u8{6850 , &[_][]const u8{
6608 "tmp.zig:3:29: error: container 'std.builtin.Mode' has no member called 'x86'",6851 "tmp.zig:3:29: error: container 'std.builtin.Mode' has no member called 'x86'",
6609 });6852 });
66106853
6611 cases.add("int to ptr of 0 bits",6854 ctx.objErrStage1("int to ptr of 0 bits",
6612 \\export fn foo() void {6855 \\export fn foo() void {
6613 \\ var x: usize = 0x1000;6856 \\ var x: usize = 0x1000;
6614 \\ var y: *void = @intToPtr(*void, x);6857 \\ var y: *void = @intToPtr(*void, x);
6858 \\ _ = y;
6615 \\}6859 \\}
6616 , &[_][]const u8{6860 , &[_][]const u8{
6617 "tmp.zig:3:30: error: type '*void' has 0 bits and cannot store information",6861 "tmp.zig:3:30: error: type '*void' has 0 bits and cannot store information",
6618 });6862 });
66196863
6620 cases.add("@fieldParentPtr - non struct",6864 ctx.objErrStage1("@fieldParentPtr - non struct",
6621 \\const Foo = i32;6865 \\const Foo = i32;
6622 \\export fn foo(a: *i32) *Foo {6866 \\export fn foo(a: *i32) *Foo {
6623 \\ return @fieldParentPtr(Foo, "a", a);6867 \\ return @fieldParentPtr(Foo, "a", a);
...@@ -6626,7 +6870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6626,7 +6870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6626 "tmp.zig:3:28: error: expected struct type, found 'i32'",6870 "tmp.zig:3:28: error: expected struct type, found 'i32'",
6627 });6871 });
66286872
6629 cases.add("@fieldParentPtr - bad field name",6873 ctx.objErrStage1("@fieldParentPtr - bad field name",
6630 \\const Foo = extern struct {6874 \\const Foo = extern struct {
6631 \\ derp: i32,6875 \\ derp: i32,
6632 \\};6876 \\};
...@@ -6637,7 +6881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6637,7 +6881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6637 "tmp.zig:5:33: error: struct 'Foo' has no field 'a'",6881 "tmp.zig:5:33: error: struct 'Foo' has no field 'a'",
6638 });6882 });
66396883
6640 cases.add("@fieldParentPtr - field pointer is not pointer",6884 ctx.objErrStage1("@fieldParentPtr - field pointer is not pointer",
6641 \\const Foo = extern struct {6885 \\const Foo = extern struct {
6642 \\ a: i32,6886 \\ a: i32,
6643 \\};6887 \\};
...@@ -6648,7 +6892,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6648,7 +6892,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6648 "tmp.zig:5:38: error: expected pointer, found 'i32'",6892 "tmp.zig:5:38: error: expected pointer, found 'i32'",
6649 });6893 });
66506894
6651 cases.add("@fieldParentPtr - comptime field ptr not based on struct",6895 ctx.objErrStage1("@fieldParentPtr - comptime field ptr not based on struct",
6652 \\const Foo = struct {6896 \\const Foo = struct {
6653 \\ a: i32,6897 \\ a: i32,
6654 \\ b: i32,6898 \\ b: i32,
...@@ -6658,12 +6902,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6658,12 +6902,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6658 \\comptime {6902 \\comptime {
6659 \\ const field_ptr = @intToPtr(*i32, 0x1234);6903 \\ const field_ptr = @intToPtr(*i32, 0x1234);
6660 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);6904 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);
6905 \\ _ = another_foo_ptr;
6661 \\}6906 \\}
6662 , &[_][]const u8{6907 , &[_][]const u8{
6663 "tmp.zig:9:55: error: pointer value not based on parent struct",6908 "tmp.zig:9:55: error: pointer value not based on parent struct",
6664 });6909 });
66656910
6666 cases.add("@fieldParentPtr - comptime wrong field index",6911 ctx.objErrStage1("@fieldParentPtr - comptime wrong field index",
6667 \\const Foo = struct {6912 \\const Foo = struct {
6668 \\ a: i32,6913 \\ a: i32,
6669 \\ b: i32,6914 \\ b: i32,
...@@ -6672,12 +6917,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6672,12 +6917,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6672 \\6917 \\
6673 \\comptime {6918 \\comptime {
6674 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);6919 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
6920 \\ _ = another_foo_ptr;
6675 \\}6921 \\}
6676 , &[_][]const u8{6922 , &[_][]const u8{
6677 "tmp.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'",6923 "tmp.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'",
6678 });6924 });
66796925
6680 cases.add("@offsetOf - non struct",6926 ctx.objErrStage1("@offsetOf - non struct",
6681 \\const Foo = i32;6927 \\const Foo = i32;
6682 \\export fn foo() usize {6928 \\export fn foo() usize {
6683 \\ return @offsetOf(Foo, "a",);6929 \\ return @offsetOf(Foo, "a",);
...@@ -6686,7 +6932,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6686,7 +6932,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6686 "tmp.zig:3:22: error: expected struct type, found 'i32'",6932 "tmp.zig:3:22: error: expected struct type, found 'i32'",
6687 });6933 });
66886934
6689 cases.add("@offsetOf - bad field name",6935 ctx.objErrStage1("@offsetOf - bad field name",
6690 \\const Foo = struct {6936 \\const Foo = struct {
6691 \\ derp: i32,6937 \\ derp: i32,
6692 \\};6938 \\};
...@@ -6697,20 +6943,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6697,20 +6943,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6697 "tmp.zig:5:27: error: struct 'Foo' has no field 'a'",6943 "tmp.zig:5:27: error: struct 'Foo' has no field 'a'",
6698 });6944 });
66996945
6700 cases.addExe("missing main fn in executable",6946 ctx.exeErrStage1("missing main fn in executable",
6701 \\6947 \\
6702 , &[_][]const u8{6948 , &[_][]const u8{
6703 "error: root source file has no member called 'main'",6949 "error: root source file has no member called 'main'",
6704 });6950 });
67056951
6706 cases.addExe("private main fn",6952 ctx.exeErrStage1("private main fn",
6707 \\fn main() void {}6953 \\fn main() void {}
6708 , &[_][]const u8{6954 , &[_][]const u8{
6709 "error: 'main' is private",6955 "error: 'main' is private",
6710 "tmp.zig:1:1: note: declared here",6956 "tmp.zig:1:1: note: declared here",
6711 });6957 });
67126958
6713 cases.add("setting a section on a local variable",6959 ctx.objErrStage1("setting a section on a local variable",
6714 \\export fn entry() i32 {6960 \\export fn entry() i32 {
6715 \\ var foo: i32 linksection(".text2") = 1234;6961 \\ var foo: i32 linksection(".text2") = 1234;
6716 \\ return foo;6962 \\ return foo;
...@@ -6719,7 +6965,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6719,7 +6965,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6719 "tmp.zig:2:30: error: cannot set section of local variable 'foo'",6965 "tmp.zig:2:30: error: cannot set section of local variable 'foo'",
6720 });6966 });
67216967
6722 cases.add("inner struct member shadowing outer struct member",6968 ctx.objErrStage1("inner struct member shadowing outer struct member",
6723 \\fn A() type {6969 \\fn A() type {
6724 \\ return struct {6970 \\ return struct {
6725 \\ b: B(),6971 \\ b: B(),
...@@ -6741,10 +6987,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6741,10 +6987,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6741 \\}6987 \\}
6742 , &[_][]const u8{6988 , &[_][]const u8{
6743 "tmp.zig:9:17: error: redefinition of 'Self'",6989 "tmp.zig:9:17: error: redefinition of 'Self'",
6744 "tmp.zig:5:9: note: previous definition is here",6990 "tmp.zig:5:9: note: previous definition here",
6745 });6991 });
67466992
6747 cases.add("while expected bool, got optional",6993 ctx.objErrStage1("while expected bool, got optional",
6748 \\export fn foo() void {6994 \\export fn foo() void {
6749 \\ while (bar()) {}6995 \\ while (bar()) {}
6750 \\}6996 \\}
...@@ -6753,7 +6999,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6753,7 +6999,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6753 "tmp.zig:2:15: error: expected type 'bool', found '?i32'",6999 "tmp.zig:2:15: error: expected type 'bool', found '?i32'",
6754 });7000 });
67557001
6756 cases.add("while expected bool, got error union",7002 ctx.objErrStage1("while expected bool, got error union",
6757 \\export fn foo() void {7003 \\export fn foo() void {
6758 \\ while (bar()) {}7004 \\ while (bar()) {}
6759 \\}7005 \\}
...@@ -6762,36 +7008,36 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6762,36 +7008,36 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6762 "tmp.zig:2:15: error: expected type 'bool', found 'anyerror!i32'",7008 "tmp.zig:2:15: error: expected type 'bool', found 'anyerror!i32'",
6763 });7009 });
67647010
6765 cases.add("while expected optional, got bool",7011 ctx.objErrStage1("while expected optional, got bool",
6766 \\export fn foo() void {7012 \\export fn foo() void {
6767 \\ while (bar()) |x| {}7013 \\ while (bar()) |x| {_ = x;}
6768 \\}7014 \\}
6769 \\fn bar() bool { return true; }7015 \\fn bar() bool { return true; }
6770 , &[_][]const u8{7016 , &[_][]const u8{
6771 "tmp.zig:2:15: error: expected optional type, found 'bool'",7017 "tmp.zig:2:15: error: expected optional type, found 'bool'",
6772 });7018 });
67737019
6774 cases.add("while expected optional, got error union",7020 ctx.objErrStage1("while expected optional, got error union",
6775 \\export fn foo() void {7021 \\export fn foo() void {
6776 \\ while (bar()) |x| {}7022 \\ while (bar()) |x| {_ = x;}
6777 \\}7023 \\}
6778 \\fn bar() anyerror!i32 { return 1; }7024 \\fn bar() anyerror!i32 { return 1; }
6779 , &[_][]const u8{7025 , &[_][]const u8{
6780 "tmp.zig:2:15: error: expected optional type, found 'anyerror!i32'",7026 "tmp.zig:2:15: error: expected optional type, found 'anyerror!i32'",
6781 });7027 });
67827028
6783 cases.add("while expected error union, got bool",7029 ctx.objErrStage1("while expected error union, got bool",
6784 \\export fn foo() void {7030 \\export fn foo() void {
6785 \\ while (bar()) |x| {} else |err| {}7031 \\ while (bar()) |x| {_ = x;} else |err| {_ = err;}
6786 \\}7032 \\}
6787 \\fn bar() bool { return true; }7033 \\fn bar() bool { return true; }
6788 , &[_][]const u8{7034 , &[_][]const u8{
6789 "tmp.zig:2:15: error: expected error union type, found 'bool'",7035 "tmp.zig:2:15: error: expected error union type, found 'bool'",
6790 });7036 });
67917037
6792 cases.add("while expected error union, got optional",7038 ctx.objErrStage1("while expected error union, got optional",
6793 \\export fn foo() void {7039 \\export fn foo() void {
6794 \\ while (bar()) |x| {} else |err| {}7040 \\ while (bar()) |x| {_ = x;} else |err| {_ = err;}
6795 \\}7041 \\}
6796 \\fn bar() ?i32 { return 1; }7042 \\fn bar() ?i32 { return 1; }
6797 , &[_][]const u8{7043 , &[_][]const u8{
...@@ -6799,7 +7045,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6799,7 +7045,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6799 });7045 });
68007046
6801 // TODO test this in stage2, but we won't even try in stage17047 // TODO test this in stage2, but we won't even try in stage1
6802 //cases.add("inline fn calls itself indirectly",7048 //ctx.objErrStage1("inline fn calls itself indirectly",
6803 // \\export fn foo() void {7049 // \\export fn foo() void {
6804 // \\ bar();7050 // \\ bar();
6805 // \\}7051 // \\}
...@@ -6816,7 +7062,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6816,7 +7062,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6816 // "tmp.zig:4:1: error: unable to inline function",7062 // "tmp.zig:4:1: error: unable to inline function",
6817 //});7063 //});
68187064
6819 //cases.add("save reference to inline function",7065 //ctx.objErrStage1("save reference to inline function",
6820 // \\export fn foo() void {7066 // \\export fn foo() void {
6821 // \\ quux(@ptrToInt(bar));7067 // \\ quux(@ptrToInt(bar));
6822 // \\}7068 // \\}
...@@ -6826,7 +7072,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6826,7 +7072,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6826 // "tmp.zig:4:1: error: unable to inline function",7072 // "tmp.zig:4:1: error: unable to inline function",
6827 //});7073 //});
68287074
6829 cases.add("signed integer division",7075 ctx.objErrStage1("signed integer division",
6830 \\export fn foo(a: i32, b: i32) i32 {7076 \\export fn foo(a: i32, b: i32) i32 {
6831 \\ return a / b;7077 \\ return a / b;
6832 \\}7078 \\}
...@@ -6834,7 +7080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6834,7 +7080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6834 "tmp.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact",7080 "tmp.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact",
6835 });7081 });
68367082
6837 cases.add("signed integer remainder division",7083 ctx.objErrStage1("signed integer remainder division",
6838 \\export fn foo(a: i32, b: i32) i32 {7084 \\export fn foo(a: i32, b: i32) i32 {
6839 \\ return a % b;7085 \\ return a % b;
6840 \\}7086 \\}
...@@ -6842,27 +7088,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6842,27 +7088,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6842 "tmp.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod",7088 "tmp.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod",
6843 });7089 });
68447090
6845 cases.add("compile-time division by zero",7091 ctx.objErrStage1("compile-time division by zero",
6846 \\comptime {7092 \\comptime {
6847 \\ const a: i32 = 1;7093 \\ const a: i32 = 1;
6848 \\ const b: i32 = 0;7094 \\ const b: i32 = 0;
6849 \\ const c = a / b;7095 \\ const c = a / b;
7096 \\ _ = c;
6850 \\}7097 \\}
6851 , &[_][]const u8{7098 , &[_][]const u8{
6852 "tmp.zig:4:17: error: division by zero",7099 "tmp.zig:4:17: error: division by zero",
6853 });7100 });
68547101
6855 cases.add("compile-time remainder division by zero",7102 ctx.objErrStage1("compile-time remainder division by zero",
6856 \\comptime {7103 \\comptime {
6857 \\ const a: i32 = 1;7104 \\ const a: i32 = 1;
6858 \\ const b: i32 = 0;7105 \\ const b: i32 = 0;
6859 \\ const c = a % b;7106 \\ const c = a % b;
7107 \\ _ = c;
6860 \\}7108 \\}
6861 , &[_][]const u8{7109 , &[_][]const u8{
6862 "tmp.zig:4:17: error: division by zero",7110 "tmp.zig:4:17: error: division by zero",
6863 });7111 });
68647112
6865 cases.add("@setRuntimeSafety twice for same scope",7113 ctx.objErrStage1("@setRuntimeSafety twice for same scope",
6866 \\export fn foo() void {7114 \\export fn foo() void {
6867 \\ @setRuntimeSafety(false);7115 \\ @setRuntimeSafety(false);
6868 \\ @setRuntimeSafety(false);7116 \\ @setRuntimeSafety(false);
...@@ -6872,7 +7120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6872,7 +7120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6872 "tmp.zig:2:5: note: first set here",7120 "tmp.zig:2:5: note: first set here",
6873 });7121 });
68747122
6875 cases.add("@setFloatMode twice for same scope",7123 ctx.objErrStage1("@setFloatMode twice for same scope",
6876 \\export fn foo() void {7124 \\export fn foo() void {
6877 \\ @setFloatMode(@import("std").builtin.FloatMode.Optimized);7125 \\ @setFloatMode(@import("std").builtin.FloatMode.Optimized);
6878 \\ @setFloatMode(@import("std").builtin.FloatMode.Optimized);7126 \\ @setFloatMode(@import("std").builtin.FloatMode.Optimized);
...@@ -6882,15 +7130,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6882,15 +7130,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6882 "tmp.zig:2:5: note: first set here",7130 "tmp.zig:2:5: note: first set here",
6883 });7131 });
68847132
6885 cases.add("array access of type",7133 ctx.objErrStage1("array access of type",
6886 \\export fn foo() void {7134 \\export fn foo() void {
6887 \\ var b: u8[40] = undefined;7135 \\ var b: u8[40] = undefined;
7136 \\ _ = b;
6888 \\}7137 \\}
6889 , &[_][]const u8{7138 , &[_][]const u8{
6890 "tmp.zig:2:14: error: array access of non-array type 'type'",7139 "tmp.zig:2:14: error: array access of non-array type 'type'",
6891 });7140 });
68927141
6893 cases.add("cannot break out of defer expression",7142 ctx.objErrStage1("cannot break out of defer expression",
6894 \\export fn foo() void {7143 \\export fn foo() void {
6895 \\ while (true) {7144 \\ while (true) {
6896 \\ defer {7145 \\ defer {
...@@ -6902,7 +7151,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6902,7 +7151,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6902 "tmp.zig:4:13: error: cannot break out of defer expression",7151 "tmp.zig:4:13: error: cannot break out of defer expression",
6903 });7152 });
69047153
6905 cases.add("cannot continue out of defer expression",7154 ctx.objErrStage1("cannot continue out of defer expression",
6906 \\export fn foo() void {7155 \\export fn foo() void {
6907 \\ while (true) {7156 \\ while (true) {
6908 \\ defer {7157 \\ defer {
...@@ -6914,11 +7163,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6914,11 +7163,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6914 "tmp.zig:4:13: error: cannot continue out of defer expression",7163 "tmp.zig:4:13: error: cannot continue out of defer expression",
6915 });7164 });
69167165
6917 cases.add("calling a generic function only known at runtime",7166 ctx.objErrStage1("calling a generic function only known at runtime",
6918 \\var foos = [_]fn(anytype) void { foo1, foo2 };7167 \\var foos = [_]fn(anytype) void { foo1, foo2 };
6919 \\7168 \\
6920 \\fn foo1(arg: anytype) void {}7169 \\fn foo1(arg: anytype) void {_ = arg;}
6921 \\fn foo2(arg: anytype) void {}7170 \\fn foo2(arg: anytype) void {_ = arg;}
6922 \\7171 \\
6923 \\pub fn main() !void {7172 \\pub fn main() !void {
6924 \\ foos[0](true);7173 \\ foos[0](true);
...@@ -6927,7 +7176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6927,7 +7176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6927 "tmp.zig:7:9: error: calling a generic function requires compile-time known function value",7176 "tmp.zig:7:9: error: calling a generic function requires compile-time known function value",
6928 });7177 });
69297178
6930 cases.add("@compileError shows traceback of references that caused it",7179 ctx.objErrStage1("@compileError shows traceback of references that caused it",
6931 \\const foo = @compileError("aoeu",);7180 \\const foo = @compileError("aoeu",);
6932 \\7181 \\
6933 \\const bar = baz + foo;7182 \\const bar = baz + foo;
...@@ -6942,23 +7191,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6942,23 +7191,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6942 "tmp.zig:7:12: note: referenced here",7191 "tmp.zig:7:12: note: referenced here",
6943 });7192 });
69447193
6945 cases.add("float literal too large error",7194 ctx.objErrStage1("float literal too large error",
6946 \\comptime {7195 \\comptime {
6947 \\ const a = 0x1.0p18495;7196 \\ const a = 0x1.0p18495;
7197 \\ _ = a;
6948 \\}7198 \\}
6949 , &[_][]const u8{7199 , &[_][]const u8{
6950 "tmp.zig:2:15: error: float literal out of range of any type",7200 "tmp.zig:2:15: error: float literal out of range of any type",
6951 });7201 });
69527202
6953 cases.add("float literal too small error (denormal)",7203 ctx.objErrStage1("float literal too small error (denormal)",
6954 \\comptime {7204 \\comptime {
6955 \\ const a = 0x1.0p-19000;7205 \\ const a = 0x1.0p-19000;
7206 \\ _ = a;
6956 \\}7207 \\}
6957 , &[_][]const u8{7208 , &[_][]const u8{
6958 "tmp.zig:2:15: error: float literal out of range of any type",7209 "tmp.zig:2:15: error: float literal out of range of any type",
6959 });7210 });
69607211
6961 cases.add("explicit cast float literal to integer when there is a fraction component",7212 ctx.objErrStage1("explicit cast float literal to integer when there is a fraction component",
6962 \\export fn entry() i32 {7213 \\export fn entry() i32 {
6963 \\ return @as(i32, 12.34);7214 \\ return @as(i32, 12.34);
6964 \\}7215 \\}
...@@ -6966,7 +7217,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6966,7 +7217,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6966 "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",7217 "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
6967 });7218 });
69687219
6969 cases.add("non pointer given to @ptrToInt",7220 ctx.objErrStage1("non pointer given to @ptrToInt",
6970 \\export fn entry(x: i32) usize {7221 \\export fn entry(x: i32) usize {
6971 \\ return @ptrToInt(x);7222 \\ return @ptrToInt(x);
6972 \\}7223 \\}
...@@ -6974,23 +7225,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6974,23 +7225,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6974 "tmp.zig:2:22: error: expected pointer, found 'i32'",7225 "tmp.zig:2:22: error: expected pointer, found 'i32'",
6975 });7226 });
69767227
6977 cases.add("@shlExact shifts out 1 bits",7228 ctx.objErrStage1("@shlExact shifts out 1 bits",
6978 \\comptime {7229 \\comptime {
6979 \\ const x = @shlExact(@as(u8, 0b01010101), 2);7230 \\ const x = @shlExact(@as(u8, 0b01010101), 2);
7231 \\ _ = x;
6980 \\}7232 \\}
6981 , &[_][]const u8{7233 , &[_][]const u8{
6982 "tmp.zig:2:15: error: operation caused overflow",7234 "tmp.zig:2:15: error: operation caused overflow",
6983 });7235 });
69847236
6985 cases.add("@shrExact shifts out 1 bits",7237 ctx.objErrStage1("@shrExact shifts out 1 bits",
6986 \\comptime {7238 \\comptime {
6987 \\ const x = @shrExact(@as(u8, 0b10101010), 2);7239 \\ const x = @shrExact(@as(u8, 0b10101010), 2);
7240 \\ _ = x;
6988 \\}7241 \\}
6989 , &[_][]const u8{7242 , &[_][]const u8{
6990 "tmp.zig:2:15: error: exact shift shifted out 1 bits",7243 "tmp.zig:2:15: error: exact shift shifted out 1 bits",
6991 });7244 });
69927245
6993 cases.add("shifting without int type or comptime known",7246 ctx.objErrStage1("shifting without int type or comptime known",
6994 \\export fn entry(x: u8) u8 {7247 \\export fn entry(x: u8) u8 {
6995 \\ return 0x11 << x;7248 \\ return 0x11 << x;
6996 \\}7249 \\}
...@@ -6998,7 +7251,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6998,7 +7251,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6998 "tmp.zig:2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be compile-time known",7251 "tmp.zig:2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be compile-time known",
6999 });7252 });
70007253
7001 cases.add("shifting RHS is log2 of LHS int bit width",7254 ctx.objErrStage1("shifting RHS is log2 of LHS int bit width",
7002 \\export fn entry(x: u8, y: u8) u8 {7255 \\export fn entry(x: u8, y: u8) u8 {
7003 \\ return x << y;7256 \\ return x << y;
7004 \\}7257 \\}
...@@ -7006,16 +7259,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7006,16 +7259,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7006 "tmp.zig:2:17: error: expected type 'u3', found 'u8'",7259 "tmp.zig:2:17: error: expected type 'u3', found 'u8'",
7007 });7260 });
70087261
7009 cases.add("globally shadowing a primitive type",7262 ctx.objErrStage1("globally shadowing a primitive type",
7010 \\const u16 = u8;7263 \\const u16 = u8;
7011 \\export fn entry() void {7264 \\export fn entry() void {
7012 \\ const a: u16 = 300;7265 \\ const a: u16 = 300;
7266 \\ _ = a;
7013 \\}7267 \\}
7014 , &[_][]const u8{7268 , &[_][]const u8{
7015 "tmp.zig:1:1: error: declaration shadows primitive type 'u16'",7269 "tmp.zig:1:1: error: declaration shadows primitive type 'u16'",
7016 });7270 });
70177271
7018 cases.add("implicitly increasing pointer alignment",7272 ctx.objErrStage1("implicitly increasing pointer alignment",
7019 \\const Foo = packed struct {7273 \\const Foo = packed struct {
7020 \\ a: u8,7274 \\ a: u8,
7021 \\ b: u32,7275 \\ b: u32,
...@@ -7033,7 +7287,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7033,7 +7287,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7033 "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'",7287 "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'",
7034 });7288 });
70357289
7036 cases.add("implicitly increasing slice alignment",7290 ctx.objErrStage1("implicitly increasing slice alignment",
7037 \\const Foo = packed struct {7291 \\const Foo = packed struct {
7038 \\ a: u8,7292 \\ a: u8,
7039 \\ b: u32,7293 \\ b: u32,
...@@ -7054,7 +7308,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7054,7 +7308,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7054 "tmp.zig:9:26: note: '*[1]u32' has alignment 4",7308 "tmp.zig:9:26: note: '*[1]u32' has alignment 4",
7055 });7309 });
70567310
7057 cases.add("increase pointer alignment in @ptrCast",7311 ctx.objErrStage1("increase pointer alignment in @ptrCast",
7058 \\export fn entry() u32 {7312 \\export fn entry() u32 {
7059 \\ var bytes: [4]u8 = [_]u8{0x01, 0x02, 0x03, 0x04};7313 \\ var bytes: [4]u8 = [_]u8{0x01, 0x02, 0x03, 0x04};
7060 \\ const ptr = @ptrCast(*u32, &bytes[0]);7314 \\ const ptr = @ptrCast(*u32, &bytes[0]);
...@@ -7066,7 +7320,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7066,7 +7320,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7066 "tmp.zig:3:26: note: '*u32' has alignment 4",7320 "tmp.zig:3:26: note: '*u32' has alignment 4",
7067 });7321 });
70687322
7069 cases.add("@alignCast expects pointer or slice",7323 ctx.objErrStage1("@alignCast expects pointer or slice",
7070 \\export fn entry() void {7324 \\export fn entry() void {
7071 \\ @alignCast(4, @as(u32, 3));7325 \\ @alignCast(4, @as(u32, 3));
7072 \\}7326 \\}
...@@ -7074,7 +7328,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7074,7 +7328,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7074 "tmp.zig:2:19: error: expected pointer or slice, found 'u32'",7328 "tmp.zig:2:19: error: expected pointer or slice, found 'u32'",
7075 });7329 });
70767330
7077 cases.add("passing an under-aligned function pointer",7331 ctx.objErrStage1("passing an under-aligned function pointer",
7078 \\export fn entry() void {7332 \\export fn entry() void {
7079 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);7333 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
7080 \\}7334 \\}
...@@ -7086,7 +7340,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7086,7 +7340,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7086 "tmp.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'",7340 "tmp.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'",
7087 });7341 });
70887342
7089 cases.add("passing a not-aligned-enough pointer to cmpxchg",7343 ctx.objErrStage1("passing a not-aligned-enough pointer to cmpxchg",
7090 \\const AtomicOrder = @import("std").builtin.AtomicOrder;7344 \\const AtomicOrder = @import("std").builtin.AtomicOrder;
7091 \\export fn entry() bool {7345 \\export fn entry() bool {
7092 \\ var x: i32 align(1) = 1234;7346 \\ var x: i32 align(1) = 1234;
...@@ -7097,15 +7351,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7097,15 +7351,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7097 "tmp.zig:4:32: error: expected type '*i32', found '*align(1) i32'",7351 "tmp.zig:4:32: error: expected type '*i32', found '*align(1) i32'",
7098 });7352 });
70997353
7100 cases.add("wrong size to an array literal",7354 ctx.objErrStage1("wrong size to an array literal",
7101 \\comptime {7355 \\comptime {
7102 \\ const array = [2]u8{1, 2, 3};7356 \\ const array = [2]u8{1, 2, 3};
7357 \\ _ = array;
7103 \\}7358 \\}
7104 , &[_][]const u8{7359 , &[_][]const u8{
7105 "tmp.zig:2:31: error: index 2 outside array of size 2",7360 "tmp.zig:2:31: error: index 2 outside array of size 2",
7106 });7361 });
71077362
7108 cases.add("wrong pointer coerced to pointer to opaque {}",7363 ctx.objErrStage1("wrong pointer coerced to pointer to opaque {}",
7109 \\const Derp = opaque {};7364 \\const Derp = opaque {};
7110 \\extern fn bar(d: *Derp) void;7365 \\extern fn bar(d: *Derp) void;
7111 \\export fn foo() void {7366 \\export fn foo() void {
...@@ -7116,53 +7371,66 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7116,53 +7371,66 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7116 "tmp.zig:5:9: error: expected type '*Derp', found '*c_void'",7371 "tmp.zig:5:9: error: expected type '*Derp', found '*c_void'",
7117 });7372 });
71187373
7119 cases.add("non-const variables of things that require const variables",7374 ctx.objErrStage1("non-const variables of things that require const variables",
7120 \\export fn entry1() void {7375 \\export fn entry1() void {
7121 \\ var m2 = &2;7376 \\ var m2 = &2;
7377 \\ _ = m2;
7122 \\}7378 \\}
7123 \\export fn entry2() void {7379 \\export fn entry2() void {
7124 \\ var a = undefined;7380 \\ var a = undefined;
7381 \\ _ = a;
7125 \\}7382 \\}
7126 \\export fn entry3() void {7383 \\export fn entry3() void {
7127 \\ var b = 1;7384 \\ var b = 1;
7385 \\ _ = b;
7128 \\}7386 \\}
7129 \\export fn entry4() void {7387 \\export fn entry4() void {
7130 \\ var c = 1.0;7388 \\ var c = 1.0;
7389 \\ _ = c;
7131 \\}7390 \\}
7132 \\export fn entry5() void {7391 \\export fn entry5() void {
7133 \\ var d = null;7392 \\ var d = null;
7393 \\ _ = d;
7134 \\}7394 \\}
7135 \\export fn entry6(opaque_: *Opaque) void {7395 \\export fn entry6(opaque_: *Opaque) void {
7136 \\ var e = opaque_.*;7396 \\ var e = opaque_.*;
7397 \\ _ = e;
7137 \\}7398 \\}
7138 \\export fn entry7() void {7399 \\export fn entry7() void {
7139 \\ var f = i32;7400 \\ var f = i32;
7401 \\ _ = f;
7140 \\}7402 \\}
7141 \\export fn entry8() void {7403 \\export fn entry8() void {
7142 \\ var h = (Foo {}).bar;7404 \\ var h = (Foo {}).bar;
7143 \\}7405 \\ _ = h;
7144 \\export fn entry9() void {
7145 \\ var z: noreturn = return;
7146 \\}7406 \\}
7147 \\const Opaque = opaque {};7407 \\const Opaque = opaque {};
7148 \\const Foo = struct {7408 \\const Foo = struct {
7149 \\ fn bar(self: *const Foo) void {}7409 \\ fn bar(self: *const Foo) void {_ = self;}
7150 \\};7410 \\};
7151 , &[_][]const u8{7411 , &[_][]const u8{
7152 "tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime",7412 "tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime",
7153 "tmp.zig:5:4: error: variable of type '(undefined)' must be const or comptime",7413 "tmp.zig:6:4: error: variable of type '(undefined)' must be const or comptime",
7154 "tmp.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",7414 "tmp.zig:10:4: error: variable of type 'comptime_int' must be const or comptime",
7155 "tmp.zig:8:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type",7415 "tmp.zig:10:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type",
7156 "tmp.zig:11:4: error: variable of type 'comptime_float' must be const or comptime",7416 "tmp.zig:14:4: error: variable of type 'comptime_float' must be const or comptime",
7157 "tmp.zig:11:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type",7417 "tmp.zig:14:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type",
7158 "tmp.zig:14:4: error: variable of type '(null)' must be const or comptime",7418 "tmp.zig:18:4: error: variable of type '(null)' must be const or comptime",
7159 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed",7419 "tmp.zig:22:4: error: variable of type 'Opaque' not allowed",
7160 "tmp.zig:20:4: error: variable of type 'type' must be const or comptime",7420 "tmp.zig:26:4: error: variable of type 'type' must be const or comptime",
7161 "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",7421 "tmp.zig:30:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
7162 "tmp.zig:26:22: error: unreachable code",7422 });
7423
7424 ctx.objErrStage1("variable with type 'noreturn'",
7425 \\export fn entry9() void {
7426 \\ var z: noreturn = return;
7427 \\}
7428 , &[_][]const u8{
7429 "tmp.zig:2:5: error: unreachable code",
7430 "tmp.zig:2:23: note: control flow is diverted here",
7163 });7431 });
71647432
7165 cases.add("wrong types given to atomic order args in cmpxchg",7433 ctx.objErrStage1("wrong types given to atomic order args in cmpxchg",
7166 \\export fn entry() void {7434 \\export fn entry() void {
7167 \\ var x: i32 = 1234;7435 \\ var x: i32 = 1234;
7168 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}7436 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}
...@@ -7171,7 +7439,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7171,7 +7439,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7171 "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'",7439 "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
7172 });7440 });
71737441
7174 cases.add("wrong types given to @export",7442 ctx.objErrStage1("wrong types given to @export",
7175 \\fn entry() callconv(.C) void { }7443 \\fn entry() callconv(.C) void { }
7176 \\comptime {7444 \\comptime {
7177 \\ @export(entry, .{.name = "entry", .linkage = @as(u32, 1234) });7445 \\ @export(entry, .{.name = "entry", .linkage = @as(u32, 1234) });
...@@ -7180,7 +7448,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7180,7 +7448,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7180 "tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'",7448 "tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'",
7181 });7449 });
71827450
7183 cases.add("struct with invalid field",7451 ctx.objErrStage1("struct with invalid field",
7184 \\const std = @import("std",);7452 \\const std = @import("std",);
7185 \\const Allocator = std.mem.Allocator;7453 \\const Allocator = std.mem.Allocator;
7186 \\const ArrayList = std.ArrayList;7454 \\const ArrayList = std.ArrayList;
...@@ -7203,12 +7471,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7203,12 +7471,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7203 \\ .text = MdText.init(&std.testing.allocator),7471 \\ .text = MdText.init(&std.testing.allocator),
7204 \\ .weight = HeaderWeight.H1,7472 \\ .weight = HeaderWeight.H1,
7205 \\ };7473 \\ };
7474 \\ _ = a;
7206 \\}7475 \\}
7207 , &[_][]const u8{7476 , &[_][]const u8{
7208 "tmp.zig:14:17: error: use of undeclared identifier 'HeaderValue'",7477 "tmp.zig:14:17: error: use of undeclared identifier 'HeaderValue'",
7209 });7478 });
72107479
7211 cases.add("@setAlignStack outside function",7480 ctx.objErrStage1("@setAlignStack outside function",
7212 \\comptime {7481 \\comptime {
7213 \\ @setAlignStack(16);7482 \\ @setAlignStack(16);
7214 \\}7483 \\}
...@@ -7216,7 +7485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7216,7 +7485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7216 "tmp.zig:2:5: error: @setAlignStack outside function",7485 "tmp.zig:2:5: error: @setAlignStack outside function",
7217 });7486 });
72187487
7219 cases.add("@setAlignStack in naked function",7488 ctx.objErrStage1("@setAlignStack in naked function",
7220 \\export fn entry() callconv(.Naked) void {7489 \\export fn entry() callconv(.Naked) void {
7221 \\ @setAlignStack(16);7490 \\ @setAlignStack(16);
7222 \\}7491 \\}
...@@ -7224,7 +7493,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7224,7 +7493,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7224 "tmp.zig:2:5: error: @setAlignStack in naked function",7493 "tmp.zig:2:5: error: @setAlignStack in naked function",
7225 });7494 });
72267495
7227 cases.add("@setAlignStack in inline function",7496 ctx.objErrStage1("@setAlignStack in inline function",
7228 \\export fn entry() void {7497 \\export fn entry() void {
7229 \\ foo();7498 \\ foo();
7230 \\}7499 \\}
...@@ -7235,7 +7504,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7235,7 +7504,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7235 "tmp.zig:5:5: error: @setAlignStack in inline function",7504 "tmp.zig:5:5: error: @setAlignStack in inline function",
7236 });7505 });
72377506
7238 cases.add("@setAlignStack set twice",7507 ctx.objErrStage1("@setAlignStack set twice",
7239 \\export fn entry() void {7508 \\export fn entry() void {
7240 \\ @setAlignStack(16);7509 \\ @setAlignStack(16);
7241 \\ @setAlignStack(16);7510 \\ @setAlignStack(16);
...@@ -7245,7 +7514,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7245,7 +7514,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7245 "tmp.zig:2:5: note: first set here",7514 "tmp.zig:2:5: note: first set here",
7246 });7515 });
72477516
7248 cases.add("@setAlignStack too big",7517 ctx.objErrStage1("@setAlignStack too big",
7249 \\export fn entry() void {7518 \\export fn entry() void {
7250 \\ @setAlignStack(511 + 1);7519 \\ @setAlignStack(511 + 1);
7251 \\}7520 \\}
...@@ -7253,7 +7522,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7253,7 +7522,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7253 "tmp.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256",7522 "tmp.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256",
7254 });7523 });
72557524
7256 cases.add("storing runtime value in compile time variable then using it",7525 ctx.objErrStage1("storing runtime value in compile time variable then using it",
7257 \\const Mode = @import("std").builtin.Mode;7526 \\const Mode = @import("std").builtin.Mode;
7258 \\7527 \\
7259 \\fn Free(comptime filename: []const u8) TestCase {7528 \\fn Free(comptime filename: []const u8) TestCase {
...@@ -7290,24 +7559,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7290,24 +7559,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7290 \\ };7559 \\ };
7291 \\7560 \\
7292 \\ for ([_]Mode { Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast }) |mode| {7561 \\ for ([_]Mode { Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast }) |mode| {
7562 \\ _ = mode;
7293 \\ inline for (tests) |test_case| {7563 \\ inline for (tests) |test_case| {
7294 \\ const foo = test_case.filename ++ ".zig";7564 \\ const foo = test_case.filename ++ ".zig";
7565 \\ _ = foo;
7295 \\ }7566 \\ }
7296 \\ }7567 \\ }
7297 \\}7568 \\}
7298 , &[_][]const u8{7569 , &[_][]const u8{
7299 "tmp.zig:37:29: error: cannot store runtime value in compile time variable",7570 "tmp.zig:38:29: error: cannot store runtime value in compile time variable",
7300 });7571 });
73017572
7302 cases.add("invalid legacy unicode escape",7573 ctx.objErrStage1("invalid legacy unicode escape",
7303 \\export fn entry() void {7574 \\export fn entry() void {
7304 \\ const a = '\U1234';7575 \\ const a = '\U1234';
7305 \\}7576 \\}
7306 , &[_][]const u8{7577 , &[_][]const u8{
7307 "tmp.zig:2:17: error: invalid character: 'U'",7578 "tmp.zig:2:15: error: expected expression, found 'invalid'",
7579 "tmp.zig:2:18: note: invalid byte: '1'",
7308 });7580 });
73097581
7310 cases.add("invalid empty unicode escape",7582 ctx.objErrStage1("invalid empty unicode escape",
7311 \\export fn entry() void {7583 \\export fn entry() void {
7312 \\ const a = '\u{}';7584 \\ const a = '\u{}';
7313 \\}7585 \\}
...@@ -7315,21 +7587,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7315,21 +7587,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7315 "tmp.zig:2:19: error: empty unicode escape sequence",7587 "tmp.zig:2:19: error: empty unicode escape sequence",
7316 });7588 });
73177589
7318 cases.add("non-printable invalid character", "\xff\xfe" ++7590 ctx.objErrStage1("non-printable invalid character", "\xff\xfe" ++
7319 \\fn test() bool {\r7591 "fn foo() bool {\r\n" ++
7320 \\ true\r7592 " return true;\r\n" ++
7321 \\}7593 "}\r\n", &[_][]const u8{
7322 , &[_][]const u8{7594 "tmp.zig:1:1: error: expected test, comptime, var decl, or container field, found 'invalid'",
7323 "tmp.zig:1:1: error: invalid character: '\\xff'",7595 "tmp.zig:1:1: note: invalid byte: '\\xff'",
7324 });7596 });
73257597
7326 cases.add("non-printable invalid character with escape alternative", "fn test() bool {\n" ++7598 ctx.objErrStage1("non-printable invalid character with escape alternative", "fn foo() bool {\n" ++
7327 "\ttrue\n" ++7599 "\treturn true;\n" ++
7328 "}\n", &[_][]const u8{7600 "}\n", &[_][]const u8{
7329 "tmp.zig:2:1: error: invalid character: '\\t'",7601 "tmp.zig:2:1: error: invalid character: '\\t'",
7330 });7602 });
73317603
7332 cases.add("calling var args extern function, passing array instead of pointer",7604 ctx.objErrStage1("calling var args extern function, passing array instead of pointer",
7333 \\export fn entry() void {7605 \\export fn entry() void {
7334 \\ foo("hello".*,);7606 \\ foo("hello".*,);
7335 \\}7607 \\}
...@@ -7338,7 +7610,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7338,7 +7610,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7338 "tmp.zig:2:16: error: expected type '*const u8', found '[5:0]u8'",7610 "tmp.zig:2:16: error: expected type '*const u8', found '[5:0]u8'",
7339 });7611 });
73407612
7341 cases.add("constant inside comptime function has compile error",7613 ctx.objErrStage1("constant inside comptime function has compile error",
7342 \\const ContextAllocator = MemoryPool(usize);7614 \\const ContextAllocator = MemoryPool(usize);
7343 \\7615 \\
7344 \\pub fn MemoryPool(comptime T: type) type {7616 \\pub fn MemoryPool(comptime T: type) type {
...@@ -7353,12 +7625,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7353,12 +7625,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7353 \\ var allocator: ContextAllocator = undefined;7625 \\ var allocator: ContextAllocator = undefined;
7354 \\}7626 \\}
7355 , &[_][]const u8{7627 , &[_][]const u8{
7356 "tmp.zig:4:25: error: aoeu",7628 "tmp.zig:4:5: error: unreachable code",
7357 "tmp.zig:1:36: note: referenced here",7629 "tmp.zig:4:25: note: control flow is diverted here",
7358 "tmp.zig:12:20: note: referenced here",7630 "tmp.zig:12:9: error: unused local variable",
7359 });7631 });
73607632
7361 cases.add("specify enum tag type that is too small",7633 ctx.objErrStage1("specify enum tag type that is too small",
7362 \\const Small = enum (u2) {7634 \\const Small = enum (u2) {
7363 \\ One,7635 \\ One,
7364 \\ Two,7636 \\ Two,
...@@ -7369,12 +7641,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7369,12 +7641,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7369 \\7641 \\
7370 \\export fn entry() void {7642 \\export fn entry() void {
7371 \\ var x = Small.One;7643 \\ var x = Small.One;
7644 \\ _ = x;
7372 \\}7645 \\}
7373 , &[_][]const u8{7646 , &[_][]const u8{
7374 "tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'",7647 "tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'",
7375 });7648 });
73767649
7377 cases.add("specify non-integer enum tag type",7650 ctx.objErrStage1("specify non-integer enum tag type",
7378 \\const Small = enum (f32) {7651 \\const Small = enum (f32) {
7379 \\ One,7652 \\ One,
7380 \\ Two,7653 \\ Two,
...@@ -7383,12 +7656,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7383,12 +7656,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7383 \\7656 \\
7384 \\export fn entry() void {7657 \\export fn entry() void {
7385 \\ var x = Small.One;7658 \\ var x = Small.One;
7659 \\ _ = x;
7386 \\}7660 \\}
7387 , &[_][]const u8{7661 , &[_][]const u8{
7388 "tmp.zig:1:21: error: expected integer, found 'f32'",7662 "tmp.zig:1:21: error: expected integer, found 'f32'",
7389 });7663 });
73907664
7391 cases.add("implicitly casting enum to tag type",7665 ctx.objErrStage1("implicitly casting enum to tag type",
7392 \\const Small = enum(u2) {7666 \\const Small = enum(u2) {
7393 \\ One,7667 \\ One,
7394 \\ Two,7668 \\ Two,
...@@ -7398,12 +7672,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7398,12 +7672,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7398 \\7672 \\
7399 \\export fn entry() void {7673 \\export fn entry() void {
7400 \\ var x: u2 = Small.Two;7674 \\ var x: u2 = Small.Two;
7675 \\ _ = x;
7401 \\}7676 \\}
7402 , &[_][]const u8{7677 , &[_][]const u8{
7403 "tmp.zig:9:22: error: expected type 'u2', found 'Small'",7678 "tmp.zig:9:22: error: expected type 'u2', found 'Small'",
7404 });7679 });
74057680
7406 cases.add("explicitly casting non tag type to enum",7681 ctx.objErrStage1("explicitly casting non tag type to enum",
7407 \\const Small = enum(u2) {7682 \\const Small = enum(u2) {
7408 \\ One,7683 \\ One,
7409 \\ Two,7684 \\ Two,
...@@ -7414,42 +7689,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7414,42 +7689,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7414 \\export fn entry() void {7689 \\export fn entry() void {
7415 \\ var y = @as(u3, 3);7690 \\ var y = @as(u3, 3);
7416 \\ var x = @intToEnum(Small, y);7691 \\ var x = @intToEnum(Small, y);
7692 \\ _ = x;
7417 \\}7693 \\}
7418 , &[_][]const u8{7694 , &[_][]const u8{
7419 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",7695 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",
7420 });7696 });
74217697
7422 cases.add("union fields with value assignments",7698 ctx.objErrStage1("union fields with value assignments",
7423 \\const MultipleChoice = union {7699 \\const MultipleChoice = union {
7424 \\ A: i32 = 20,7700 \\ A: i32 = 20,
7425 \\};7701 \\};
7426 \\export fn entry() void {7702 \\export fn entry() void {
7427 \\ var x: MultipleChoice = undefined;7703 \\ var x: MultipleChoice = undefined;
7704 \\ _ = x;
7428 \\}7705 \\}
7429 , &[_][]const u8{7706 , &[_][]const u8{
7430 "tmp.zig:2:14: error: untagged union field assignment",7707 "tmp.zig:1:24: error: explicitly valued tagged union missing integer tag type",
7431 "tmp.zig:1:24: note: consider 'union(enum)' here",7708 "tmp.zig:2:14: note: tag value specified here",
7432 });7709 });
74337710
7434 cases.add("enum with 0 fields",7711 ctx.objErrStage1("enum with 0 fields",
7435 \\const Foo = enum {};7712 \\const Foo = enum {};
7436 \\export fn entry() usize {
7437 \\ return @sizeOf(Foo);
7438 \\}
7439 , &[_][]const u8{7713 , &[_][]const u8{
7440 "tmp.zig:1:13: error: enums must have 1 or more fields",7714 "tmp.zig:1:13: error: enum declarations must have at least one tag",
7441 });7715 });
74427716
7443 cases.add("union with 0 fields",7717 ctx.objErrStage1("union with 0 fields",
7444 \\const Foo = union {};7718 \\const Foo = union {};
7445 \\export fn entry() usize {
7446 \\ return @sizeOf(Foo);
7447 \\}
7448 , &[_][]const u8{7719 , &[_][]const u8{
7449 "tmp.zig:1:13: error: unions must have 1 or more fields",7720 "tmp.zig:1:13: error: union declarations must have at least one tag",
7450 });7721 });
74517722
7452 cases.add("enum value already taken",7723 ctx.objErrStage1("enum value already taken",
7453 \\const MultipleChoice = enum(u32) {7724 \\const MultipleChoice = enum(u32) {
7454 \\ A = 20,7725 \\ A = 20,
7455 \\ B = 40,7726 \\ B = 40,
...@@ -7459,13 +7730,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7459,13 +7730,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7459 \\};7730 \\};
7460 \\export fn entry() void {7731 \\export fn entry() void {
7461 \\ var x = MultipleChoice.C;7732 \\ var x = MultipleChoice.C;
7733 \\ _ = x;
7462 \\}7734 \\}
7463 , &[_][]const u8{7735 , &[_][]const u8{
7464 "tmp.zig:6:5: error: enum tag value 60 already taken",7736 "tmp.zig:6:5: error: enum tag value 60 already taken",
7465 "tmp.zig:4:5: note: other occurrence here",7737 "tmp.zig:4:5: note: other occurrence here",
7466 });7738 });
74677739
7468 cases.add("union with specified enum omits field",7740 ctx.objErrStage1("union with specified enum omits field",
7469 \\const Letter = enum {7741 \\const Letter = enum {
7470 \\ A,7742 \\ A,
7471 \\ B,7743 \\ B,
...@@ -7483,29 +7755,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7483,29 +7755,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7483 "tmp.zig:4:5: note: declared here",7755 "tmp.zig:4:5: note: declared here",
7484 });7756 });
74857757
7486 cases.add("non-integer tag type to automatic union enum",7758 ctx.objErrStage1("non-integer tag type to automatic union enum",
7487 \\const Foo = union(enum(f32)) {7759 \\const Foo = union(enum(f32)) {
7488 \\ A: i32,7760 \\ A: i32,
7489 \\};7761 \\};
7490 \\export fn entry() void {7762 \\export fn entry() void {
7491 \\ const x = @typeInfo(Foo).Union.tag_type.?;7763 \\ const x = @typeInfo(Foo).Union.tag_type.?;
7764 \\ _ = x;
7492 \\}7765 \\}
7493 , &[_][]const u8{7766 , &[_][]const u8{
7494 "tmp.zig:1:24: error: expected integer tag type, found 'f32'",7767 "tmp.zig:1:24: error: expected integer tag type, found 'f32'",
7495 });7768 });
74967769
7497 cases.add("non-enum tag type passed to union",7770 ctx.objErrStage1("non-enum tag type passed to union",
7498 \\const Foo = union(u32) {7771 \\const Foo = union(u32) {
7499 \\ A: i32,7772 \\ A: i32,
7500 \\};7773 \\};
7501 \\export fn entry() void {7774 \\export fn entry() void {
7502 \\ const x = @typeInfo(Foo).Union.tag_type.?;7775 \\ const x = @typeInfo(Foo).Union.tag_type.?;
7776 \\ _ = x;
7503 \\}7777 \\}
7504 , &[_][]const u8{7778 , &[_][]const u8{
7505 "tmp.zig:1:19: error: expected enum tag type, found 'u32'",7779 "tmp.zig:1:19: error: expected enum tag type, found 'u32'",
7506 });7780 });
75077781
7508 cases.add("union auto-enum value already taken",7782 ctx.objErrStage1("union auto-enum value already taken",
7509 \\const MultipleChoice = union(enum(u32)) {7783 \\const MultipleChoice = union(enum(u32)) {
7510 \\ A = 20,7784 \\ A = 20,
7511 \\ B = 40,7785 \\ B = 40,
...@@ -7515,13 +7789,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7515,13 +7789,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7515 \\};7789 \\};
7516 \\export fn entry() void {7790 \\export fn entry() void {
7517 \\ var x = MultipleChoice { .C = {} };7791 \\ var x = MultipleChoice { .C = {} };
7792 \\ _ = x;
7518 \\}7793 \\}
7519 , &[_][]const u8{7794 , &[_][]const u8{
7520 "tmp.zig:6:9: error: enum tag value 60 already taken",7795 "tmp.zig:6:9: error: enum tag value 60 already taken",
7521 "tmp.zig:4:9: note: other occurrence here",7796 "tmp.zig:4:9: note: other occurrence here",
7522 });7797 });
75237798
7524 cases.add("union enum field does not match enum",7799 ctx.objErrStage1("union enum field does not match enum",
7525 \\const Letter = enum {7800 \\const Letter = enum {
7526 \\ A,7801 \\ A,
7527 \\ B,7802 \\ B,
...@@ -7535,49 +7810,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7535,49 +7810,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7535 \\};7810 \\};
7536 \\export fn entry() void {7811 \\export fn entry() void {
7537 \\ var a = Payload {.A = 1234};7812 \\ var a = Payload {.A = 1234};
7813 \\ _ = a;
7538 \\}7814 \\}
7539 , &[_][]const u8{7815 , &[_][]const u8{
7540 "tmp.zig:10:5: error: enum field not found: 'D'",7816 "tmp.zig:10:5: error: enum field not found: 'D'",
7541 "tmp.zig:1:16: note: enum declared here",7817 "tmp.zig:1:16: note: enum declared here",
7542 });7818 });
75437819
7544 cases.add("field type supplied in an enum",7820 ctx.objErrStage1("field type supplied in an enum",
7545 \\const Letter = enum {7821 \\const Letter = enum {
7546 \\ A: void,7822 \\ A: void,
7547 \\ B,7823 \\ B,
7548 \\ C,7824 \\ C,
7549 \\};7825 \\};
7550 \\export fn entry() void {
7551 \\ var b = Letter.B;
7552 \\}
7553 , &[_][]const u8{7826 , &[_][]const u8{
7554 "tmp.zig:2:8: error: structs and unions, not enums, support field types",7827 "tmp.zig:2:8: error: enum fields do not have types",
7555 "tmp.zig:1:16: note: consider 'union(enum)' here",7828 "tmp.zig:1:16: note: consider 'union(enum)' here to make it a tagged union",
7556 });7829 });
75577830
7558 cases.add("struct field missing type",7831 ctx.objErrStage1("struct field missing type",
7559 \\const Letter = struct {7832 \\const Letter = struct {
7560 \\ A,7833 \\ A,
7561 \\};7834 \\};
7562 \\export fn entry() void {7835 \\export fn entry() void {
7563 \\ var a = Letter { .A = {} };7836 \\ var a = Letter { .A = {} };
7837 \\ _ = a;
7564 \\}7838 \\}
7565 , &[_][]const u8{7839 , &[_][]const u8{
7566 "tmp.zig:2:5: error: struct field missing type",7840 "tmp.zig:2:5: error: struct field missing type",
7567 });7841 });
75687842
7569 cases.add("extern union field missing type",7843 ctx.objErrStage1("extern union field missing type",
7570 \\const Letter = extern union {7844 \\const Letter = extern union {
7571 \\ A,7845 \\ A,
7572 \\};7846 \\};
7573 \\export fn entry() void {7847 \\export fn entry() void {
7574 \\ var a = Letter { .A = {} };7848 \\ var a = Letter { .A = {} };
7849 \\ _ = a;
7575 \\}7850 \\}
7576 , &[_][]const u8{7851 , &[_][]const u8{
7577 "tmp.zig:2:5: error: union field missing type",7852 "tmp.zig:2:5: error: union field missing type",
7578 });7853 });
75797854
7580 cases.add("extern union given enum tag type",7855 ctx.objErrStage1("extern union given enum tag type",
7581 \\const Letter = enum {7856 \\const Letter = enum {
7582 \\ A,7857 \\ A,
7583 \\ B,7858 \\ B,
...@@ -7590,12 +7865,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7590,12 +7865,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7590 \\};7865 \\};
7591 \\export fn entry() void {7866 \\export fn entry() void {
7592 \\ var a = Payload { .A = 1234 };7867 \\ var a = Payload { .A = 1234 };
7868 \\ _ = a;
7593 \\}7869 \\}
7594 , &[_][]const u8{7870 , &[_][]const u8{
7595 "tmp.zig:6:30: error: extern union does not support enum tag type",7871 "tmp.zig:6:30: error: extern union does not support enum tag type",
7596 });7872 });
75977873
7598 cases.add("packed union given enum tag type",7874 ctx.objErrStage1("packed union given enum tag type",
7599 \\const Letter = enum {7875 \\const Letter = enum {
7600 \\ A,7876 \\ A,
7601 \\ B,7877 \\ B,
...@@ -7608,12 +7884,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7608,12 +7884,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7608 \\};7884 \\};
7609 \\export fn entry() void {7885 \\export fn entry() void {
7610 \\ var a = Payload { .A = 1234 };7886 \\ var a = Payload { .A = 1234 };
7887 \\ _ = a;
7611 \\}7888 \\}
7612 , &[_][]const u8{7889 , &[_][]const u8{
7613 "tmp.zig:6:30: error: packed union does not support enum tag type",7890 "tmp.zig:6:30: error: packed union does not support enum tag type",
7614 });7891 });
76157892
7616 cases.add("packed union with automatic layout field",7893 ctx.objErrStage1("packed union with automatic layout field",
7617 \\const Foo = struct {7894 \\const Foo = struct {
7618 \\ a: u32,7895 \\ a: u32,
7619 \\ b: f32,7896 \\ b: f32,
...@@ -7624,12 +7901,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7624,12 +7901,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7624 \\};7901 \\};
7625 \\export fn entry() void {7902 \\export fn entry() void {
7626 \\ var a = Payload { .B = true };7903 \\ var a = Payload { .B = true };
7904 \\ _ = a;
7627 \\}7905 \\}
7628 , &[_][]const u8{7906 , &[_][]const u8{
7629 "tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation",7907 "tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation",
7630 });7908 });
76317909
7632 cases.add("switch on union with no attached enum",7910 ctx.objErrStage1("switch on union with no attached enum",
7633 \\const Payload = union {7911 \\const Payload = union {
7634 \\ A: i32,7912 \\ A: i32,
7635 \\ B: f64,7913 \\ B: f64,
...@@ -7650,20 +7928,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7650,20 +7928,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7650 "tmp.zig:1:17: note: consider 'union(enum)' here",7928 "tmp.zig:1:17: note: consider 'union(enum)' here",
7651 });7929 });
76527930
7653 cases.add("enum in field count range but not matching tag",7931 ctx.objErrStage1("enum in field count range but not matching tag",
7654 \\const Foo = enum(u32) {7932 \\const Foo = enum(u32) {
7655 \\ A = 10,7933 \\ A = 10,
7656 \\ B = 11,7934 \\ B = 11,
7657 \\};7935 \\};
7658 \\export fn entry() void {7936 \\export fn entry() void {
7659 \\ var x = @intToEnum(Foo, 0);7937 \\ var x = @intToEnum(Foo, 0);
7938 \\ _ = x;
7660 \\}7939 \\}
7661 , &[_][]const u8{7940 , &[_][]const u8{
7662 "tmp.zig:6:13: error: enum 'Foo' has no tag matching integer value 0",7941 "tmp.zig:6:13: error: enum 'Foo' has no tag matching integer value 0",
7663 "tmp.zig:1:13: note: 'Foo' declared here",7942 "tmp.zig:1:13: note: 'Foo' declared here",
7664 });7943 });
76657944
7666 cases.add("comptime cast enum to union but field has payload",7945 ctx.objErrStage1("comptime cast enum to union but field has payload",
7667 \\const Letter = enum { A, B, C };7946 \\const Letter = enum { A, B, C };
7668 \\const Value = union(Letter) {7947 \\const Value = union(Letter) {
7669 \\ A: i32,7948 \\ A: i32,
...@@ -7672,13 +7951,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7672,13 +7951,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7672 \\};7951 \\};
7673 \\export fn entry() void {7952 \\export fn entry() void {
7674 \\ var x: Value = Letter.A;7953 \\ var x: Value = Letter.A;
7954 \\ _ = x;
7675 \\}7955 \\}
7676 , &[_][]const u8{7956 , &[_][]const u8{
7677 "tmp.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",7957 "tmp.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",
7678 "tmp.zig:3:5: note: field 'A' declared here",7958 "tmp.zig:3:5: note: field 'A' declared here",
7679 });7959 });
76807960
7681 cases.add("runtime cast to union which has non-void fields",7961 ctx.objErrStage1("runtime cast to union which has non-void fields",
7682 \\const Letter = enum { A, B, C };7962 \\const Letter = enum { A, B, C };
7683 \\const Value = union(Letter) {7963 \\const Value = union(Letter) {
7684 \\ A: i32,7964 \\ A: i32,
...@@ -7690,35 +7970,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7690,35 +7970,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7690 \\}7970 \\}
7691 \\fn foo(l: Letter) void {7971 \\fn foo(l: Letter) void {
7692 \\ var x: Value = l;7972 \\ var x: Value = l;
7973 \\ _ = x;
7693 \\}7974 \\}
7694 , &[_][]const u8{7975 , &[_][]const u8{
7695 "tmp.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",7976 "tmp.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
7696 "tmp.zig:3:5: note: field 'A' has type 'i32'",7977 "tmp.zig:3:5: note: field 'A' has type 'i32'",
7697 });7978 });
76987979
7699 cases.add("taking byte offset of void field in struct",7980 ctx.objErrStage1("taking byte offset of void field in struct",
7700 \\const Empty = struct {7981 \\const Empty = struct {
7701 \\ val: void,7982 \\ val: void,
7702 \\};7983 \\};
7703 \\export fn foo() void {7984 \\export fn foo() void {
7704 \\ const fieldOffset = @offsetOf(Empty, "val",);7985 \\ const fieldOffset = @offsetOf(Empty, "val",);
7986 \\ _ = fieldOffset;
7705 \\}7987 \\}
7706 , &[_][]const u8{7988 , &[_][]const u8{
7707 "tmp.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset",7989 "tmp.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset",
7708 });7990 });
77097991
7710 cases.add("taking bit offset of void field in struct",7992 ctx.objErrStage1("taking bit offset of void field in struct",
7711 \\const Empty = struct {7993 \\const Empty = struct {
7712 \\ val: void,7994 \\ val: void,
7713 \\};7995 \\};
7714 \\export fn foo() void {7996 \\export fn foo() void {
7715 \\ const fieldOffset = @bitOffsetOf(Empty, "val",);7997 \\ const fieldOffset = @bitOffsetOf(Empty, "val",);
7998 \\ _ = fieldOffset;
7716 \\}7999 \\}
7717 , &[_][]const u8{8000 , &[_][]const u8{
7718 "tmp.zig:5:45: error: zero-bit field 'val' in struct 'Empty' has no offset",8001 "tmp.zig:5:45: error: zero-bit field 'val' in struct 'Empty' has no offset",
7719 });8002 });
77208003
7721 cases.add("invalid union field access in comptime",8004 ctx.objErrStage1("invalid union field access in comptime",
7722 \\const Foo = union {8005 \\const Foo = union {
7723 \\ Bar: u8,8006 \\ Bar: u8,
7724 \\ Baz: void,8007 \\ Baz: void,
...@@ -7726,12 +8009,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7726,12 +8009,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7726 \\comptime {8009 \\comptime {
7727 \\ var foo = Foo {.Baz = {}};8010 \\ var foo = Foo {.Baz = {}};
7728 \\ const bar_val = foo.Bar;8011 \\ const bar_val = foo.Bar;
8012 \\ _ = bar_val;
7729 \\}8013 \\}
7730 , &[_][]const u8{8014 , &[_][]const u8{
7731 "tmp.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set",8015 "tmp.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set",
7732 });8016 });
77338017
7734 cases.add("unsupported modifier at start of asm output constraint",8018 ctx.objErrStage1("unsupported modifier at start of asm output constraint",
7735 \\export fn foo() void {8019 \\export fn foo() void {
7736 \\ var bar: u32 = 3;8020 \\ var bar: u32 = 3;
7737 \\ asm volatile ("" : [baz]"+r"(bar) : : "");8021 \\ asm volatile ("" : [baz]"+r"(bar) : : "");
...@@ -7740,7 +8024,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7740,7 +8024,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7740 "tmp.zig:3:5: error: invalid modifier starting output constraint for 'baz': '+', only '=' is supported. Compiler TODO: see https://github.com/ziglang/zig/issues/215",8024 "tmp.zig:3:5: error: invalid modifier starting output constraint for 'baz': '+', only '=' is supported. Compiler TODO: see https://github.com/ziglang/zig/issues/215",
7741 });8025 });
77428026
7743 cases.add("comptime_int in asm input",8027 ctx.objErrStage1("comptime_int in asm input",
7744 \\export fn foo() void {8028 \\export fn foo() void {
7745 \\ asm volatile ("" : : [bar]"r"(3) : "");8029 \\ asm volatile ("" : : [bar]"r"(3) : "");
7746 \\}8030 \\}
...@@ -7748,7 +8032,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7748,7 +8032,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7748 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_int",8032 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_int",
7749 });8033 });
77508034
7751 cases.add("comptime_float in asm input",8035 ctx.objErrStage1("comptime_float in asm input",
7752 \\export fn foo() void {8036 \\export fn foo() void {
7753 \\ asm volatile ("" : : [bar]"r"(3.17) : "");8037 \\ asm volatile ("" : : [bar]"r"(3.17) : "");
7754 \\}8038 \\}
...@@ -7756,7 +8040,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7756,7 +8040,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7756 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_float",8040 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_float",
7757 });8041 });
77588042
7759 cases.add("runtime assignment to comptime struct type",8043 ctx.objErrStage1("runtime assignment to comptime struct type",
7760 \\const Foo = struct {8044 \\const Foo = struct {
7761 \\ Bar: u8,8045 \\ Bar: u8,
7762 \\ Baz: type,8046 \\ Baz: type,
...@@ -7764,12 +8048,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7764,12 +8048,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7764 \\export fn f() void {8048 \\export fn f() void {
7765 \\ var x: u8 = 0;8049 \\ var x: u8 = 0;
7766 \\ const foo = Foo { .Bar = x, .Baz = u8 };8050 \\ const foo = Foo { .Bar = x, .Baz = u8 };
8051 \\ _ = foo;
7767 \\}8052 \\}
7768 , &[_][]const u8{8053 , &[_][]const u8{
7769 "tmp.zig:7:23: error: unable to evaluate constant expression",8054 "tmp.zig:7:23: error: unable to evaluate constant expression",
7770 });8055 });
77718056
7772 cases.add("runtime assignment to comptime union type",8057 ctx.objErrStage1("runtime assignment to comptime union type",
7773 \\const Foo = union {8058 \\const Foo = union {
7774 \\ Bar: u8,8059 \\ Bar: u8,
7775 \\ Baz: type,8060 \\ Baz: type,
...@@ -7777,16 +8062,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7777,16 +8062,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7777 \\export fn f() void {8062 \\export fn f() void {
7778 \\ var x: u8 = 0;8063 \\ var x: u8 = 0;
7779 \\ const foo = Foo { .Bar = x };8064 \\ const foo = Foo { .Bar = x };
8065 \\ _ = foo;
7780 \\}8066 \\}
7781 , &[_][]const u8{8067 , &[_][]const u8{
7782 "tmp.zig:7:23: error: unable to evaluate constant expression",8068 "tmp.zig:7:23: error: unable to evaluate constant expression",
7783 });8069 });
77848070
7785 cases.addTest("@shuffle with selected index past first vector length",8071 ctx.testErrStage1("@shuffle with selected index past first vector length",
7786 \\export fn entry() void {8072 \\export fn entry() void {
7787 \\ const v: @import("std").meta.Vector(4, u32) = [4]u32{ 10, 11, 12, 13 };8073 \\ const v: @import("std").meta.Vector(4, u32) = [4]u32{ 10, 11, 12, 13 };
7788 \\ const x: @import("std").meta.Vector(4, u32) = [4]u32{ 14, 15, 16, 17 };8074 \\ const x: @import("std").meta.Vector(4, u32) = [4]u32{ 14, 15, 16, 17 };
7789 \\ var z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });8075 \\ var z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });
8076 \\ _ = z;
7790 \\}8077 \\}
7791 , &[_][]const u8{8078 , &[_][]const u8{
7792 "tmp.zig:4:39: error: mask index '4' has out-of-bounds selection",8079 "tmp.zig:4:39: error: mask index '4' has out-of-bounds selection",
...@@ -7794,27 +8081,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7794,27 +8081,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7794 "tmp.zig:4:30: note: selections from the second vector are specified with negative numbers",8081 "tmp.zig:4:30: note: selections from the second vector are specified with negative numbers",
7795 });8082 });
77968083
7797 cases.addTest("nested vectors",8084 ctx.testErrStage1("nested vectors",
7798 \\export fn entry() void {8085 \\export fn entry() void {
7799 \\ const V1 = @import("std").meta.Vector(4, u8);8086 \\ const V1 = @import("std").meta.Vector(4, u8);
7800 \\ const V2 = @Type(@import("std").builtin.TypeInfo{ .Vector = .{ .len = 4, .child = V1 } });8087 \\ const V2 = @Type(@import("std").builtin.TypeInfo{ .Vector = .{ .len = 4, .child = V1 } });
7801 \\ var v: V2 = undefined;8088 \\ var v: V2 = undefined;
8089 \\ _ = v;
7802 \\}8090 \\}
7803 , &[_][]const u8{8091 , &[_][]const u8{
7804 "tmp.zig:3:53: error: vector element type must be integer, float, bool, or pointer; '@Vector(4, u8)' is invalid",8092 "tmp.zig:3:53: error: vector element type must be integer, float, bool, or pointer; '@Vector(4, u8)' is invalid",
7805 "tmp.zig:3:16: note: referenced here",8093 "tmp.zig:3:16: note: referenced here",
7806 });8094 });
78078095
7808 cases.addTest("bad @splat type",8096 ctx.testErrStage1("bad @splat type",
7809 \\export fn entry() void {8097 \\export fn entry() void {
7810 \\ const c = 4;8098 \\ const c = 4;
7811 \\ var v = @splat(4, c);8099 \\ var v = @splat(4, c);
8100 \\ _ = v;
7812 \\}8101 \\}
7813 , &[_][]const u8{8102 , &[_][]const u8{
7814 "tmp.zig:3:23: error: vector element type must be integer, float, bool, or pointer; 'comptime_int' is invalid",8103 "tmp.zig:3:23: error: vector element type must be integer, float, bool, or pointer; 'comptime_int' is invalid",
7815 });8104 });
78168105
7817 cases.add("compileLog of tagged enum doesn't crash the compiler",8106 ctx.objErrStage1("compileLog of tagged enum doesn't crash the compiler",
7818 \\const Bar = union(enum(u32)) {8107 \\const Bar = union(enum(u32)) {
7819 \\ X: i32 = 18108 \\ X: i32 = 1
7820 \\};8109 \\};
...@@ -7830,28 +8119,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7830,28 +8119,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7830 "tmp.zig:6:5: error: found compile log statement",8119 "tmp.zig:6:5: error: found compile log statement",
7831 });8120 });
78328121
7833 cases.add("attempted implicit cast from *const T to *[1]T",8122 ctx.objErrStage1("attempted implicit cast from *const T to *[1]T",
7834 \\export fn entry(byte: u8) void {8123 \\export fn entry(byte: u8) void {
7835 \\ const w: i32 = 1234;8124 \\ const w: i32 = 1234;
7836 \\ var x: *const i32 = &w;8125 \\ var x: *const i32 = &w;
7837 \\ var y: *[1]i32 = x;8126 \\ var y: *[1]i32 = x;
7838 \\ y[0] += 1;8127 \\ y[0] += 1;
8128 \\ _ = byte;
7839 \\}8129 \\}
7840 , &[_][]const u8{8130 , &[_][]const u8{
7841 "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'",8131 "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'",
7842 "tmp.zig:4:22: note: cast discards const qualifier",8132 "tmp.zig:4:22: note: cast discards const qualifier",
7843 });8133 });
78448134
7845 cases.add("attempted implicit cast from *const T to []T",8135 ctx.objErrStage1("attempted implicit cast from *const T to []T",
7846 \\export fn entry() void {8136 \\export fn entry() void {
7847 \\ const u: u32 = 42;8137 \\ const u: u32 = 42;
7848 \\ const x: []u32 = &u;8138 \\ const x: []u32 = &u;
8139 \\ _ = x;
7849 \\}8140 \\}
7850 , &[_][]const u8{8141 , &[_][]const u8{
7851 "tmp.zig:3:23: error: expected type '[]u32', found '*const u32'",8142 "tmp.zig:3:23: error: expected type '[]u32', found '*const u32'",
7852 });8143 });
78538144
7854 cases.add("for loop body expression ignored",8145 ctx.objErrStage1("for loop body expression ignored",
7855 \\fn returns() usize {8146 \\fn returns() usize {
7856 \\ return 2;8147 \\ return 2;
7857 \\}8148 \\}
...@@ -7861,21 +8152,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7861,21 +8152,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7861 \\export fn f2() void {8152 \\export fn f2() void {
7862 \\ var x: anyerror!i32 = error.Bad;8153 \\ var x: anyerror!i32 = error.Bad;
7863 \\ for ("hello") |_| returns() else unreachable;8154 \\ for ("hello") |_| returns() else unreachable;
8155 \\ _ = x;
7864 \\}8156 \\}
7865 , &[_][]const u8{8157 , &[_][]const u8{
7866 "tmp.zig:5:30: error: expression value is ignored",8158 "tmp.zig:5:30: error: expression value is ignored",
7867 "tmp.zig:9:30: error: expression value is ignored",8159 "tmp.zig:9:30: error: expression value is ignored",
7868 });8160 });
78698161
7870 cases.add("aligned variable of zero-bit type",8162 ctx.objErrStage1("aligned variable of zero-bit type",
7871 \\export fn f() void {8163 \\export fn f() void {
7872 \\ var s: struct {} align(4) = undefined;8164 \\ var s: struct {} align(4) = undefined;
8165 \\ _ = s;
7873 \\}8166 \\}
7874 , &[_][]const u8{8167 , &[_][]const u8{
7875 "tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned",8168 "tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned",
7876 });8169 });
78778170
7878 cases.add("function returning opaque type",8171 ctx.objErrStage1("function returning opaque type",
7879 \\const FooType = opaque {};8172 \\const FooType = opaque {};
7880 \\export fn bar() !FooType {8173 \\export fn bar() !FooType {
7881 \\ return error.InvalidValue;8174 \\ return error.InvalidValue;
...@@ -7893,7 +8186,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7893,7 +8186,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7893 "tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed",8186 "tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed",
7894 });8187 });
78958188
7896 cases.add("generic function returning opaque type",8189 ctx.objErrStage1("generic function returning opaque type",
7897 \\const FooType = opaque {};8190 \\const FooType = opaque {};
7898 \\fn generic(comptime T: type) !T {8191 \\fn generic(comptime T: type) !T {
7899 \\ return undefined;8192 \\ return undefined;
...@@ -7917,81 +8210,89 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7917,81 +8210,89 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7917 "tmp.zig:2:1: note: function declared here",8210 "tmp.zig:2:1: note: function declared here",
7918 });8211 });
79198212
7920 cases.add("function parameter is opaque",8213 ctx.objErrStage1("function parameter is opaque",
7921 \\const FooType = opaque {};8214 \\const FooType = opaque {};
7922 \\export fn entry1() void {8215 \\export fn entry1() void {
7923 \\ const someFuncPtr: fn (FooType) void = undefined;8216 \\ const someFuncPtr: fn (FooType) void = undefined;
8217 \\ _ = someFuncPtr;
7924 \\}8218 \\}
7925 \\8219 \\
7926 \\export fn entry2() void {8220 \\export fn entry2() void {
7927 \\ const someFuncPtr: fn (@TypeOf(null)) void = undefined;8221 \\ const someFuncPtr: fn (@TypeOf(null)) void = undefined;
8222 \\ _ = someFuncPtr;
7928 \\}8223 \\}
7929 \\8224 \\
7930 \\fn foo(p: FooType) void {}8225 \\fn foo(p: FooType) void {_ = p;}
7931 \\export fn entry3() void {8226 \\export fn entry3() void {
7932 \\ _ = foo;8227 \\ _ = foo;
7933 \\}8228 \\}
7934 \\8229 \\
7935 \\fn bar(p: @TypeOf(null)) void {}8230 \\fn bar(p: @TypeOf(null)) void {_ = p;}
7936 \\export fn entry4() void {8231 \\export fn entry4() void {
7937 \\ _ = bar;8232 \\ _ = bar;
7938 \\}8233 \\}
7939 , &[_][]const u8{8234 , &[_][]const u8{
7940 "tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed",8235 "tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed",
7941 "tmp.zig:7:28: error: parameter of type '(null)' not allowed",8236 "tmp.zig:8:28: error: parameter of type '(null)' not allowed",
7942 "tmp.zig:10:11: error: parameter of opaque type 'FooType' not allowed",8237 "tmp.zig:12:11: error: parameter of opaque type 'FooType' not allowed",
7943 "tmp.zig:15:11: error: parameter of type '(null)' not allowed",8238 "tmp.zig:17:11: error: parameter of type '(null)' not allowed",
7944 });8239 });
79458240
7946 cases.add( // fixed bug #20328241 ctx.objErrStage1( // fixed bug #2032
7947 "compile diagnostic string for top level decl type",8242 "compile diagnostic string for top level decl type",
7948 \\export fn entry() void {8243 \\export fn entry() void {
7949 \\ var foo: u32 = @This(){};8244 \\ var foo: u32 = @This(){};
8245 \\ _ = foo;
7950 \\}8246 \\}
7951 , &[_][]const u8{8247 , &[_][]const u8{
7952 "tmp.zig:2:27: error: type 'u32' does not support array initialization",8248 "tmp.zig:2:27: error: type 'u32' does not support array initialization",
7953 });8249 });
79548250
7955 cases.add("issue #2687: coerce from undefined array pointer to slice",8251 ctx.objErrStage1("issue #2687: coerce from undefined array pointer to slice",
7956 \\export fn foo1() void {8252 \\export fn foo1() void {
7957 \\ const a: *[1]u8 = undefined;8253 \\ const a: *[1]u8 = undefined;
7958 \\ var b: []u8 = a;8254 \\ var b: []u8 = a;
8255 \\ _ = b;
7959 \\}8256 \\}
7960 \\export fn foo2() void {8257 \\export fn foo2() void {
7961 \\ comptime {8258 \\ comptime {
7962 \\ var a: *[1]u8 = undefined;8259 \\ var a: *[1]u8 = undefined;
7963 \\ var b: []u8 = a;8260 \\ var b: []u8 = a;
8261 \\ _ = b;
7964 \\ }8262 \\ }
7965 \\}8263 \\}
7966 \\export fn foo3() void {8264 \\export fn foo3() void {
7967 \\ comptime {8265 \\ comptime {
7968 \\ const a: *[1]u8 = undefined;8266 \\ const a: *[1]u8 = undefined;
7969 \\ var b: []u8 = a;8267 \\ var b: []u8 = a;
8268 \\ _ = b;
7970 \\ }8269 \\ }
7971 \\}8270 \\}
7972 , &[_][]const u8{8271 , &[_][]const u8{
7973 "tmp.zig:3:19: error: use of undefined value here causes undefined behavior",8272 "tmp.zig:3:19: error: use of undefined value here causes undefined behavior",
7974 "tmp.zig:8:23: error: use of undefined value here causes undefined behavior",8273 "tmp.zig:9:23: error: use of undefined value here causes undefined behavior",
7975 "tmp.zig:14:23: error: use of undefined value here causes undefined behavior",8274 "tmp.zig:16:23: error: use of undefined value here causes undefined behavior",
7976 });8275 });
79778276
7978 cases.add("issue #3818: bitcast from parray/slice to u16",8277 ctx.objErrStage1("issue #3818: bitcast from parray/slice to u16",
7979 \\export fn foo1() void {8278 \\export fn foo1() void {
7980 \\ var bytes = [_]u8{1, 2};8279 \\ var bytes = [_]u8{1, 2};
7981 \\ const word: u16 = @bitCast(u16, bytes[0..]);8280 \\ const word: u16 = @bitCast(u16, bytes[0..]);
8281 \\ _ = word;
7982 \\}8282 \\}
7983 \\export fn foo2() void {8283 \\export fn foo2() void {
7984 \\ var bytes: []const u8 = &[_]u8{1, 2};8284 \\ var bytes: []const u8 = &[_]u8{1, 2};
7985 \\ const word: u16 = @bitCast(u16, bytes);8285 \\ const word: u16 = @bitCast(u16, bytes);
8286 \\ _ = word;
7986 \\}8287 \\}
7987 , &[_][]const u8{8288 , &[_][]const u8{
7988 "tmp.zig:3:42: error: unable to @bitCast from pointer type '*[2]u8'",8289 "tmp.zig:3:42: error: unable to @bitCast from pointer type '*[2]u8'",
7989 "tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]const u8' has size 16",8290 "tmp.zig:8:32: error: destination type 'u16' has size 2 but source type '[]const u8' has size 16",
7990 "tmp.zig:7:37: note: referenced here",8291 "tmp.zig:8:37: note: referenced here",
7991 });8292 });
79928293
7993 // issue #78108294 // issue #7810
7994 cases.add("comptime slice-len increment beyond bounds",8295 ctx.objErrStage1("comptime slice-len increment beyond bounds",
7995 \\export fn foo_slice_len_increment_beyond_bounds() void {8296 \\export fn foo_slice_len_increment_beyond_bounds() void {
7996 \\ comptime {8297 \\ comptime {
7997 \\ var buf_storage: [8]u8 = undefined;8298 \\ var buf_storage: [8]u8 = undefined;
...@@ -8004,11 +8305,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8004,11 +8305,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8004 ":6:12: error: out of bounds slice",8305 ":6:12: error: out of bounds slice",
8005 });8306 });
80068307
8007 cases.add("comptime slice-sentinel is out of bounds (unterminated)",8308 ctx.objErrStage1("comptime slice-sentinel is out of bounds (unterminated)",
8008 \\export fn foo_array() void {8309 \\export fn foo_array() void {
8009 \\ comptime {8310 \\ comptime {
8010 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8311 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8011 \\ const slice = target[0..14 :0];8312 \\ const slice = target[0..14 :0];
8313 \\ _ = slice;
8012 \\ }8314 \\ }
8013 \\}8315 \\}
8014 \\export fn foo_ptr_array() void {8316 \\export fn foo_ptr_array() void {
...@@ -8016,6 +8318,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8016,6 +8318,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8016 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8318 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8017 \\ var target = &buf;8319 \\ var target = &buf;
8018 \\ const slice = target[0..14 :0];8320 \\ const slice = target[0..14 :0];
8321 \\ _ = slice;
8019 \\ }8322 \\ }
8020 \\}8323 \\}
8021 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {8324 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
...@@ -8023,6 +8326,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8023,6 +8326,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8023 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8326 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8024 \\ var target: [*]u8 = &buf;8327 \\ var target: [*]u8 = &buf;
8025 \\ const slice = target[0..14 :0];8328 \\ const slice = target[0..14 :0];
8329 \\ _ = slice;
8026 \\ }8330 \\ }
8027 \\}8331 \\}
8028 \\export fn foo_vector_ConstPtrSpecialRef() void {8332 \\export fn foo_vector_ConstPtrSpecialRef() void {
...@@ -8030,6 +8334,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8030,6 +8334,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8030 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8334 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8031 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);8335 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
8032 \\ const slice = target[0..14 :0];8336 \\ const slice = target[0..14 :0];
8337 \\ _ = slice;
8033 \\ }8338 \\ }
8034 \\}8339 \\}
8035 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {8340 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
...@@ -8037,6 +8342,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8037,6 +8342,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8037 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8342 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8038 \\ var target: [*c]u8 = &buf;8343 \\ var target: [*c]u8 = &buf;
8039 \\ const slice = target[0..14 :0];8344 \\ const slice = target[0..14 :0];
8345 \\ _ = slice;
8040 \\ }8346 \\ }
8041 \\}8347 \\}
8042 \\export fn foo_cvector_ConstPtrSpecialRef() void {8348 \\export fn foo_cvector_ConstPtrSpecialRef() void {
...@@ -8044,6 +8350,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8044,6 +8350,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8044 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8350 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8045 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);8351 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
8046 \\ const slice = target[0..14 :0];8352 \\ const slice = target[0..14 :0];
8353 \\ _ = slice;
8047 \\ }8354 \\ }
8048 \\}8355 \\}
8049 \\export fn foo_slice() void {8356 \\export fn foo_slice() void {
...@@ -8051,23 +8358,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8051,23 +8358,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8051 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8358 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8052 \\ var target: []u8 = &buf;8359 \\ var target: []u8 = &buf;
8053 \\ const slice = target[0..14 :0];8360 \\ const slice = target[0..14 :0];
8361 \\ _ = slice;
8054 \\ }8362 \\ }
8055 \\}8363 \\}
8056 , &[_][]const u8{8364 , &[_][]const u8{
8057 ":4:29: error: slice-sentinel is out of bounds",8365 ":4:29: error: slice-sentinel is out of bounds",
8058 ":11:29: error: slice-sentinel is out of bounds",8366 ":12:29: error: slice-sentinel is out of bounds",
8059 ":18:29: error: slice-sentinel is out of bounds",8367 ":20:29: error: slice-sentinel is out of bounds",
8060 ":25:29: error: slice-sentinel is out of bounds",8368 ":28:29: error: slice-sentinel is out of bounds",
8061 ":32:29: error: slice-sentinel is out of bounds",8369 ":36:29: error: slice-sentinel is out of bounds",
8062 ":39:29: error: slice-sentinel is out of bounds",8370 ":44:29: error: slice-sentinel is out of bounds",
8063 ":46:29: error: slice-sentinel is out of bounds",8371 ":52:29: error: slice-sentinel is out of bounds",
8064 });8372 });
80658373
8066 cases.add("comptime slice-sentinel is out of bounds (terminated)",8374 ctx.objErrStage1("comptime slice-sentinel is out of bounds (terminated)",
8067 \\export fn foo_array() void {8375 \\export fn foo_array() void {
8068 \\ comptime {8376 \\ comptime {
8069 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8377 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8070 \\ const slice = target[0..15 :1];8378 \\ const slice = target[0..15 :1];
8379 \\ _ = slice;
8071 \\ }8380 \\ }
8072 \\}8381 \\}
8073 \\export fn foo_ptr_array() void {8382 \\export fn foo_ptr_array() void {
...@@ -8075,6 +8384,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8075,6 +8384,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8075 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8384 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8076 \\ var target = &buf;8385 \\ var target = &buf;
8077 \\ const slice = target[0..15 :0];8386 \\ const slice = target[0..15 :0];
8387 \\ _ = slice;
8078 \\ }8388 \\ }
8079 \\}8389 \\}
8080 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {8390 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
...@@ -8082,6 +8392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8082,6 +8392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8082 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8392 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8083 \\ var target: [*]u8 = &buf;8393 \\ var target: [*]u8 = &buf;
8084 \\ const slice = target[0..15 :0];8394 \\ const slice = target[0..15 :0];
8395 \\ _ = slice;
8085 \\ }8396 \\ }
8086 \\}8397 \\}
8087 \\export fn foo_vector_ConstPtrSpecialRef() void {8398 \\export fn foo_vector_ConstPtrSpecialRef() void {
...@@ -8089,6 +8400,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8089,6 +8400,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8089 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8400 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8090 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);8401 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
8091 \\ const slice = target[0..15 :0];8402 \\ const slice = target[0..15 :0];
8403 \\ _ = slice;
8092 \\ }8404 \\ }
8093 \\}8405 \\}
8094 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {8406 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
...@@ -8096,6 +8408,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8096,6 +8408,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8096 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8408 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8097 \\ var target: [*c]u8 = &buf;8409 \\ var target: [*c]u8 = &buf;
8098 \\ const slice = target[0..15 :0];8410 \\ const slice = target[0..15 :0];
8411 \\ _ = slice;
8099 \\ }8412 \\ }
8100 \\}8413 \\}
8101 \\export fn foo_cvector_ConstPtrSpecialRef() void {8414 \\export fn foo_cvector_ConstPtrSpecialRef() void {
...@@ -8103,6 +8416,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8103,6 +8416,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8103 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8416 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8104 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);8417 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
8105 \\ const slice = target[0..15 :0];8418 \\ const slice = target[0..15 :0];
8419 \\ _ = slice;
8106 \\ }8420 \\ }
8107 \\}8421 \\}
8108 \\export fn foo_slice() void {8422 \\export fn foo_slice() void {
...@@ -8110,23 +8424,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8110,23 +8424,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8110 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8424 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8111 \\ var target: []u8 = &buf;8425 \\ var target: []u8 = &buf;
8112 \\ const slice = target[0..15 :0];8426 \\ const slice = target[0..15 :0];
8427 \\ _ = slice;
8113 \\ }8428 \\ }
8114 \\}8429 \\}
8115 , &[_][]const u8{8430 , &[_][]const u8{
8116 ":4:29: error: out of bounds slice",8431 ":4:29: error: out of bounds slice",
8117 ":11:29: error: out of bounds slice",8432 ":12:29: error: out of bounds slice",
8118 ":18:29: error: out of bounds slice",8433 ":20:29: error: out of bounds slice",
8119 ":25:29: error: out of bounds slice",8434 ":28:29: error: out of bounds slice",
8120 ":32:29: error: out of bounds slice",8435 ":36:29: error: out of bounds slice",
8121 ":39:29: error: out of bounds slice",8436 ":44:29: error: out of bounds slice",
8122 ":46:29: error: out of bounds slice",8437 ":52:29: error: out of bounds slice",
8123 });8438 });
81248439
8125 cases.add("comptime slice-sentinel does not match memory at target index (unterminated)",8440 ctx.objErrStage1("comptime slice-sentinel does not match memory at target index (unterminated)",
8126 \\export fn foo_array() void {8441 \\export fn foo_array() void {
8127 \\ comptime {8442 \\ comptime {
8128 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8443 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8129 \\ const slice = target[0..3 :0];8444 \\ const slice = target[0..3 :0];
8445 \\ _ = slice;
8130 \\ }8446 \\ }
8131 \\}8447 \\}
8132 \\export fn foo_ptr_array() void {8448 \\export fn foo_ptr_array() void {
...@@ -8134,6 +8450,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8134,6 +8450,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8134 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8450 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8135 \\ var target = &buf;8451 \\ var target = &buf;
8136 \\ const slice = target[0..3 :0];8452 \\ const slice = target[0..3 :0];
8453 \\ _ = slice;
8137 \\ }8454 \\ }
8138 \\}8455 \\}
8139 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {8456 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
...@@ -8141,6 +8458,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8141,6 +8458,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8141 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8458 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8142 \\ var target: [*]u8 = &buf;8459 \\ var target: [*]u8 = &buf;
8143 \\ const slice = target[0..3 :0];8460 \\ const slice = target[0..3 :0];
8461 \\ _ = slice;
8144 \\ }8462 \\ }
8145 \\}8463 \\}
8146 \\export fn foo_vector_ConstPtrSpecialRef() void {8464 \\export fn foo_vector_ConstPtrSpecialRef() void {
...@@ -8148,6 +8466,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8148,6 +8466,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8148 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8466 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8149 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);8467 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
8150 \\ const slice = target[0..3 :0];8468 \\ const slice = target[0..3 :0];
8469 \\ _ = slice;
8151 \\ }8470 \\ }
8152 \\}8471 \\}
8153 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {8472 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
...@@ -8155,6 +8474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8155,6 +8474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8155 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8474 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8156 \\ var target: [*c]u8 = &buf;8475 \\ var target: [*c]u8 = &buf;
8157 \\ const slice = target[0..3 :0];8476 \\ const slice = target[0..3 :0];
8477 \\ _ = slice;
8158 \\ }8478 \\ }
8159 \\}8479 \\}
8160 \\export fn foo_cvector_ConstPtrSpecialRef() void {8480 \\export fn foo_cvector_ConstPtrSpecialRef() void {
...@@ -8162,6 +8482,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8162,6 +8482,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8162 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8482 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8163 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);8483 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
8164 \\ const slice = target[0..3 :0];8484 \\ const slice = target[0..3 :0];
8485 \\ _ = slice;
8165 \\ }8486 \\ }
8166 \\}8487 \\}
8167 \\export fn foo_slice() void {8488 \\export fn foo_slice() void {
...@@ -8169,23 +8490,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8169,23 +8490,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8169 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8490 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8170 \\ var target: []u8 = &buf;8491 \\ var target: []u8 = &buf;
8171 \\ const slice = target[0..3 :0];8492 \\ const slice = target[0..3 :0];
8493 \\ _ = slice;
8172 \\ }8494 \\ }
8173 \\}8495 \\}
8174 , &[_][]const u8{8496 , &[_][]const u8{
8175 ":4:29: error: slice-sentinel does not match memory at target index",8497 ":4:29: error: slice-sentinel does not match memory at target index",
8176 ":11:29: error: slice-sentinel does not match memory at target index",8498 ":12:29: error: slice-sentinel does not match memory at target index",
8177 ":18:29: error: slice-sentinel does not match memory at target index",8499 ":20:29: error: slice-sentinel does not match memory at target index",
8178 ":25:29: error: slice-sentinel does not match memory at target index",8500 ":28:29: error: slice-sentinel does not match memory at target index",
8179 ":32:29: error: slice-sentinel does not match memory at target index",8501 ":36:29: error: slice-sentinel does not match memory at target index",
8180 ":39:29: error: slice-sentinel does not match memory at target index",8502 ":44:29: error: slice-sentinel does not match memory at target index",
8181 ":46:29: error: slice-sentinel does not match memory at target index",8503 ":52:29: error: slice-sentinel does not match memory at target index",
8182 });8504 });
81838505
8184 cases.add("comptime slice-sentinel does not match memory at target index (terminated)",8506 ctx.objErrStage1("comptime slice-sentinel does not match memory at target index (terminated)",
8185 \\export fn foo_array() void {8507 \\export fn foo_array() void {
8186 \\ comptime {8508 \\ comptime {
8187 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8509 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8188 \\ const slice = target[0..3 :0];8510 \\ const slice = target[0..3 :0];
8511 \\ _ = slice;
8189 \\ }8512 \\ }
8190 \\}8513 \\}
8191 \\export fn foo_ptr_array() void {8514 \\export fn foo_ptr_array() void {
...@@ -8193,6 +8516,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8193,6 +8516,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8193 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8516 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8194 \\ var target = &buf;8517 \\ var target = &buf;
8195 \\ const slice = target[0..3 :0];8518 \\ const slice = target[0..3 :0];
8519 \\ _ = slice;
8196 \\ }8520 \\ }
8197 \\}8521 \\}
8198 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {8522 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
...@@ -8200,6 +8524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8200,6 +8524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8200 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8524 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8201 \\ var target: [*]u8 = &buf;8525 \\ var target: [*]u8 = &buf;
8202 \\ const slice = target[0..3 :0];8526 \\ const slice = target[0..3 :0];
8527 \\ _ = slice;
8203 \\ }8528 \\ }
8204 \\}8529 \\}
8205 \\export fn foo_vector_ConstPtrSpecialRef() void {8530 \\export fn foo_vector_ConstPtrSpecialRef() void {
...@@ -8207,6 +8532,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8207,6 +8532,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8207 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8532 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8208 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);8533 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
8209 \\ const slice = target[0..3 :0];8534 \\ const slice = target[0..3 :0];
8535 \\ _ = slice;
8210 \\ }8536 \\ }
8211 \\}8537 \\}
8212 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {8538 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
...@@ -8214,6 +8540,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8214,6 +8540,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8214 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8540 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8215 \\ var target: [*c]u8 = &buf;8541 \\ var target: [*c]u8 = &buf;
8216 \\ const slice = target[0..3 :0];8542 \\ const slice = target[0..3 :0];
8543 \\ _ = slice;
8217 \\ }8544 \\ }
8218 \\}8545 \\}
8219 \\export fn foo_cvector_ConstPtrSpecialRef() void {8546 \\export fn foo_cvector_ConstPtrSpecialRef() void {
...@@ -8221,6 +8548,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8221,6 +8548,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8221 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8548 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8222 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);8549 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
8223 \\ const slice = target[0..3 :0];8550 \\ const slice = target[0..3 :0];
8551 \\ _ = slice;
8224 \\ }8552 \\ }
8225 \\}8553 \\}
8226 \\export fn foo_slice() void {8554 \\export fn foo_slice() void {
...@@ -8228,23 +8556,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8228,23 +8556,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8228 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8556 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8229 \\ var target: []u8 = &buf;8557 \\ var target: []u8 = &buf;
8230 \\ const slice = target[0..3 :0];8558 \\ const slice = target[0..3 :0];
8559 \\ _ = slice;
8231 \\ }8560 \\ }
8232 \\}8561 \\}
8233 , &[_][]const u8{8562 , &[_][]const u8{
8234 ":4:29: error: slice-sentinel does not match memory at target index",8563 ":4:29: error: slice-sentinel does not match memory at target index",
8235 ":11:29: error: slice-sentinel does not match memory at target index",8564 ":12:29: error: slice-sentinel does not match memory at target index",
8236 ":18:29: error: slice-sentinel does not match memory at target index",8565 ":20:29: error: slice-sentinel does not match memory at target index",
8237 ":25:29: error: slice-sentinel does not match memory at target index",8566 ":28:29: error: slice-sentinel does not match memory at target index",
8238 ":32:29: error: slice-sentinel does not match memory at target index",8567 ":36:29: error: slice-sentinel does not match memory at target index",
8239 ":39:29: error: slice-sentinel does not match memory at target index",8568 ":44:29: error: slice-sentinel does not match memory at target index",
8240 ":46:29: error: slice-sentinel does not match memory at target index",8569 ":52:29: error: slice-sentinel does not match memory at target index",
8241 });8570 });
82428571
8243 cases.add("comptime slice-sentinel does not match target-sentinel",8572 ctx.objErrStage1("comptime slice-sentinel does not match target-sentinel",
8244 \\export fn foo_array() void {8573 \\export fn foo_array() void {
8245 \\ comptime {8574 \\ comptime {
8246 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8575 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8247 \\ const slice = target[0..14 :255];8576 \\ const slice = target[0..14 :255];
8577 \\ _ = slice;
8248 \\ }8578 \\ }
8249 \\}8579 \\}
8250 \\export fn foo_ptr_array() void {8580 \\export fn foo_ptr_array() void {
...@@ -8252,6 +8582,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8252,6 +8582,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8252 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8582 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8253 \\ var target = &buf;8583 \\ var target = &buf;
8254 \\ const slice = target[0..14 :255];8584 \\ const slice = target[0..14 :255];
8585 \\ _ = slice;
8255 \\ }8586 \\ }
8256 \\}8587 \\}
8257 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {8588 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
...@@ -8259,6 +8590,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8259,6 +8590,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8259 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8590 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8260 \\ var target: [*]u8 = &buf;8591 \\ var target: [*]u8 = &buf;
8261 \\ const slice = target[0..14 :255];8592 \\ const slice = target[0..14 :255];
8593 \\ _ = slice;
8262 \\ }8594 \\ }
8263 \\}8595 \\}
8264 \\export fn foo_vector_ConstPtrSpecialRef() void {8596 \\export fn foo_vector_ConstPtrSpecialRef() void {
...@@ -8266,6 +8598,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8266,6 +8598,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8266 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8598 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8267 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);8599 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
8268 \\ const slice = target[0..14 :255];8600 \\ const slice = target[0..14 :255];
8601 \\ _ = slice;
8269 \\ }8602 \\ }
8270 \\}8603 \\}
8271 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {8604 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
...@@ -8273,6 +8606,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8273,6 +8606,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8273 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8606 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8274 \\ var target: [*c]u8 = &buf;8607 \\ var target: [*c]u8 = &buf;
8275 \\ const slice = target[0..14 :255];8608 \\ const slice = target[0..14 :255];
8609 \\ _ = slice;
8276 \\ }8610 \\ }
8277 \\}8611 \\}
8278 \\export fn foo_cvector_ConstPtrSpecialRef() void {8612 \\export fn foo_cvector_ConstPtrSpecialRef() void {
...@@ -8280,6 +8614,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8280,6 +8614,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8280 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8614 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8281 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);8615 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
8282 \\ const slice = target[0..14 :255];8616 \\ const slice = target[0..14 :255];
8617 \\ _ = slice;
8283 \\ }8618 \\ }
8284 \\}8619 \\}
8285 \\export fn foo_slice() void {8620 \\export fn foo_slice() void {
...@@ -8287,19 +8622,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8287,19 +8622,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8287 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;8622 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
8288 \\ var target: []u8 = &buf;8623 \\ var target: []u8 = &buf;
8289 \\ const slice = target[0..14 :255];8624 \\ const slice = target[0..14 :255];
8625 \\ _ = slice;
8290 \\ }8626 \\ }
8291 \\}8627 \\}
8292 , &[_][]const u8{8628 , &[_][]const u8{
8293 ":4:29: error: slice-sentinel does not match target-sentinel",8629 ":4:29: error: slice-sentinel does not match target-sentinel",
8294 ":11:29: error: slice-sentinel does not match target-sentinel",8630 ":12:29: error: slice-sentinel does not match target-sentinel",
8295 ":18:29: error: slice-sentinel does not match target-sentinel",8631 ":20:29: error: slice-sentinel does not match target-sentinel",
8296 ":25:29: error: slice-sentinel does not match target-sentinel",8632 ":28:29: error: slice-sentinel does not match target-sentinel",
8297 ":32:29: error: slice-sentinel does not match target-sentinel",8633 ":36:29: error: slice-sentinel does not match target-sentinel",
8298 ":39:29: error: slice-sentinel does not match target-sentinel",8634 ":44:29: error: slice-sentinel does not match target-sentinel",
8299 ":46:29: error: slice-sentinel does not match target-sentinel",8635 ":52:29: error: slice-sentinel does not match target-sentinel",
8300 });8636 });
83018637
8302 cases.add("issue #4207: coerce from non-terminated-slice to terminated-pointer",8638 ctx.objErrStage1("issue #4207: coerce from non-terminated-slice to terminated-pointer",
8303 \\export fn foo() [*:0]const u8 {8639 \\export fn foo() [*:0]const u8 {
8304 \\ var buffer: [64]u8 = undefined;8640 \\ var buffer: [64]u8 = undefined;
8305 \\ return buffer[0..];8641 \\ return buffer[0..];
...@@ -8309,8 +8645,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8309,8 +8645,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8309 ":3:18: note: destination pointer requires a terminating '0' sentinel",8645 ":3:18: note: destination pointer requires a terminating '0' sentinel",
8310 });8646 });
83118647
8312 cases.add("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",8648 ctx.objErrStage1("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",
8313 \\fn ignore(comptime param: anytype) void {}8649 \\fn ignore(comptime param: anytype) void {_ = param;}
8314 \\8650 \\
8315 \\export fn foo() void {8651 \\export fn foo() void {
8316 \\ const MyStruct = struct {8652 \\ const MyStruct = struct {
...@@ -8323,7 +8659,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8323,7 +8659,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8323 ":5:28: error: expected type '[]u8', found '*const [3:0]u8'",8659 ":5:28: error: expected type '[]u8', found '*const [3:0]u8'",
8324 });8660 });
83258661
8326 cases.add("integer underflow error",8662 ctx.objErrStage1("integer underflow error",
8327 \\export fn entry() void {8663 \\export fn entry() void {
8328 \\ _ = @intToPtr(*c_void, ~@as(usize, @import("std").math.maxInt(usize)) - 1);8664 \\ _ = @intToPtr(*c_void, ~@as(usize, @import("std").math.maxInt(usize)) - 1);
8329 \\}8665 \\}
...@@ -8331,23 +8667,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8331,23 +8667,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8331 ":2:75: error: operation caused overflow",8667 ":2:75: error: operation caused overflow",
8332 });8668 });
83338669
8334 cases.addCase(x: {8670 {
8335 var tc = cases.create("align(N) expr function pointers is a compile error",8671 const case = ctx.obj("align(N) expr function pointers is a compile error", .{
8672 .cpu_arch = .wasm32,
8673 .os_tag = .freestanding,
8674 .abi = .none,
8675 });
8676 case.backend = .stage1;
8677
8678 case.addError(
8336 \\export fn foo() align(1) void {8679 \\export fn foo() align(1) void {
8337 \\ return;8680 \\ return;
8338 \\}8681 \\}
8339 , &[_][]const u8{8682 , &[_][]const u8{
8340 "tmp.zig:1:23: error: align(N) expr is not allowed on function prototypes in wasm32/wasm64",8683 "tmp.zig:1:23: error: align(N) expr is not allowed on function prototypes in wasm32/wasm64",
8341 });8684 });
8342 tc.target = std.zig.CrossTarget{8685 }
8343 .cpu_arch = .wasm32,
8344 .os_tag = .freestanding,
8345 .abi = .none,
8346 };
8347 break :x tc;
8348 });
83498686
8350 cases.add("compare optional to non-optional with invalid types",8687 ctx.objErrStage1("compare optional to non-optional with invalid types",
8351 \\export fn inconsistentChildType() void {8688 \\export fn inconsistentChildType() void {
8352 \\ var x: ?i32 = undefined;8689 \\ var x: ?i32 = undefined;
8353 \\ const y: comptime_int = 10;8690 \\ const y: comptime_int = 10;
...@@ -8381,16 +8718,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8381,16 +8718,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8381 ":22:12: note: operator not supported for type '[3]i32'",8718 ":22:12: note: operator not supported for type '[3]i32'",
8382 });8719 });
83838720
8384 cases.add("slice cannot have its bytes reinterpreted",8721 ctx.objErrStage1("slice cannot have its bytes reinterpreted",
8385 \\export fn foo() void {8722 \\export fn foo() void {
8386 \\ const bytes = [1]u8{ 0xfa } ** 16;8723 \\ const bytes = [1]u8{ 0xfa } ** 16;
8387 \\ var value = @ptrCast(*const []const u8, &bytes).*;8724 \\ var value = @ptrCast(*const []const u8, &bytes).*;
8725 \\ _ = value;
8388 \\}8726 \\}
8389 , &[_][]const u8{8727 , &[_][]const u8{
8390 ":3:52: error: slice '[]const u8' cannot have its bytes reinterpreted",8728 ":3:52: error: slice '[]const u8' cannot have its bytes reinterpreted",
8391 });8729 });
83928730
8393 cases.add("wasmMemorySize is a compile error in non-Wasm targets",8731 ctx.objErrStage1("wasmMemorySize is a compile error in non-Wasm targets",
8394 \\export fn foo() void {8732 \\export fn foo() void {
8395 \\ _ = @wasmMemorySize(0);8733 \\ _ = @wasmMemorySize(0);
8396 \\ return;8734 \\ return;
...@@ -8399,7 +8737,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8399,7 +8737,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8399 "tmp.zig:2:9: error: @wasmMemorySize is a wasm32 feature only",8737 "tmp.zig:2:9: error: @wasmMemorySize is a wasm32 feature only",
8400 });8738 });
84018739
8402 cases.add("wasmMemoryGrow is a compile error in non-Wasm targets",8740 ctx.objErrStage1("wasmMemoryGrow is a compile error in non-Wasm targets",
8403 \\export fn foo() void {8741 \\export fn foo() void {
8404 \\ _ = @wasmMemoryGrow(0, 1);8742 \\ _ = @wasmMemoryGrow(0, 1);
8405 \\ return;8743 \\ return;
...@@ -8407,7 +8745,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8407,7 +8745,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8407 , &[_][]const u8{8745 , &[_][]const u8{
8408 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",8746 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
8409 });8747 });
8410 cases.add("Issue #5586: Make unary minus for unsigned types a compile error",8748 ctx.objErrStage1("Issue #5586: Make unary minus for unsigned types a compile error",
8411 \\export fn f1(x: u32) u32 {8749 \\export fn f1(x: u32) u32 {
8412 \\ const y = -%x;8750 \\ const y = -%x;
8413 \\ return -y;8751 \\ return -y;
...@@ -8422,7 +8760,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8422,7 +8760,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8422 "tmp.zig:8:12: error: negation of type 'u32'",8760 "tmp.zig:8:12: error: negation of type 'u32'",
8423 });8761 });
84248762
8425 cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.",8763 ctx.objErrStage1("Issue #5618: coercion of ?*c_void to *c_void must fail.",
8426 \\export fn foo() void {8764 \\export fn foo() void {
8427 \\ var u: ?*c_void = null;8765 \\ var u: ?*c_void = null;
8428 \\ var v: *c_void = undefined;8766 \\ var v: *c_void = undefined;
...@@ -8432,15 +8770,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8432,15 +8770,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8432 "tmp.zig:4:9: error: expected type '*c_void', found '?*c_void'",8770 "tmp.zig:4:9: error: expected type '*c_void', found '?*c_void'",
8433 });8771 });
84348772
8435 cases.add("Issue #6823: don't allow .* to be followed by **",8773 ctx.objErrStage1("Issue #6823: don't allow .* to be followed by **",
8436 \\fn foo() void {8774 \\fn foo() void {
8437 \\ var sequence = "repeat".*** 10;8775 \\ var sequence = "repeat".*** 10;
8776 \\ _ = sequence;
8438 \\}8777 \\}
8439 , &[_][]const u8{8778 , &[_][]const u8{
8440 "tmp.zig:2:30: error: `.*` cannot be followed by `*`. Are you missing a space?",8779 // Ideally this would be column 30 but it's not very important.
8780 "tmp.zig:2:28: error: '.*' cannot be followed by '*'. Are you missing a space?",
8441 });8781 });
84428782
8443 cases.add("Issue #9165: windows tcp server compilation error",8783 ctx.objErrStage1("Issue #9165: windows tcp server compilation error",
8444 \\const std = @import("std");8784 \\const std = @import("std");
8445 \\pub const io_mode = .evented;8785 \\pub const io_mode = .evented;
8446 \\pub fn main() !void {8786 \\pub fn main() !void {
test/stage2/cbe.zig+7-6
...@@ -525,7 +525,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -525,7 +525,7 @@ pub fn addCases(ctx: *TestContext) !void {
525 \\}525 \\}
526 , &.{526 , &.{
527 ":3:21: error: missing struct field: x",527 ":3:21: error: missing struct field: x",
528 ":1:15: note: struct 'test_case.Point' declared here",528 ":1:15: note: struct 'tmp.Point' declared here",
529 });529 });
530 case.addError(530 case.addError(
531 \\const Point = struct { x: i32, y: i32 };531 \\const Point = struct { x: i32, y: i32 };
...@@ -538,7 +538,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -538,7 +538,7 @@ pub fn addCases(ctx: *TestContext) !void {
538 \\ return p.y - p.x - p.x;538 \\ return p.y - p.x - p.x;
539 \\}539 \\}
540 , &.{540 , &.{
541 ":6:10: error: no field named 'z' in struct 'test_case.Point'",541 ":6:10: error: no field named 'z' in struct 'tmp.Point'",
542 ":1:15: note: struct declared here",542 ":1:15: note: struct declared here",
543 });543 });
544 case.addCompareOutput(544 case.addCompareOutput(
...@@ -591,6 +591,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -591,6 +591,7 @@ pub fn addCases(ctx: *TestContext) !void {
591 , &.{591 , &.{
592 ":3:5: error: enum fields cannot be marked comptime",592 ":3:5: error: enum fields cannot be marked comptime",
593 ":8:8: error: enum fields do not have types",593 ":8:8: error: enum fields do not have types",
594 ":6:12: note: consider 'union(enum)' here to make it a tagged union",
594 });595 });
595596
596 // @enumToInt, @intToEnum, enum literal coercion, field access syntax, comparison, switch597 // @enumToInt, @intToEnum, enum literal coercion, field access syntax, comparison, switch
...@@ -716,7 +717,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -716,7 +717,7 @@ pub fn addCases(ctx: *TestContext) !void {
716 \\ _ = @intToEnum(E, 3);717 \\ _ = @intToEnum(E, 3);
717 \\}718 \\}
718 , &.{719 , &.{
719 ":3:9: error: enum 'test_case.E' has no tag with value 3",720 ":3:9: error: enum 'tmp.E' has no tag with value 3",
720 ":1:11: note: enum declared here",721 ":1:11: note: enum declared here",
721 });722 });
722723
...@@ -732,7 +733,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -732,7 +733,7 @@ pub fn addCases(ctx: *TestContext) !void {
732 , &.{733 , &.{
733 ":4:5: error: switch must handle all possibilities",734 ":4:5: error: switch must handle all possibilities",
734 ":4:5: note: unhandled enumeration value: 'b'",735 ":4:5: note: unhandled enumeration value: 'b'",
735 ":1:11: note: enum 'test_case.E' declared here",736 ":1:11: note: enum 'tmp.E' declared here",
736 });737 });
737738
738 case.addError(739 case.addError(
...@@ -787,7 +788,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -787,7 +788,7 @@ pub fn addCases(ctx: *TestContext) !void {
787 \\ _ = E.d;788 \\ _ = E.d;
788 \\}789 \\}
789 , &.{790 , &.{
790 ":3:10: error: enum 'test_case.E' has no member named 'd'",791 ":3:10: error: enum 'tmp.E' has no member named 'd'",
791 ":1:11: note: enum declared here",792 ":1:11: note: enum declared here",
792 });793 });
793794
...@@ -798,7 +799,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -798,7 +799,7 @@ pub fn addCases(ctx: *TestContext) !void {
798 \\ _ = x;799 \\ _ = x;
799 \\}800 \\}
800 , &.{801 , &.{
801 ":3:17: error: enum 'test_case.E' has no field named 'd'",802 ":3:17: error: enum 'tmp.E' has no field named 'd'",
802 ":1:11: note: enum declared here",803 ":1:11: note: enum declared here",
803 });804 });
804 }805 }
test/stage2/darwin.zig+1-1
...@@ -14,7 +14,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -14,7 +14,7 @@ pub fn addCases(ctx: *TestContext) !void {
14 {14 {
15 var case = ctx.exe("hello world with updates", target);15 var case = ctx.exe("hello world with updates", target);
16 case.addError("", &[_][]const u8{16 case.addError("", &[_][]const u8{
17 ":93:9: error: struct 'test_case.test_case' has no member named 'main'",17 ":93:9: error: struct 'tmp.tmp' has no member named 'main'",
18 });18 });
1919
20 // Incorrect return type20 // Incorrect return type
test/stage2/test.zig deleted-1626
...@@ -1,1626 +0,0 @@
1const std = @import("std");
2const TestContext = @import("../../src/test.zig").TestContext;
3
4// Self-hosted has differing levels of support for various architectures. For now we pass explicit
5// target parameters to each test case. At some point we will take this to the next level and have
6// a set of targets that all test cases run on unless specifically overridden. For now, each test
7// case applies to only the specified target.
8
9const linux_x64 = std.zig.CrossTarget{
10 .cpu_arch = .x86_64,
11 .os_tag = .linux,
12};
13
14pub fn addCases(ctx: *TestContext) !void {
15 try @import("cbe.zig").addCases(ctx);
16 try @import("arm.zig").addCases(ctx);
17 try @import("aarch64.zig").addCases(ctx);
18 try @import("llvm.zig").addCases(ctx);
19 try @import("wasm.zig").addCases(ctx);
20 try @import("darwin.zig").addCases(ctx);
21 try @import("riscv64.zig").addCases(ctx);
22
23 {
24 var case = ctx.exe("hello world with updates", linux_x64);
25
26 case.addError("", &[_][]const u8{
27 ":93:9: error: struct 'test_case.test_case' has no member named 'main'",
28 });
29
30 // Incorrect return type
31 case.addError(
32 \\pub export fn _start() noreturn {
33 \\}
34 , &[_][]const u8{":2:1: error: expected noreturn, found void"});
35
36 // Regular old hello world
37 case.addCompareOutput(
38 \\pub export fn _start() noreturn {
39 \\ print();
40 \\
41 \\ exit();
42 \\}
43 \\
44 \\fn print() void {
45 \\ asm volatile ("syscall"
46 \\ :
47 \\ : [number] "{rax}" (1),
48 \\ [arg1] "{rdi}" (1),
49 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
50 \\ [arg3] "{rdx}" (14)
51 \\ : "rcx", "r11", "memory"
52 \\ );
53 \\ return;
54 \\}
55 \\
56 \\fn exit() noreturn {
57 \\ asm volatile ("syscall"
58 \\ :
59 \\ : [number] "{rax}" (231),
60 \\ [arg1] "{rdi}" (0)
61 \\ : "rcx", "r11", "memory"
62 \\ );
63 \\ unreachable;
64 \\}
65 ,
66 "Hello, World!\n",
67 );
68
69 // Convert to pub fn main
70 case.addCompareOutput(
71 \\pub fn main() void {
72 \\ print();
73 \\}
74 \\
75 \\fn print() void {
76 \\ asm volatile ("syscall"
77 \\ :
78 \\ : [number] "{rax}" (1),
79 \\ [arg1] "{rdi}" (1),
80 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
81 \\ [arg3] "{rdx}" (14)
82 \\ : "rcx", "r11", "memory"
83 \\ );
84 \\ return;
85 \\}
86 ,
87 "Hello, World!\n",
88 );
89
90 // Now change the message only
91 case.addCompareOutput(
92 \\pub fn main() void {
93 \\ print();
94 \\}
95 \\
96 \\fn print() void {
97 \\ asm volatile ("syscall"
98 \\ :
99 \\ : [number] "{rax}" (1),
100 \\ [arg1] "{rdi}" (1),
101 \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")),
102 \\ [arg3] "{rdx}" (104)
103 \\ : "rcx", "r11", "memory"
104 \\ );
105 \\ return;
106 \\}
107 ,
108 "What is up? This is a longer message that will force the data to be relocated in virtual address space.\n",
109 );
110 // Now we print it twice.
111 case.addCompareOutput(
112 \\pub fn main() void {
113 \\ print();
114 \\ print();
115 \\}
116 \\
117 \\fn print() void {
118 \\ asm volatile ("syscall"
119 \\ :
120 \\ : [number] "{rax}" (1),
121 \\ [arg1] "{rdi}" (1),
122 \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")),
123 \\ [arg3] "{rdx}" (104)
124 \\ : "rcx", "r11", "memory"
125 \\ );
126 \\ return;
127 \\}
128 ,
129 \\What is up? This is a longer message that will force the data to be relocated in virtual address space.
130 \\What is up? This is a longer message that will force the data to be relocated in virtual address space.
131 \\
132 );
133 }
134
135 {
136 var case = ctx.exe("adding numbers at comptime", linux_x64);
137 case.addCompareOutput(
138 \\pub export fn _start() noreturn {
139 \\ asm volatile ("syscall"
140 \\ :
141 \\ : [number] "{rax}" (1),
142 \\ [arg1] "{rdi}" (1),
143 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
144 \\ [arg3] "{rdx}" (10 + 4)
145 \\ : "rcx", "r11", "memory"
146 \\ );
147 \\ asm volatile ("syscall"
148 \\ :
149 \\ : [number] "{rax}" (@as(usize, 230) + @as(usize, 1)),
150 \\ [arg1] "{rdi}" (0)
151 \\ : "rcx", "r11", "memory"
152 \\ );
153 \\ unreachable;
154 \\}
155 ,
156 "Hello, World!\n",
157 );
158 }
159
160 {
161 var case = ctx.exe("adding numbers at runtime and comptime", linux_x64);
162 case.addCompareOutput(
163 \\pub export fn _start() noreturn {
164 \\ add(3, 4);
165 \\
166 \\ exit();
167 \\}
168 \\
169 \\fn add(a: u32, b: u32) void {
170 \\ if (a + b != 7) unreachable;
171 \\}
172 \\
173 \\fn exit() noreturn {
174 \\ asm volatile ("syscall"
175 \\ :
176 \\ : [number] "{rax}" (231),
177 \\ [arg1] "{rdi}" (0)
178 \\ : "rcx", "r11", "memory"
179 \\ );
180 \\ unreachable;
181 \\}
182 ,
183 "",
184 );
185 // comptime function call
186 case.addCompareOutput(
187 \\pub export fn _start() noreturn {
188 \\ exit();
189 \\}
190 \\
191 \\fn add(a: u32, b: u32) u32 {
192 \\ return a + b;
193 \\}
194 \\
195 \\const x = add(3, 4);
196 \\
197 \\fn exit() noreturn {
198 \\ asm volatile ("syscall"
199 \\ :
200 \\ : [number] "{rax}" (231),
201 \\ [arg1] "{rdi}" (x - 7)
202 \\ : "rcx", "r11", "memory"
203 \\ );
204 \\ unreachable;
205 \\}
206 ,
207 "",
208 );
209 // Inline function call
210 case.addCompareOutput(
211 \\pub export fn _start() noreturn {
212 \\ var x: usize = 3;
213 \\ const y = add(1, 2, x);
214 \\ exit(y - 6);
215 \\}
216 \\
217 \\fn add(a: usize, b: usize, c: usize) callconv(.Inline) usize {
218 \\ return a + b + c;
219 \\}
220 \\
221 \\fn exit(code: usize) noreturn {
222 \\ asm volatile ("syscall"
223 \\ :
224 \\ : [number] "{rax}" (231),
225 \\ [arg1] "{rdi}" (code)
226 \\ : "rcx", "r11", "memory"
227 \\ );
228 \\ unreachable;
229 \\}
230 ,
231 "",
232 );
233 }
234
235 {
236 var case = ctx.exe("subtracting numbers at runtime", linux_x64);
237 case.addCompareOutput(
238 \\pub fn main() void {
239 \\ sub(7, 4);
240 \\}
241 \\
242 \\fn sub(a: u32, b: u32) void {
243 \\ if (a - b != 3) unreachable;
244 \\}
245 ,
246 "",
247 );
248 }
249 {
250 var case = ctx.exe("unused vars", linux_x64);
251 case.addError(
252 \\pub fn main() void {
253 \\ const x = 1;
254 \\}
255 , &.{":2:11: error: unused local constant"});
256 }
257 {
258 var case = ctx.exe("@TypeOf", linux_x64);
259 case.addCompareOutput(
260 \\pub fn main() void {
261 \\ var x: usize = 0;
262 \\ _ = x;
263 \\ const z = @TypeOf(x, @as(u128, 5));
264 \\ assert(z == u128);
265 \\}
266 \\
267 \\pub fn assert(ok: bool) void {
268 \\ if (!ok) unreachable; // assertion failure
269 \\}
270 ,
271 "",
272 );
273 case.addCompareOutput(
274 \\pub fn main() void {
275 \\ const z = @TypeOf(true);
276 \\ assert(z == bool);
277 \\}
278 \\
279 \\pub fn assert(ok: bool) void {
280 \\ if (!ok) unreachable; // assertion failure
281 \\}
282 ,
283 "",
284 );
285 case.addError(
286 \\pub fn main() void {
287 \\ _ = @TypeOf(true, 1);
288 \\}
289 , &[_][]const u8{":2:9: error: incompatible types: 'bool' and 'comptime_int'"});
290 }
291
292 {
293 var case = ctx.exe("multiplying numbers at runtime and comptime", linux_x64);
294 case.addCompareOutput(
295 \\pub export fn _start() noreturn {
296 \\ mul(3, 4);
297 \\
298 \\ exit();
299 \\}
300 \\
301 \\fn mul(a: u32, b: u32) void {
302 \\ if (a * b != 12) unreachable;
303 \\}
304 \\
305 \\fn exit() noreturn {
306 \\ asm volatile ("syscall"
307 \\ :
308 \\ : [number] "{rax}" (231),
309 \\ [arg1] "{rdi}" (0)
310 \\ : "rcx", "r11", "memory"
311 \\ );
312 \\ unreachable;
313 \\}
314 ,
315 "",
316 );
317 // comptime function call
318 case.addCompareOutput(
319 \\pub fn _start() noreturn {
320 \\ exit();
321 \\}
322 \\
323 \\fn mul(a: u32, b: u32) u32 {
324 \\ return a * b;
325 \\}
326 \\
327 \\const x = mul(3, 4);
328 \\
329 \\fn exit() noreturn {
330 \\ asm volatile ("syscall"
331 \\ :
332 \\ : [number] "{rax}" (231),
333 \\ [arg1] "{rdi}" (x - 12)
334 \\ : "rcx", "r11", "memory"
335 \\ );
336 \\ unreachable;
337 \\}
338 ,
339 "",
340 );
341 // Inline function call
342 case.addCompareOutput(
343 \\pub export fn _start() noreturn {
344 \\ var x: usize = 5;
345 \\ const y = mul(2, 3, x);
346 \\ exit(y - 30);
347 \\}
348 \\
349 \\fn mul(a: usize, b: usize, c: usize) callconv(.Inline) usize {
350 \\ return a * b * c;
351 \\}
352 \\
353 \\fn exit(code: usize) noreturn {
354 \\ asm volatile ("syscall"
355 \\ :
356 \\ : [number] "{rax}" (231),
357 \\ [arg1] "{rdi}" (code)
358 \\ : "rcx", "r11", "memory"
359 \\ );
360 \\ unreachable;
361 \\}
362 ,
363 "",
364 );
365 }
366
367 {
368 var case = ctx.exe("assert function", linux_x64);
369 case.addCompareOutput(
370 \\pub fn main() void {
371 \\ add(3, 4);
372 \\}
373 \\
374 \\fn add(a: u32, b: u32) void {
375 \\ assert(a + b == 7);
376 \\}
377 \\
378 \\pub fn assert(ok: bool) void {
379 \\ if (!ok) unreachable; // assertion failure
380 \\}
381 \\
382 \\fn exit() noreturn {
383 \\ asm volatile ("syscall"
384 \\ :
385 \\ : [number] "{rax}" (231),
386 \\ [arg1] "{rdi}" (0)
387 \\ : "rcx", "r11", "memory"
388 \\ );
389 \\ unreachable;
390 \\}
391 ,
392 "",
393 );
394
395 // Tests copying a register. For the `c = a + b`, it has to
396 // preserve both a and b, because they are both used later.
397 case.addCompareOutput(
398 \\pub fn main() void {
399 \\ add(3, 4);
400 \\}
401 \\
402 \\fn add(a: u32, b: u32) void {
403 \\ const c = a + b; // 7
404 \\ const d = a + c; // 10
405 \\ const e = d + b; // 14
406 \\ assert(e == 14);
407 \\}
408 \\
409 \\pub fn assert(ok: bool) void {
410 \\ if (!ok) unreachable; // assertion failure
411 \\}
412 ,
413 "",
414 );
415
416 // More stress on the liveness detection.
417 case.addCompareOutput(
418 \\pub fn main() void {
419 \\ add(3, 4);
420 \\}
421 \\
422 \\fn add(a: u32, b: u32) void {
423 \\ const c = a + b; // 7
424 \\ const d = a + c; // 10
425 \\ const e = d + b; // 14
426 \\ const f = d + e; // 24
427 \\ const g = e + f; // 38
428 \\ const h = f + g; // 62
429 \\ const i = g + h; // 100
430 \\ assert(i == 100);
431 \\}
432 \\
433 \\pub fn assert(ok: bool) void {
434 \\ if (!ok) unreachable; // assertion failure
435 \\}
436 ,
437 "",
438 );
439
440 // Requires a second move. The register allocator should figure out to re-use rax.
441 case.addCompareOutput(
442 \\pub fn main() void {
443 \\ add(3, 4);
444 \\}
445 \\
446 \\fn add(a: u32, b: u32) void {
447 \\ const c = a + b; // 7
448 \\ const d = a + c; // 10
449 \\ const e = d + b; // 14
450 \\ const f = d + e; // 24
451 \\ const g = e + f; // 38
452 \\ const h = f + g; // 62
453 \\ const i = g + h; // 100
454 \\ const j = i + d; // 110
455 \\ assert(j == 110);
456 \\}
457 \\
458 \\pub fn assert(ok: bool) void {
459 \\ if (!ok) unreachable; // assertion failure
460 \\}
461 ,
462 "",
463 );
464
465 // Now we test integer return values.
466 case.addCompareOutput(
467 \\pub fn main() void {
468 \\ assert(add(3, 4) == 7);
469 \\ assert(add(20, 10) == 30);
470 \\}
471 \\
472 \\fn add(a: u32, b: u32) u32 {
473 \\ return a + b;
474 \\}
475 \\
476 \\pub fn assert(ok: bool) void {
477 \\ if (!ok) unreachable; // assertion failure
478 \\}
479 ,
480 "",
481 );
482
483 // Local mutable variables.
484 case.addCompareOutput(
485 \\pub fn main() void {
486 \\ assert(add(3, 4) == 7);
487 \\ assert(add(20, 10) == 30);
488 \\}
489 \\
490 \\fn add(a: u32, b: u32) u32 {
491 \\ var x: u32 = undefined;
492 \\ x = 0;
493 \\ x += a;
494 \\ x += b;
495 \\ return x;
496 \\}
497 \\
498 \\pub fn assert(ok: bool) void {
499 \\ if (!ok) unreachable; // assertion failure
500 \\}
501 ,
502 "",
503 );
504
505 // Optionals
506 case.addCompareOutput(
507 \\pub fn main() void {
508 \\ const a: u32 = 2;
509 \\ const b: ?u32 = a;
510 \\ const c = b.?;
511 \\ if (c != 2) unreachable;
512 \\}
513 ,
514 "",
515 );
516
517 // While loops
518 case.addCompareOutput(
519 \\pub fn main() void {
520 \\ var i: u32 = 0;
521 \\ while (i < 4) : (i += 1) print();
522 \\ assert(i == 4);
523 \\}
524 \\
525 \\fn print() void {
526 \\ asm volatile ("syscall"
527 \\ :
528 \\ : [number] "{rax}" (1),
529 \\ [arg1] "{rdi}" (1),
530 \\ [arg2] "{rsi}" (@ptrToInt("hello\n")),
531 \\ [arg3] "{rdx}" (6)
532 \\ : "rcx", "r11", "memory"
533 \\ );
534 \\ return;
535 \\}
536 \\
537 \\pub fn assert(ok: bool) void {
538 \\ if (!ok) unreachable; // assertion failure
539 \\}
540 ,
541 "hello\nhello\nhello\nhello\n",
542 );
543
544 // inline while requires the condition to be comptime known.
545 case.addError(
546 \\pub fn main() void {
547 \\ var i: u32 = 0;
548 \\ inline while (i < 4) : (i += 1) print();
549 \\ assert(i == 4);
550 \\}
551 \\
552 \\fn print() void {
553 \\ asm volatile ("syscall"
554 \\ :
555 \\ : [number] "{rax}" (1),
556 \\ [arg1] "{rdi}" (1),
557 \\ [arg2] "{rsi}" (@ptrToInt("hello\n")),
558 \\ [arg3] "{rdx}" (6)
559 \\ : "rcx", "r11", "memory"
560 \\ );
561 \\ return;
562 \\}
563 \\
564 \\pub fn assert(ok: bool) void {
565 \\ if (!ok) unreachable; // assertion failure
566 \\}
567 , &[_][]const u8{":3:21: error: unable to resolve comptime value"});
568
569 // Labeled blocks (no conditional branch)
570 case.addCompareOutput(
571 \\pub fn main() void {
572 \\ assert(add(3, 4) == 20);
573 \\}
574 \\
575 \\fn add(a: u32, b: u32) u32 {
576 \\ const x: u32 = blk: {
577 \\ const c = a + b; // 7
578 \\ const d = a + c; // 10
579 \\ const e = d + b; // 14
580 \\ break :blk e;
581 \\ };
582 \\ const y = x + a; // 17
583 \\ const z = y + a; // 20
584 \\ return z;
585 \\}
586 \\
587 \\pub fn assert(ok: bool) void {
588 \\ if (!ok) unreachable; // assertion failure
589 \\}
590 ,
591 "",
592 );
593
594 // This catches a possible bug in the logic for re-using dying operands.
595 case.addCompareOutput(
596 \\pub fn main() void {
597 \\ assert(add(3, 4) == 116);
598 \\}
599 \\
600 \\fn add(a: u32, b: u32) u32 {
601 \\ const x: u32 = blk: {
602 \\ const c = a + b; // 7
603 \\ const d = a + c; // 10
604 \\ const e = d + b; // 14
605 \\ const f = d + e; // 24
606 \\ const g = e + f; // 38
607 \\ const h = f + g; // 62
608 \\ const i = g + h; // 100
609 \\ const j = i + d; // 110
610 \\ break :blk j;
611 \\ };
612 \\ const y = x + a; // 113
613 \\ const z = y + a; // 116
614 \\ return z;
615 \\}
616 \\
617 \\pub fn assert(ok: bool) void {
618 \\ if (!ok) unreachable; // assertion failure
619 \\}
620 ,
621 "",
622 );
623
624 // Spilling registers to the stack.
625 case.addCompareOutput(
626 \\pub fn main() void {
627 \\ assert(add(3, 4) == 1221);
628 \\ assert(mul(3, 4) == 21609);
629 \\}
630 \\
631 \\fn add(a: u32, b: u32) u32 {
632 \\ const x: u32 = blk: {
633 \\ const c = a + b; // 7
634 \\ const d = a + c; // 10
635 \\ const e = d + b; // 14
636 \\ const f = d + e; // 24
637 \\ const g = e + f; // 38
638 \\ const h = f + g; // 62
639 \\ const i = g + h; // 100
640 \\ const j = i + d; // 110
641 \\ const k = i + j; // 210
642 \\ const l = j + k; // 320
643 \\ const m = l + c; // 327
644 \\ const n = m + d; // 337
645 \\ const o = n + e; // 351
646 \\ const p = o + f; // 375
647 \\ const q = p + g; // 413
648 \\ const r = q + h; // 475
649 \\ const s = r + i; // 575
650 \\ const t = s + j; // 685
651 \\ const u = t + k; // 895
652 \\ const v = u + l; // 1215
653 \\ break :blk v;
654 \\ };
655 \\ const y = x + a; // 1218
656 \\ const z = y + a; // 1221
657 \\ return z;
658 \\}
659 \\
660 \\fn mul(a: u32, b: u32) u32 {
661 \\ const x: u32 = blk: {
662 \\ const c = a * a * a * a; // 81
663 \\ const d = a * a * a * b; // 108
664 \\ const e = a * a * b * a; // 108
665 \\ const f = a * a * b * b; // 144
666 \\ const g = a * b * a * a; // 108
667 \\ const h = a * b * a * b; // 144
668 \\ const i = a * b * b * a; // 144
669 \\ const j = a * b * b * b; // 192
670 \\ const k = b * a * a * a; // 108
671 \\ const l = b * a * a * b; // 144
672 \\ const m = b * a * b * a; // 144
673 \\ const n = b * a * b * b; // 192
674 \\ const o = b * b * a * a; // 144
675 \\ const p = b * b * a * b; // 192
676 \\ const q = b * b * b * a; // 192
677 \\ const r = b * b * b * b; // 256
678 \\ const s = c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r; // 2401
679 \\ break :blk s;
680 \\ };
681 \\ const y = x * a; // 7203
682 \\ const z = y * a; // 21609
683 \\ return z;
684 \\}
685 \\
686 \\pub fn assert(ok: bool) void {
687 \\ if (!ok) unreachable; // assertion failure
688 \\}
689 ,
690 "",
691 );
692
693 // Reusing the registers of dead operands playing nicely with conditional branching.
694 case.addCompareOutput(
695 \\pub fn main() void {
696 \\ assert(add(3, 4) == 791);
697 \\ assert(add(4, 3) == 79);
698 \\}
699 \\
700 \\fn add(a: u32, b: u32) u32 {
701 \\ const x: u32 = if (a < b) blk: {
702 \\ const c = a + b; // 7
703 \\ const d = a + c; // 10
704 \\ const e = d + b; // 14
705 \\ const f = d + e; // 24
706 \\ const g = e + f; // 38
707 \\ const h = f + g; // 62
708 \\ const i = g + h; // 100
709 \\ const j = i + d; // 110
710 \\ const k = i + j; // 210
711 \\ const l = k + c; // 217
712 \\ const m = l + d; // 227
713 \\ const n = m + e; // 241
714 \\ const o = n + f; // 265
715 \\ const p = o + g; // 303
716 \\ const q = p + h; // 365
717 \\ const r = q + i; // 465
718 \\ const s = r + j; // 575
719 \\ const t = s + k; // 785
720 \\ break :blk t;
721 \\ } else blk: {
722 \\ const t = b + b + a; // 10
723 \\ const c = a + t; // 14
724 \\ const d = c + t; // 24
725 \\ const e = d + t; // 34
726 \\ const f = e + t; // 44
727 \\ const g = f + t; // 54
728 \\ const h = c + g; // 68
729 \\ break :blk h + b; // 71
730 \\ };
731 \\ const y = x + a; // 788, 75
732 \\ const z = y + a; // 791, 79
733 \\ return z;
734 \\}
735 \\
736 \\pub fn assert(ok: bool) void {
737 \\ if (!ok) unreachable; // assertion failure
738 \\}
739 ,
740 "",
741 );
742
743 // Character literals and multiline strings.
744 case.addCompareOutput(
745 \\pub fn main() void {
746 \\ const ignore =
747 \\ \\ cool thx
748 \\ \\
749 \\ ;
750 \\ _ = ignore;
751 \\ add('ぁ', '\x03');
752 \\}
753 \\
754 \\fn add(a: u32, b: u32) void {
755 \\ assert(a + b == 12356);
756 \\}
757 \\
758 \\pub fn assert(ok: bool) void {
759 \\ if (!ok) unreachable; // assertion failure
760 \\}
761 ,
762 "",
763 );
764
765 // Global const.
766 case.addCompareOutput(
767 \\pub fn main() void {
768 \\ add(aa, bb);
769 \\}
770 \\
771 \\const aa = 'ぁ';
772 \\const bb = '\x03';
773 \\
774 \\fn add(a: u32, b: u32) void {
775 \\ assert(a + b == 12356);
776 \\}
777 \\
778 \\pub fn assert(ok: bool) void {
779 \\ if (!ok) unreachable; // assertion failure
780 \\}
781 ,
782 "",
783 );
784
785 // Array access.
786 case.addCompareOutput(
787 \\pub fn main() void {
788 \\ assert("hello"[0] == 'h');
789 \\}
790 \\
791 \\pub fn assert(ok: bool) void {
792 \\ if (!ok) unreachable; // assertion failure
793 \\}
794 ,
795 "",
796 );
797
798 // Array access to a global array.
799 case.addCompareOutput(
800 \\const hello = "hello".*;
801 \\pub fn main() void {
802 \\ assert(hello[1] == 'e');
803 \\}
804 \\
805 \\pub fn assert(ok: bool) void {
806 \\ if (!ok) unreachable; // assertion failure
807 \\}
808 ,
809 "",
810 );
811
812 // 64bit set stack
813 case.addCompareOutput(
814 \\pub fn main() void {
815 \\ var i: u64 = 0xFFEEDDCCBBAA9988;
816 \\ assert(i == 0xFFEEDDCCBBAA9988);
817 \\}
818 \\
819 \\pub fn assert(ok: bool) void {
820 \\ if (!ok) unreachable; // assertion failure
821 \\}
822 ,
823 "",
824 );
825
826 // Basic for loop
827 case.addCompareOutput(
828 \\pub fn main() void {
829 \\ for ("hello") |_| print();
830 \\}
831 \\
832 \\fn print() void {
833 \\ asm volatile ("syscall"
834 \\ :
835 \\ : [number] "{rax}" (1),
836 \\ [arg1] "{rdi}" (1),
837 \\ [arg2] "{rsi}" (@ptrToInt("hello\n")),
838 \\ [arg3] "{rdx}" (6)
839 \\ : "rcx", "r11", "memory"
840 \\ );
841 \\ return;
842 \\}
843 ,
844 "hello\nhello\nhello\nhello\nhello\n",
845 );
846 }
847
848 {
849 var case = ctx.exe("basic import", linux_x64);
850 case.addCompareOutput(
851 \\pub fn main() void {
852 \\ @import("print.zig").print();
853 \\}
854 ,
855 "Hello, World!\n",
856 );
857 try case.files.append(.{
858 .src =
859 \\pub fn print() void {
860 \\ asm volatile ("syscall"
861 \\ :
862 \\ : [number] "{rax}" (@as(usize, 1)),
863 \\ [arg1] "{rdi}" (@as(usize, 1)),
864 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
865 \\ [arg3] "{rdx}" (@as(usize, 14))
866 \\ : "rcx", "r11", "memory"
867 \\ );
868 \\ return;
869 \\}
870 ,
871 .path = "print.zig",
872 });
873 }
874 {
875 var case = ctx.exe("redundant comptime", linux_x64);
876 case.addError(
877 \\pub fn main() void {
878 \\ var a: comptime u32 = 0;
879 \\}
880 ,
881 &.{":2:12: error: redundant comptime keyword in already comptime scope"},
882 );
883 case.addError(
884 \\pub fn main() void {
885 \\ comptime {
886 \\ var a: u32 = comptime 0;
887 \\ }
888 \\}
889 ,
890 &.{":3:22: error: redundant comptime keyword in already comptime scope"},
891 );
892 }
893 {
894 var case = ctx.exe("try in comptime in struct in test", linux_x64);
895 case.addError(
896 \\test "@unionInit on union w/ tag but no fields" {
897 \\ const S = struct {
898 \\ comptime {
899 \\ try expect(false);
900 \\ }
901 \\ };
902 \\ _ = S;
903 \\}
904 ,
905 &.{":4:13: error: invalid 'try' outside function scope"},
906 );
907 }
908 {
909 var case = ctx.exe("import private", linux_x64);
910 case.addError(
911 \\pub fn main() void {
912 \\ @import("print.zig").print();
913 \\}
914 ,
915 &.{
916 ":2:25: error: 'print' is not marked 'pub'",
917 "print.zig:2:1: note: declared here",
918 },
919 );
920 try case.files.append(.{
921 .src =
922 \\// dummy comment to make print be on line 2
923 \\fn print() void {
924 \\ asm volatile ("syscall"
925 \\ :
926 \\ : [number] "{rax}" (@as(usize, 1)),
927 \\ [arg1] "{rdi}" (@as(usize, 1)),
928 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
929 \\ [arg3] "{rdx}" (@as(usize, 14))
930 \\ : "rcx", "r11", "memory"
931 \\ );
932 \\ return;
933 \\}
934 ,
935 .path = "print.zig",
936 });
937 }
938
939 ctx.compileError("function redeclaration", linux_x64,
940 \\// dummy comment
941 \\fn entry() void {}
942 \\fn entry() void {}
943 \\
944 \\fn foo() void {
945 \\ var foo = 1234;
946 \\}
947 , &[_][]const u8{
948 ":3:1: error: redeclaration of 'entry'",
949 ":2:1: note: other declaration here",
950 ":6:9: error: local shadows declaration of 'foo'",
951 ":5:1: note: declared here",
952 });
953
954 ctx.compileError("returns in try", linux_x64,
955 \\pub fn main() !void {
956 \\ try a();
957 \\ try b();
958 \\}
959 \\
960 \\pub fn a() !void {
961 \\ defer try b();
962 \\}
963 \\pub fn b() !void {
964 \\ defer return a();
965 \\}
966 , &[_][]const u8{
967 ":7:8: error: try is not allowed inside defer expression",
968 ":10:8: error: cannot return from defer expression",
969 });
970
971 ctx.compileError("ambiguous references", linux_x64,
972 \\const T = struct {
973 \\ const T = struct {
974 \\ fn f() void {
975 \\ _ = T;
976 \\ }
977 \\ };
978 \\};
979 , &.{
980 ":4:17: error: ambiguous reference",
981 ":1:1: note: declared here",
982 ":2:5: note: also declared here",
983 });
984
985 ctx.compileError("inner func accessing outer var", linux_x64,
986 \\pub fn f() void {
987 \\ var bar: bool = true;
988 \\ const S = struct {
989 \\ fn baz() bool {
990 \\ return bar;
991 \\ }
992 \\ };
993 \\ _ = S;
994 \\}
995 , &.{
996 ":5:20: error: 'bar' not accessible from inner function",
997 ":2:9: note: declared here",
998 });
999
1000 ctx.compileError("global variable redeclaration", linux_x64,
1001 \\// dummy comment
1002 \\var foo = false;
1003 \\var foo = true;
1004 , &[_][]const u8{
1005 ":3:1: error: redeclaration of 'foo'",
1006 ":2:1: note: other declaration here",
1007 });
1008
1009 ctx.compileError("compileError", linux_x64,
1010 \\export fn foo() void {
1011 \\ @compileError("this is an error");
1012 \\}
1013 , &[_][]const u8{":2:3: error: this is an error"});
1014
1015 {
1016 var case = ctx.exe("intToPtr", linux_x64);
1017 case.addError(
1018 \\pub fn main() void {
1019 \\ _ = @intToPtr(*u8, 0);
1020 \\}
1021 , &[_][]const u8{
1022 ":2:24: error: pointer type '*u8' does not allow address zero",
1023 });
1024 case.addError(
1025 \\pub fn main() void {
1026 \\ _ = @intToPtr(*u32, 2);
1027 \\}
1028 , &[_][]const u8{
1029 ":2:25: error: pointer type '*u32' requires aligned address",
1030 });
1031 }
1032
1033 {
1034 var case = ctx.obj("variable shadowing", linux_x64);
1035 case.addError(
1036 \\pub fn main() void {
1037 \\ var i: u32 = 10;
1038 \\ var i: u32 = 10;
1039 \\}
1040 , &[_][]const u8{
1041 ":3:9: error: redeclaration of 'i'",
1042 ":2:9: note: previously declared here",
1043 });
1044 case.addError(
1045 \\var testing: i64 = 10;
1046 \\pub fn main() void {
1047 \\ var testing: i64 = 20;
1048 \\}
1049 , &[_][]const u8{
1050 ":3:9: error: local shadows declaration of 'testing'",
1051 ":1:1: note: declared here",
1052 });
1053 case.addError(
1054 \\fn a() type {
1055 \\ return struct {
1056 \\ pub fn b() void {
1057 \\ const c = 6;
1058 \\ const c = 69;
1059 \\ }
1060 \\ };
1061 \\}
1062 , &[_][]const u8{
1063 ":5:19: error: redeclaration of 'c'",
1064 ":4:19: note: previously declared here",
1065 });
1066 }
1067
1068 {
1069 // TODO make the test harness support checking the compile log output too
1070 var case = ctx.obj("@compileLog", linux_x64);
1071 // The other compile error prevents emission of a "found compile log" statement.
1072 case.addError(
1073 \\export fn _start() noreturn {
1074 \\ const b = true;
1075 \\ var f: u32 = 1;
1076 \\ @compileLog(b, 20, f, x);
1077 \\ @compileLog(1000);
1078 \\ var bruh: usize = true;
1079 \\ _ = bruh;
1080 \\ unreachable;
1081 \\}
1082 \\export fn other() void {
1083 \\ @compileLog(1234);
1084 \\}
1085 \\fn x() void {}
1086 , &[_][]const u8{
1087 ":6:23: error: expected usize, found bool",
1088 });
1089
1090 // Now only compile log statements remain. One per Decl.
1091 case.addError(
1092 \\export fn _start() noreturn {
1093 \\ const b = true;
1094 \\ var f: u32 = 1;
1095 \\ @compileLog(b, 20, f, x);
1096 \\ @compileLog(1000);
1097 \\ unreachable;
1098 \\}
1099 \\export fn other() void {
1100 \\ @compileLog(1234);
1101 \\}
1102 \\fn x() void {}
1103 , &[_][]const u8{
1104 ":9:5: error: found compile log statement",
1105 ":4:5: note: also here",
1106 });
1107 }
1108
1109 {
1110 var case = ctx.obj("extern variable has no type", linux_x64);
1111 case.addError(
1112 \\comptime {
1113 \\ _ = foo;
1114 \\}
1115 \\extern var foo: i32;
1116 , &[_][]const u8{":2:9: error: unable to resolve comptime value"});
1117 case.addError(
1118 \\export fn entry() void {
1119 \\ _ = foo;
1120 \\}
1121 \\extern var foo;
1122 , &[_][]const u8{":4:8: error: unable to infer variable type"});
1123 }
1124
1125 {
1126 var case = ctx.exe("break/continue", linux_x64);
1127
1128 // Break out of loop
1129 case.addCompareOutput(
1130 \\pub fn main() void {
1131 \\ while (true) {
1132 \\ break;
1133 \\ }
1134 \\}
1135 ,
1136 "",
1137 );
1138 case.addCompareOutput(
1139 \\pub fn main() void {
1140 \\ foo: while (true) {
1141 \\ break :foo;
1142 \\ }
1143 \\}
1144 ,
1145 "",
1146 );
1147
1148 // Continue in loop
1149 case.addCompareOutput(
1150 \\pub export fn _start() noreturn {
1151 \\ var i: u64 = 0;
1152 \\ while (true) : (i+=1) {
1153 \\ if (i == 4) exit();
1154 \\ continue;
1155 \\ }
1156 \\}
1157 \\
1158 \\fn exit() noreturn {
1159 \\ asm volatile ("syscall"
1160 \\ :
1161 \\ : [number] "{rax}" (231),
1162 \\ [arg1] "{rdi}" (0)
1163 \\ : "rcx", "r11", "memory"
1164 \\ );
1165 \\ unreachable;
1166 \\}
1167 ,
1168 "",
1169 );
1170 case.addCompareOutput(
1171 \\pub export fn _start() noreturn {
1172 \\ var i: u64 = 0;
1173 \\ foo: while (true) : (i+=1) {
1174 \\ if (i == 4) exit();
1175 \\ continue :foo;
1176 \\ }
1177 \\}
1178 \\
1179 \\fn exit() noreturn {
1180 \\ asm volatile ("syscall"
1181 \\ :
1182 \\ : [number] "{rax}" (231),
1183 \\ [arg1] "{rdi}" (0)
1184 \\ : "rcx", "r11", "memory"
1185 \\ );
1186 \\ unreachable;
1187 \\}
1188 ,
1189 "",
1190 );
1191 }
1192
1193 {
1194 var case = ctx.exe("unused labels", linux_x64);
1195 case.addError(
1196 \\comptime {
1197 \\ foo: {}
1198 \\}
1199 , &[_][]const u8{":2:5: error: unused block label"});
1200 case.addError(
1201 \\comptime {
1202 \\ foo: while (true) {}
1203 \\}
1204 , &[_][]const u8{":2:5: error: unused while loop label"});
1205 case.addError(
1206 \\comptime {
1207 \\ foo: for ("foo") |_| {}
1208 \\}
1209 , &[_][]const u8{":2:5: error: unused for loop label"});
1210 case.addError(
1211 \\comptime {
1212 \\ blk: {blk: {}}
1213 \\}
1214 , &[_][]const u8{
1215 ":2:11: error: redefinition of label 'blk'",
1216 ":2:5: note: previous definition is here",
1217 });
1218 }
1219
1220 {
1221 var case = ctx.exe("bad inferred variable type", linux_x64);
1222 case.addError(
1223 \\pub fn main() void {
1224 \\ var x = null;
1225 \\ _ = x;
1226 \\}
1227 , &[_][]const u8{
1228 ":2:9: error: variable of type '@Type(.Null)' must be const or comptime",
1229 });
1230 }
1231
1232 {
1233 var case = ctx.exe("compile error in inline fn call fixed", linux_x64);
1234 case.addError(
1235 \\pub export fn _start() noreturn {
1236 \\ var x: usize = 3;
1237 \\ const y = add(10, 2, x);
1238 \\ exit(y - 6);
1239 \\}
1240 \\
1241 \\fn add(a: usize, b: usize, c: usize) callconv(.Inline) usize {
1242 \\ if (a == 10) @compileError("bad");
1243 \\ return a + b + c;
1244 \\}
1245 \\
1246 \\fn exit(code: usize) noreturn {
1247 \\ asm volatile ("syscall"
1248 \\ :
1249 \\ : [number] "{rax}" (231),
1250 \\ [arg1] "{rdi}" (code)
1251 \\ : "rcx", "r11", "memory"
1252 \\ );
1253 \\ unreachable;
1254 \\}
1255 , &[_][]const u8{":8:18: error: bad"});
1256
1257 case.addCompareOutput(
1258 \\pub export fn _start() noreturn {
1259 \\ var x: usize = 3;
1260 \\ const y = add(1, 2, x);
1261 \\ exit(y - 6);
1262 \\}
1263 \\
1264 \\fn add(a: usize, b: usize, c: usize) callconv(.Inline) usize {
1265 \\ if (a == 10) @compileError("bad");
1266 \\ return a + b + c;
1267 \\}
1268 \\
1269 \\fn exit(code: usize) noreturn {
1270 \\ asm volatile ("syscall"
1271 \\ :
1272 \\ : [number] "{rax}" (231),
1273 \\ [arg1] "{rdi}" (code)
1274 \\ : "rcx", "r11", "memory"
1275 \\ );
1276 \\ unreachable;
1277 \\}
1278 ,
1279 "",
1280 );
1281 }
1282 {
1283 var case = ctx.exe("recursive inline function", linux_x64);
1284 case.addCompareOutput(
1285 \\pub export fn _start() noreturn {
1286 \\ const y = fibonacci(7);
1287 \\ exit(y - 21);
1288 \\}
1289 \\
1290 \\fn fibonacci(n: usize) callconv(.Inline) usize {
1291 \\ if (n <= 2) return n;
1292 \\ return fibonacci(n - 2) + fibonacci(n - 1);
1293 \\}
1294 \\
1295 \\fn exit(code: usize) noreturn {
1296 \\ asm volatile ("syscall"
1297 \\ :
1298 \\ : [number] "{rax}" (231),
1299 \\ [arg1] "{rdi}" (code)
1300 \\ : "rcx", "r11", "memory"
1301 \\ );
1302 \\ unreachable;
1303 \\}
1304 ,
1305 "",
1306 );
1307 // This additionally tests that the compile error reports the correct source location.
1308 // Without storing source locations relative to the owner decl, the compile error
1309 // here would be off by 2 bytes (from the "7" -> "999").
1310 case.addError(
1311 \\pub export fn _start() noreturn {
1312 \\ const y = fibonacci(999);
1313 \\ exit(y - 21);
1314 \\}
1315 \\
1316 \\fn fibonacci(n: usize) callconv(.Inline) usize {
1317 \\ if (n <= 2) return n;
1318 \\ return fibonacci(n - 2) + fibonacci(n - 1);
1319 \\}
1320 \\
1321 \\fn exit(code: usize) noreturn {
1322 \\ asm volatile ("syscall"
1323 \\ :
1324 \\ : [number] "{rax}" (231),
1325 \\ [arg1] "{rdi}" (code)
1326 \\ : "rcx", "r11", "memory"
1327 \\ );
1328 \\ unreachable;
1329 \\}
1330 , &[_][]const u8{":8:21: error: evaluation exceeded 1000 backwards branches"});
1331 }
1332 {
1333 var case = ctx.exe("orelse at comptime", linux_x64);
1334 case.addCompareOutput(
1335 \\pub fn main() void {
1336 \\ const i: ?u64 = 0;
1337 \\ const result = i orelse 5;
1338 \\ assert(result == 0);
1339 \\}
1340 \\fn assert(b: bool) void {
1341 \\ if (!b) unreachable;
1342 \\}
1343 ,
1344 "",
1345 );
1346 case.addCompareOutput(
1347 \\pub fn main() void {
1348 \\ const i: ?u64 = null;
1349 \\ const result = i orelse 5;
1350 \\ assert(result == 5);
1351 \\}
1352 \\fn assert(b: bool) void {
1353 \\ if (!b) unreachable;
1354 \\}
1355 ,
1356 "",
1357 );
1358 }
1359
1360 {
1361 var case = ctx.exe("only 1 function and it gets updated", linux_x64);
1362 case.addCompareOutput(
1363 \\pub export fn _start() noreturn {
1364 \\ asm volatile ("syscall"
1365 \\ :
1366 \\ : [number] "{rax}" (60), // exit
1367 \\ [arg1] "{rdi}" (0)
1368 \\ : "rcx", "r11", "memory"
1369 \\ );
1370 \\ unreachable;
1371 \\}
1372 ,
1373 "",
1374 );
1375 case.addCompareOutput(
1376 \\pub export fn _start() noreturn {
1377 \\ asm volatile ("syscall"
1378 \\ :
1379 \\ : [number] "{rax}" (231), // exit_group
1380 \\ [arg1] "{rdi}" (0)
1381 \\ : "rcx", "r11", "memory"
1382 \\ );
1383 \\ unreachable;
1384 \\}
1385 ,
1386 "",
1387 );
1388 }
1389 {
1390 var case = ctx.exe("passing u0 to function", linux_x64);
1391 case.addCompareOutput(
1392 \\pub fn main() void {
1393 \\ doNothing(0);
1394 \\}
1395 \\fn doNothing(arg: u0) void {
1396 \\ _ = arg;
1397 \\}
1398 ,
1399 "",
1400 );
1401 }
1402 {
1403 var case = ctx.exe("catch at comptime", linux_x64);
1404 case.addCompareOutput(
1405 \\pub fn main() void {
1406 \\ const i: anyerror!u64 = 0;
1407 \\ const caught = i catch 5;
1408 \\ assert(caught == 0);
1409 \\}
1410 \\fn assert(b: bool) void {
1411 \\ if (!b) unreachable;
1412 \\}
1413 ,
1414 "",
1415 );
1416
1417 case.addCompareOutput(
1418 \\pub fn main() void {
1419 \\ const i: anyerror!u64 = error.B;
1420 \\ const caught = i catch 5;
1421 \\ assert(caught == 5);
1422 \\}
1423 \\fn assert(b: bool) void {
1424 \\ if (!b) unreachable;
1425 \\}
1426 ,
1427 "",
1428 );
1429
1430 case.addCompareOutput(
1431 \\pub fn main() void {
1432 \\ const a: anyerror!comptime_int = 42;
1433 \\ const b: *const comptime_int = &(a catch unreachable);
1434 \\ assert(b.* == 42);
1435 \\}
1436 \\fn assert(b: bool) void {
1437 \\ if (!b) unreachable; // assertion failure
1438 \\}
1439 , "");
1440
1441 case.addCompareOutput(
1442 \\pub fn main() void {
1443 \\ const a: anyerror!u32 = error.B;
1444 \\ _ = &(a catch |err| assert(err == error.B));
1445 \\}
1446 \\fn assert(b: bool) void {
1447 \\ if (!b) unreachable;
1448 \\}
1449 , "");
1450
1451 case.addCompareOutput(
1452 \\pub fn main() void {
1453 \\ const a: anyerror!u32 = error.Bar;
1454 \\ a catch |err| assert(err == error.Bar);
1455 \\}
1456 \\fn assert(b: bool) void {
1457 \\ if (!b) unreachable;
1458 \\}
1459 , "");
1460 }
1461 {
1462 var case = ctx.exe("merge error sets", linux_x64);
1463
1464 case.addCompareOutput(
1465 \\pub fn main() void {
1466 \\ const E = error{ A, B, D } || error { A, B, C };
1467 \\ E.A catch {};
1468 \\ E.B catch {};
1469 \\ E.C catch {};
1470 \\ E.D catch {};
1471 \\ const E2 = error { X, Y } || @TypeOf(error.Z);
1472 \\ E2.X catch {};
1473 \\ E2.Y catch {};
1474 \\ E2.Z catch {};
1475 \\ assert(anyerror || error { Z } == anyerror);
1476 \\}
1477 \\fn assert(b: bool) void {
1478 \\ if (!b) unreachable;
1479 \\}
1480 ,
1481 "",
1482 );
1483 }
1484 {
1485 var case = ctx.exe("inline assembly", linux_x64);
1486
1487 case.addError(
1488 \\pub fn main() void {
1489 \\ const number = 1234;
1490 \\ const x = asm volatile ("syscall"
1491 \\ : [o] "{rax}" (-> number)
1492 \\ : [number] "{rax}" (231),
1493 \\ [arg1] "{rdi}" (code)
1494 \\ : "rcx", "r11", "memory"
1495 \\ );
1496 \\ _ = x;
1497 \\}
1498 , &[_][]const u8{":4:27: error: expected type, found comptime_int"});
1499 }
1500 {
1501 var case = ctx.exe("comptime var", linux_x64);
1502
1503 case.addError(
1504 \\pub fn main() void {
1505 \\ var a: u32 = 0;
1506 \\ comptime var b: u32 = 0;
1507 \\ if (a == 0) b = 3;
1508 \\}
1509 , &.{
1510 ":4:21: error: store to comptime variable depends on runtime condition",
1511 ":4:11: note: runtime condition here",
1512 });
1513
1514 case.addError(
1515 \\pub fn main() void {
1516 \\ var a: u32 = 0;
1517 \\ comptime var b: u32 = 0;
1518 \\ switch (a) {
1519 \\ 0 => {},
1520 \\ else => b = 3,
1521 \\ }
1522 \\}
1523 , &.{
1524 ":6:21: error: store to comptime variable depends on runtime condition",
1525 ":4:13: note: runtime condition here",
1526 });
1527
1528 case.addCompareOutput(
1529 \\pub fn main() void {
1530 \\ comptime var len: u32 = 5;
1531 \\ print(len);
1532 \\ len += 9;
1533 \\ print(len);
1534 \\}
1535 \\
1536 \\fn print(len: usize) void {
1537 \\ asm volatile ("syscall"
1538 \\ :
1539 \\ : [number] "{rax}" (1),
1540 \\ [arg1] "{rdi}" (1),
1541 \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
1542 \\ [arg3] "{rdx}" (len)
1543 \\ : "rcx", "r11", "memory"
1544 \\ );
1545 \\ return;
1546 \\}
1547 , "HelloHello, World!\n");
1548
1549 case.addError(
1550 \\comptime {
1551 \\ var x: i32 = 1;
1552 \\ x += 1;
1553 \\ if (x != 1) unreachable;
1554 \\}
1555 \\pub fn main() void {}
1556 , &.{":4:17: error: unable to resolve comptime value"});
1557
1558 case.addError(
1559 \\pub fn main() void {
1560 \\ comptime var i: u64 = 0;
1561 \\ while (i < 5) : (i += 1) {}
1562 \\}
1563 , &.{
1564 ":3:24: error: cannot store to comptime variable in non-inline loop",
1565 ":3:5: note: non-inline loop here",
1566 });
1567
1568 case.addCompareOutput(
1569 \\pub fn main() void {
1570 \\ var a: u32 = 0;
1571 \\ if (a == 0) {
1572 \\ comptime var b: u32 = 0;
1573 \\ b = 1;
1574 \\ }
1575 \\}
1576 \\comptime {
1577 \\ var x: i32 = 1;
1578 \\ x += 1;
1579 \\ if (x != 2) unreachable;
1580 \\}
1581 , "");
1582
1583 case.addCompareOutput(
1584 \\pub fn main() void {
1585 \\ comptime var i: u64 = 2;
1586 \\ inline while (i < 6) : (i+=1) {
1587 \\ print(i);
1588 \\ }
1589 \\}
1590 \\fn print(len: usize) void {
1591 \\ asm volatile ("syscall"
1592 \\ :
1593 \\ : [number] "{rax}" (1),
1594 \\ [arg1] "{rdi}" (1),
1595 \\ [arg2] "{rsi}" (@ptrToInt("Hello")),
1596 \\ [arg3] "{rdx}" (len)
1597 \\ : "rcx", "r11", "memory"
1598 \\ );
1599 \\ return;
1600 \\}
1601 , "HeHelHellHello");
1602 }
1603
1604 {
1605 var case = ctx.exe("double ampersand", linux_x64);
1606
1607 case.addError(
1608 \\pub const a = if (true && false) 1 else 2;
1609 , &[_][]const u8{":1:24: error: `&&` is invalid; note that `and` is boolean AND"});
1610
1611 case.addError(
1612 \\pub fn main() void {
1613 \\ const a = true;
1614 \\ const b = false;
1615 \\ _ = a & &b;
1616 \\}
1617 , &[_][]const u8{":4:11: error: incompatible types: 'bool' and '*const bool'"});
1618
1619 case.addCompareOutput(
1620 \\pub fn main() void {
1621 \\ const b: u8 = 1;
1622 \\ _ = &&b;
1623 \\}
1624 , "");
1625 }
1626}
test/tests.zig-321
...@@ -16,7 +16,6 @@ const LibExeObjStep = build.LibExeObjStep;...@@ -16,7 +16,6 @@ const LibExeObjStep = build.LibExeObjStep;
16const compare_output = @import("compare_output.zig");16const compare_output = @import("compare_output.zig");
17const standalone = @import("standalone.zig");17const standalone = @import("standalone.zig");
18const stack_traces = @import("stack_traces.zig");18const stack_traces = @import("stack_traces.zig");
19const compile_errors = @import("compile_errors.zig");
20const assemble_and_link = @import("assemble_and_link.zig");19const assemble_and_link = @import("assemble_and_link.zig");
21const runtime_safety = @import("runtime_safety.zig");20const runtime_safety = @import("runtime_safety.zig");
22const translate_c = @import("translate_c.zig");21const translate_c = @import("translate_c.zig");
...@@ -384,21 +383,6 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:...@@ -384,21 +383,6 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
384 return cases.step;383 return cases.step;
385}384}
386385
387pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
388 const cases = b.allocator.create(CompileErrorContext) catch unreachable;
389 cases.* = CompileErrorContext{
390 .b = b,
391 .step = b.step("test-compile-errors", "Run the compile error tests"),
392 .test_index = 0,
393 .test_filter = test_filter,
394 .modes = modes,
395 };
396
397 compile_errors.addCases(cases);
398
399 return cases.step;
400}
401
402pub fn addStandaloneTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode, skip_non_native: bool, target: std.zig.CrossTarget) *build.Step {386pub fn addStandaloneTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode, skip_non_native: bool, target: std.zig.CrossTarget) *build.Step {
403 const cases = b.allocator.create(StandaloneContext) catch unreachable;387 const cases = b.allocator.create(StandaloneContext) catch unreachable;
404 cases.* = StandaloneContext{388 cases.* = StandaloneContext{
...@@ -840,304 +824,6 @@ pub const StackTracesContext = struct {...@@ -840,304 +824,6 @@ pub const StackTracesContext = struct {
840 };824 };
841};825};
842826
843pub const CompileErrorContext = struct {
844 b: *build.Builder,
845 step: *build.Step,
846 test_index: usize,
847 test_filter: ?[]const u8,
848 modes: []const Mode,
849
850 const TestCase = struct {
851 name: []const u8,
852 sources: ArrayList(SourceFile),
853 expected_errors: ArrayList([]const u8),
854 expect_exact: bool,
855 link_libc: bool,
856 is_exe: bool,
857 is_test: bool,
858 target: CrossTarget = CrossTarget{},
859
860 const SourceFile = struct {
861 filename: []const u8,
862 source: []const u8,
863 };
864
865 pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
866 self.sources.append(SourceFile{
867 .filename = filename,
868 .source = source,
869 }) catch unreachable;
870 }
871
872 pub fn addExpectedError(self: *TestCase, text: []const u8) void {
873 self.expected_errors.append(text) catch unreachable;
874 }
875 };
876
877 const CompileCmpOutputStep = struct {
878 pub const base_id = .custom;
879
880 step: build.Step,
881 context: *CompileErrorContext,
882 name: []const u8,
883 test_index: usize,
884 case: *const TestCase,
885 build_mode: Mode,
886 write_src: *build.WriteFileStep,
887
888 const ErrLineIter = struct {
889 lines: mem.SplitIterator,
890
891 const source_file = "tmp.zig";
892
893 fn init(input: []const u8) ErrLineIter {
894 return ErrLineIter{ .lines = mem.split(input, "\n") };
895 }
896
897 fn next(self: *ErrLineIter) ?[]const u8 {
898 while (self.lines.next()) |line| {
899 if (mem.indexOf(u8, line, source_file) != null)
900 return line;
901 }
902 return null;
903 }
904 };
905
906 pub fn create(
907 context: *CompileErrorContext,
908 name: []const u8,
909 case: *const TestCase,
910 build_mode: Mode,
911 write_src: *build.WriteFileStep,
912 ) *CompileCmpOutputStep {
913 const allocator = context.b.allocator;
914 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
915 ptr.* = CompileCmpOutputStep{
916 .step = build.Step.init(.custom, "CompileCmpOutput", allocator, make),
917 .context = context,
918 .name = name,
919 .test_index = context.test_index,
920 .case = case,
921 .build_mode = build_mode,
922 .write_src = write_src,
923 };
924
925 context.test_index += 1;
926 return ptr;
927 }
928
929 fn make(step: *build.Step) !void {
930 const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
931 const b = self.context.b;
932
933 var zig_args = ArrayList([]const u8).init(b.allocator);
934 zig_args.append(b.zig_exe) catch unreachable;
935
936 if (self.case.is_exe) {
937 try zig_args.append("build-exe");
938 } else if (self.case.is_test) {
939 try zig_args.append("test");
940 } else {
941 try zig_args.append("build-obj");
942 }
943 const root_src_basename = self.case.sources.items[0].filename;
944 try zig_args.append(self.write_src.getFileSource(root_src_basename).?.getPath(b));
945
946 zig_args.append("--name") catch unreachable;
947 zig_args.append("test") catch unreachable;
948
949 if (!self.case.target.isNative()) {
950 try zig_args.append("-target");
951 try zig_args.append(try self.case.target.zigTriple(b.allocator));
952 }
953
954 zig_args.append("-O") catch unreachable;
955 zig_args.append(@tagName(self.build_mode)) catch unreachable;
956
957 warn("Test {d}/{d} {s}...", .{ self.test_index + 1, self.context.test_index, self.name });
958
959 if (b.verbose) {
960 printInvocation(zig_args.items);
961 }
962
963 const child = std.ChildProcess.init(zig_args.items, b.allocator) catch unreachable;
964 defer child.deinit();
965
966 child.env_map = b.env_map;
967 child.stdin_behavior = .Ignore;
968 child.stdout_behavior = .Pipe;
969 child.stderr_behavior = .Pipe;
970
971 child.spawn() catch |err| debug.panic("Unable to spawn {s}: {s}\n", .{ zig_args.items[0], @errorName(err) });
972
973 var stdout_buf = ArrayList(u8).init(b.allocator);
974 var stderr_buf = ArrayList(u8).init(b.allocator);
975
976 child.stdout.?.reader().readAllArrayList(&stdout_buf, max_stdout_size) catch unreachable;
977 child.stderr.?.reader().readAllArrayList(&stderr_buf, max_stdout_size) catch unreachable;
978
979 const term = child.wait() catch |err| {
980 debug.panic("Unable to spawn {s}: {s}\n", .{ zig_args.items[0], @errorName(err) });
981 };
982 switch (term) {
983 .Exited => |code| {
984 if (code == 0) {
985 printInvocation(zig_args.items);
986 return error.CompilationIncorrectlySucceeded;
987 }
988 },
989 else => {
990 warn("Process {s} terminated unexpectedly\n", .{b.zig_exe});
991 printInvocation(zig_args.items);
992 return error.TestFailed;
993 },
994 }
995
996 const stdout = stdout_buf.items;
997 const stderr = stderr_buf.items;
998
999 if (stdout.len != 0) {
1000 warn(
1001 \\
1002 \\Expected empty stdout, instead found:
1003 \\================================================
1004 \\{s}
1005 \\================================================
1006 \\
1007 , .{stdout});
1008 return error.TestFailed;
1009 }
1010
1011 var ok = true;
1012 if (self.case.expect_exact) {
1013 var err_iter = ErrLineIter.init(stderr);
1014 var i: usize = 0;
1015 ok = while (err_iter.next()) |line| : (i += 1) {
1016 if (i >= self.case.expected_errors.items.len) break false;
1017 const expected = self.case.expected_errors.items[i];
1018 if (mem.indexOf(u8, line, expected) == null) break false;
1019 continue;
1020 } else true;
1021
1022 ok = ok and i == self.case.expected_errors.items.len;
1023
1024 if (!ok) {
1025 warn("\n======== Expected these compile errors: ========\n", .{});
1026 for (self.case.expected_errors.items) |expected| {
1027 warn("{s}\n", .{expected});
1028 }
1029 }
1030 } else {
1031 for (self.case.expected_errors.items) |expected| {
1032 if (mem.indexOf(u8, stderr, expected) == null) {
1033 warn(
1034 \\
1035 \\=========== Expected compile error: ============
1036 \\{s}
1037 \\
1038 , .{expected});
1039 ok = false;
1040 break;
1041 }
1042 }
1043 }
1044
1045 if (!ok) {
1046 warn(
1047 \\================= Full output: =================
1048 \\{s}
1049 \\
1050 , .{stderr});
1051 return error.TestFailed;
1052 }
1053
1054 warn("OK\n", .{});
1055 }
1056 };
1057
1058 pub fn create(
1059 self: *CompileErrorContext,
1060 name: []const u8,
1061 source: []const u8,
1062 expected_lines: []const []const u8,
1063 ) *TestCase {
1064 const tc = self.b.allocator.create(TestCase) catch unreachable;
1065 tc.* = TestCase{
1066 .name = name,
1067 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
1068 .expected_errors = ArrayList([]const u8).init(self.b.allocator),
1069 .expect_exact = false,
1070 .link_libc = false,
1071 .is_exe = false,
1072 .is_test = false,
1073 };
1074
1075 tc.addSourceFile("tmp.zig", source);
1076 var arg_i: usize = 0;
1077 while (arg_i < expected_lines.len) : (arg_i += 1) {
1078 tc.addExpectedError(expected_lines[arg_i]);
1079 }
1080 return tc;
1081 }
1082
1083 pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: []const []const u8) void {
1084 var tc = self.create(name, source, expected_lines);
1085 tc.link_libc = true;
1086 self.addCase(tc);
1087 }
1088
1089 pub fn addExe(
1090 self: *CompileErrorContext,
1091 name: []const u8,
1092 source: []const u8,
1093 expected_lines: []const []const u8,
1094 ) void {
1095 var tc = self.create(name, source, expected_lines);
1096 tc.is_exe = true;
1097 self.addCase(tc);
1098 }
1099
1100 pub fn add(
1101 self: *CompileErrorContext,
1102 name: []const u8,
1103 source: []const u8,
1104 expected_lines: []const []const u8,
1105 ) void {
1106 const tc = self.create(name, source, expected_lines);
1107 self.addCase(tc);
1108 }
1109
1110 pub fn addTest(
1111 self: *CompileErrorContext,
1112 name: []const u8,
1113 source: []const u8,
1114 expected_lines: []const []const u8,
1115 ) void {
1116 const tc = self.create(name, source, expected_lines);
1117 tc.is_test = true;
1118 self.addCase(tc);
1119 }
1120
1121 pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
1122 const b = self.b;
1123
1124 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {s}", .{
1125 case.name,
1126 }) catch unreachable;
1127 if (self.test_filter) |filter| {
1128 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
1129 }
1130 const write_src = b.addWriteFiles();
1131 for (case.sources.items) |src_file| {
1132 write_src.add(src_file.filename, src_file.source);
1133 }
1134
1135 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, .Debug, write_src);
1136 compile_and_cmp_errors.step.dependOn(&write_src.step);
1137 self.step.dependOn(&compile_and_cmp_errors.step);
1138 }
1139};
1140
1141pub const StandaloneContext = struct {827pub const StandaloneContext = struct {
1142 b: *build.Builder,828 b: *build.Builder,
1143 step: *build.Step,829 step: *build.Step,
...@@ -1312,13 +998,6 @@ pub const GenHContext = struct {...@@ -1312,13 +998,6 @@ pub const GenHContext = struct {
1312 }998 }
1313 };999 };
13141000
1315 fn printInvocation(args: []const []const u8) void {
1316 for (args) |arg| {
1317 warn("{s} ", .{arg});
1318 }
1319 warn("\n", .{});
1320 }
1321
1322 pub fn create(1001 pub fn create(
1323 self: *GenHContext,1002 self: *GenHContext,
1324 filename: []const u8,1003 filename: []const u8,