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 {
4040
4141 var test_stage2 = b.addTest("src/test.zig");
4242 test_stage2.setBuildMode(mode);
43 test_stage2.addPackagePath("stage2_tests", "test/stage2/test.zig");
43 test_stage2.addPackagePath("test_cases", "test/cases.zig");
4444
4545 const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});
4646
......@@ -113,11 +113,15 @@ pub fn build(b: *Builder) !void {
113113 if (is_stage1) {
114114 exe.addIncludeDir("src");
115115 exe.addIncludeDir("deps/SoftFloat-3e/source/include");
116
117 test_stage2.addIncludeDir("src");
118 test_stage2.addIncludeDir("deps/SoftFloat-3e/source/include");
116119 // This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
117120 // of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
118121 // is pointless.
119122 exe.addPackagePath("compiler_rt", "src/empty.zig");
120123 exe.defineCMacro("ZIG_LINK_MODE", "Static");
124 test_stage2.defineCMacro("ZIG_LINK_MODE", "Static");
121125
122126 const softfloat = b.addStaticLibrary("softfloat", null);
123127 softfloat.setBuildMode(.ReleaseFast);
......@@ -126,10 +130,15 @@ pub fn build(b: *Builder) !void {
126130 softfloat.addIncludeDir("deps/SoftFloat-3e/source/8086");
127131 softfloat.addIncludeDir("deps/SoftFloat-3e/source/include");
128132 softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
133
129134 exe.linkLibrary(softfloat);
135 test_stage2.linkLibrary(softfloat);
130136
131137 exe.addCSourceFiles(&stage1_sources, &exe_cflags);
132138 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" });
133142 }
134143 if (cmake_cfg) |cfg| {
135144 // 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 {
139148 b.addSearchPrefix(cfg.cmake_prefix_path);
140149 }
141150
142 try addCmakeCfgOptionsToExe(b, cfg, tracy, exe);
143 try addCmakeCfgOptionsToExe(b, cfg, tracy, test_stage2);
151 try addCmakeCfgOptionsToExe(b, cfg, exe);
152 try addCmakeCfgOptionsToExe(b, cfg, test_stage2);
144153 } else {
145154 // Here we are -Denable-llvm but no cmake integration.
146155 try addStaticLlvmOptionsToExe(exe);
......@@ -233,7 +242,9 @@ pub fn build(b: *Builder) !void {
233242 const is_darling_enabled = b.option(bool, "enable-darling", "[Experimental] Use Darling to run cross compiled macOS tests") orelse false;
234243 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);
236246 test_stage2.addBuildOption(bool, "skip_non_native", skip_non_native);
247 test_stage2.addBuildOption(bool, "skip_compile_errors", skip_compile_errors);
237248 test_stage2.addBuildOption(bool, "is_stage1", is_stage1);
238249 test_stage2.addBuildOption(bool, "omit_stage2", omit_stage2);
239250 test_stage2.addBuildOption(bool, "have_llvm", enable_llvm);
......@@ -243,7 +254,8 @@ pub fn build(b: *Builder) !void {
243254 test_stage2.addBuildOption(u32, "mem_leak_frames", mem_leak_frames * 2);
244255 test_stage2.addBuildOption(bool, "enable_darling", is_darling_enabled);
245256 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
248260 const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
249261 test_stage2_step.dependOn(&test_stage2.step);
......@@ -339,9 +351,6 @@ pub fn build(b: *Builder) !void {
339351 }
340352 // tests for this feature are disabled until we have the self-hosted compiler available
341353 // 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
346355 const std_step = tests.addPkgTests(
347356 b,
......@@ -383,7 +392,6 @@ const exe_cflags = [_][]const u8{
383392fn addCmakeCfgOptionsToExe(
384393 b: *Builder,
385394 cfg: CMakeConfig,
386 tracy: ?[]const u8,
387395 exe: *std.build.LibExeObjStep,
388396) !void {
389397 exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
......@@ -397,7 +405,7 @@ fn addCmakeCfgOptionsToExe(
397405 addCMakeLibraryList(exe, cfg.lld_libraries);
398406 addCMakeLibraryList(exe, cfg.llvm_libraries);
399407
400 const need_cpp_includes = tracy != null;
408 const need_cpp_includes = true;
401409
402410 // System -lc++ must be used because in this code path we are attempting to link
403411 // against system-provided LLVM, Clang, LLD.
......@@ -486,9 +494,9 @@ fn addCxxKnownPath(
486494 if (need_cpp_includes) {
487495 // I used these temporarily for testing something but we obviously need a
488496 // 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");
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");
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");
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");
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");
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");
492500 }
493501}
494502
doc/docgen.zig+34-14
......@@ -8,6 +8,7 @@ const Progress = std.Progress;
88const print = std.debug.print;
99const mem = std.mem;
1010const testing = std.testing;
11const Allocator = std.mem.Allocator;
1112
1213const max_doc_file_size = 10 * 1024 * 1024;
1314
......@@ -326,7 +327,7 @@ const Action = enum {
326327 Close,
327328};
328329
329fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
330fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
330331 var urls = std.StringHashMap(Token).init(allocator);
331332 errdefer urls.deinit();
332333
......@@ -630,7 +631,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
630631 };
631632}
632633
633fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
634fn urlize(allocator: *Allocator, input: []const u8) ![]u8 {
634635 var buf = std.ArrayList(u8).init(allocator);
635636 defer buf.deinit();
636637
......@@ -649,7 +650,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
649650 return buf.toOwnedSlice();
650651}
651652
652fn escapeHtml(allocator: *mem.Allocator, input: []const u8) ![]u8 {
653fn escapeHtml(allocator: *Allocator, input: []const u8) ![]u8 {
653654 var buf = std.ArrayList(u8).init(allocator);
654655 defer buf.deinit();
655656
......@@ -695,7 +696,7 @@ test "term color" {
695696 testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);
696697}
697698
698fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
699fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {
699700 var buf = std.ArrayList(u8).init(allocator);
700701 defer buf.deinit();
701702
......@@ -789,8 +790,15 @@ fn isType(name: []const u8) bool {
789790 return false;
790791}
791792
792fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token: Token, raw_src: []const u8) !void {
793 const src = mem.trim(u8, raw_src, " \n");
793fn tokenizeAndPrintRaw(
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);
794802 try out.writeAll("<code class=\"zig\">");
795803 var tokenizer = std.zig.Tokenizer.init(src);
796804 var index: usize = 0;
......@@ -1016,12 +1024,24 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token:
10161024 try out.writeAll("</code>");
10171025}
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 {
10201033 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);
10221035}
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 {
10251045 var progress = Progress{};
10261046 const root_node = try progress.start("Generating docgen examples", toc.nodes.len);
10271047 defer root_node.end();
......@@ -1048,7 +1068,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
10481068 },
10491069 .Builtin => |tok| {
10501070 try out.writeAll("<pre>");
1051 try tokenizeAndPrintRaw(tokenizer, out, tok, builtin_code);
1071 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);
10521072 try out.writeAll("</pre>");
10531073 },
10541074 .HeaderOpen => |info| {
......@@ -1069,7 +1089,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
10691089 try out.writeAll("</ul>\n");
10701090 },
10711091 .Syntax => |content_tok| {
1072 try tokenizeAndPrint(tokenizer, out, content_tok);
1092 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);
10731093 },
10741094 .Code => |code| {
10751095 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
10781098 try out.print("<p class=\"file\">{s}.zig</p>", .{code.name});
10791099 }
10801100 try out.writeAll("<pre>");
1081 try tokenizeAndPrint(tokenizer, out, code.source_token);
1101 try tokenizeAndPrint(allocator, tokenizer, out, code.source_token);
10821102 try out.writeAll("</pre>");
10831103
10841104 if (!do_code_tests) {
......@@ -1497,7 +1517,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
14971517 }
14981518}
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 {
15011521 const result = try ChildProcess.exec(.{
15021522 .allocator = allocator,
15031523 .argv = args,
......@@ -1521,7 +1541,7 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
15211541 return result;
15221542}
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 {
15251545 const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });
15261546 return result.stdout;
15271547}
doc/langref.html.in+18-6
......@@ -3025,7 +3025,7 @@ test "@tagName" {
30253025 </p>
30263026 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}
30273027const Foo = enum { a, b, c };
3028export fn entry(foo: Foo) void { }
3028export fn entry(foo: Foo) void { _ = foo; }
30293029 {#code_end#}
30303030 <p>
30313031 For a C-ABI-compatible enum, provide an explicit tag type to
......@@ -3346,7 +3346,7 @@ test "call foo" {
33463346 <p>
33473347 Blocks are used to limit the scope of variable declarations:
33483348 </p>
3349 {#code_begin|test_err|undeclared identifier#}
3349 {#code_begin|test_err|unused local variable#}
33503350test "access variable after block scope" {
33513351 {
33523352 var x: i32 = 1;
......@@ -3377,7 +3377,7 @@ test "labeled break from labeled block expression" {
33773377
33783378 {#header_open|Shadowing#}
33793379 <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#}
33813381const pi = 3.14;
33823382
33833383test "inside test block" {
......@@ -4228,8 +4228,8 @@ test "type of unreachable" {
42284228 comptime {
42294229 // The type of unreachable is noreturn.
42304230
4231 // However this assertion will still fail because
4232 // evaluating unreachable at compile-time is a compile error.
4231 // However this assertion will still fail to compile because
4232 // unreachable expressions are compile errors.
42334233
42344234 assert(@TypeOf(unreachable) == noreturn);
42354235 }
......@@ -5257,6 +5257,7 @@ test "float widening" {
52575257// Compile time coercion of float to int
52585258test "implicit cast to comptime_int" {
52595259 var f: f32 = 54.0 / 5;
5260 _ = f;
52605261}
52615262 {#code_end#}
52625263 {#header_close#}
......@@ -5817,6 +5818,7 @@ fn foo(condition: bool) void {
58175818 if (condition) f32 else u64,
58185819 1234,
58195820 5678);
5821 _ = result;
58205822}
58215823 {#code_end#}
58225824 <p>
......@@ -6313,7 +6315,7 @@ pub fn printValue(self: *Writer, value: anytype) !void {
63136315 <p>
63146316 And now, what happens if we give too many arguments to {#syntax#}printf{#endsyntax#}?
63156317 </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: {}#}
63176319const print = @import("std").debug.print;
63186320
63196321const a_number: i32 = 1234;
......@@ -8853,6 +8855,7 @@ pub fn main() void {
88538855comptime {
88548856 const array: [5]u8 = "hello".*;
88558857 const garbage = array[5];
8858 _ = garbage;
88568859}
88578860 {#code_end#}
88588861 <p>At runtime:</p>
......@@ -8873,6 +8876,7 @@ fn foo(x: []const u8) u8 {
88738876comptime {
88748877 const value: i32 = -1;
88758878 const unsigned = @intCast(u32, value);
8879 _ = unsigned;
88768880}
88778881 {#code_end#}
88788882 <p>At runtime:</p>
......@@ -8895,6 +8899,7 @@ pub fn main() void {
88958899comptime {
88968900 const spartan_count: u16 = 300;
88978901 const byte = @intCast(u8, spartan_count);
8902 _ = byte;
88988903}
88998904 {#code_end#}
89008905 <p>At runtime:</p>
......@@ -9028,6 +9033,7 @@ test "wraparound addition and subtraction" {
90289033 {#code_begin|test_err|operation caused overflow#}
90299034comptime {
90309035 const x = @shlExact(@as(u8, 0b01010101), 2);
9036 _ = x;
90319037}
90329038 {#code_end#}
90339039 <p>At runtime:</p>
......@@ -9046,6 +9052,7 @@ pub fn main() void {
90469052 {#code_begin|test_err|exact shift shifted out 1 bits#}
90479053comptime {
90489054 const x = @shrExact(@as(u8, 0b10101010), 2);
9055 _ = x;
90499056}
90509057 {#code_end#}
90519058 <p>At runtime:</p>
......@@ -9066,6 +9073,7 @@ comptime {
90669073 const a: i32 = 1;
90679074 const b: i32 = 0;
90689075 const c = a / b;
9076 _ = c;
90699077}
90709078 {#code_end#}
90719079 <p>At runtime:</p>
......@@ -9087,6 +9095,7 @@ comptime {
90879095 const a: i32 = 10;
90889096 const b: i32 = 0;
90899097 const c = a % b;
9098 _ = c;
90909099}
90919100 {#code_end#}
90929101 <p>At runtime:</p>
......@@ -9108,6 +9117,7 @@ comptime {
91089117 const a: u32 = 10;
91099118 const b: u32 = 3;
91109119 const c = @divExact(a, b);
9120 _ = c;
91119121}
91129122 {#code_end#}
91139123 <p>At runtime:</p>
......@@ -9300,6 +9310,7 @@ fn foo(set1: Set1) void {
93009310comptime {
93019311 const ptr = @intToPtr(*align(1) i32, 0x1);
93029312 const aligned = @alignCast(4, ptr);
9313 _ = aligned;
93039314}
93049315 {#code_end#}
93059316 <p>At runtime:</p>
......@@ -9414,6 +9425,7 @@ fn bar(f: *Foo) void {
94149425comptime {
94159426 const opt_ptr: ?*i32 = null;
94169427 const ptr = @ptrCast(*i32, opt_ptr);
9428 _ = ptr;
94179429}
94189430 {#code_end#}
94199431 <p>At runtime:</p>
lib/std/fmt.zig+2-2
......@@ -362,8 +362,8 @@ pub fn format(
362362 const missing_count = arg_state.args_len - @popCount(ArgSetType, arg_state.used_args);
363363 switch (missing_count) {
364364 0 => unreachable,
365 1 => @compileError("Unused argument in \"" ++ fmt ++ "\""),
366 else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in \"" ++ fmt ++ "\""),
365 1 => @compileError("Unused argument in '" ++ fmt ++ "'"),
366 else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in '" ++ fmt ++ "'"),
367367 }
368368 }
369369}
lib/std/mem.zig+5-5
......@@ -2297,14 +2297,14 @@ pub fn replaceOwned(comptime T: type, allocator: *Allocator, input: []const T, n
22972297}
22982298
22992299test "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;
2303 defer allocator.free(base_replace);
2302 const base_replace = replaceOwned(u8, gpa, "All your base are belong to us", "base", "Zig") catch @panic("out of memory");
2303 defer gpa.free(base_replace);
23042304 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;
2307 defer allocator.free(zen_replace);
2306 const zen_replace = replaceOwned(u8, gpa, "Favor reading code over writing code.", " code", "") catch @panic("out of memory");
2307 defer gpa.free(zen_replace);
23082308 try testing.expect(eql(u8, zen_replace, "Favor reading over writing."));
23092309}
23102310
lib/std/os/uefi/protocols/simple_network_protocol.zig+4-4
......@@ -57,13 +57,13 @@ pub const SimpleNetworkProtocol = extern struct {
5757 }
5858
5959 /// Modifies or resets the current station address, if supported.
60 pub fn stationAddress(self: *const SimpleNetworkProtocol, reset: bool, new: ?*const MacAddress) Status {
61 return self._station_address(self, reset, new);
60 pub fn stationAddress(self: *const SimpleNetworkProtocol, reset_flag: bool, new: ?*const MacAddress) Status {
61 return self._station_address(self, reset_flag, new);
6262 }
6363
6464 /// 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 {
66 return self._statistics(self, reset_, statistics_size, statistics_table);
65 pub fn statistics(self: *const SimpleNetworkProtocol, reset_flag: bool, statistics_size: ?*usize, statistics_table: ?*NetworkStatistics) Status {
66 return self._statistics(self, reset_flag, statistics_size, statistics_table);
6767 }
6868
6969 /// Converts a multicast IP address to a multicast HW MAC address.
lib/std/unicode.zig-1
......@@ -247,7 +247,6 @@ pub const Utf8View = struct {
247247 } else |err| switch (err) {
248248 error.InvalidUtf8 => {
249249 @compileError("invalid utf8");
250 unreachable;
251250 },
252251 }
253252 }
lib/std/zig.zig+147-56
......@@ -6,6 +6,7 @@
66const std = @import("std.zig");
77const tokenizer = @import("zig/tokenizer.zig");
88const fmt = @import("zig/fmt.zig");
9const assert = std.debug.assert;
910
1011pub const Token = tokenizer.Token;
1112pub const Tokenizer = tokenizer.Tokenizer;
......@@ -183,29 +184,48 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
183184 }
184185}
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
186207/// Only validates escape sequence characters.
187208/// Slice must be valid utf8 starting and ending with "'" and exactly one codepoint in between.
188pub fn parseCharLiteral(
189 slice: []const u8,
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] == '\'');
209pub fn parseCharLiteral(slice: []const u8) ParsedCharLiteral {
210 assert(slice.len >= 3 and slice[0] == '\'' and slice[slice.len - 1] == '\'');
193211
194 if (slice[1] == '\\') {
195 switch (slice[2]) {
196 'n' => return '\n',
197 'r' => return '\r',
198 '\\' => return '\\',
199 't' => return '\t',
200 '\'' => return '\'',
201 '"' => return '"',
212 switch (slice[1]) {
213 0 => return .{ .invalid_character = 1 },
214 '\\' => switch (slice[2]) {
215 'n' => return .{ .success = '\n' },
216 'r' => return .{ .success = '\r' },
217 '\\' => return .{ .success = '\\' },
218 't' => return .{ .success = '\t' },
219 '\'' => return .{ .success = '\'' },
220 '"' => return .{ .success = '"' },
202221 'x' => {
203 if (slice.len != 6) {
204 bad_index.* = slice.len - 2;
205 return error.InvalidCharacter;
222 if (slice.len < 4) {
223 return .{ .expected_hex_digit = 3 };
206224 }
207225 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];
209229 switch (c) {
210230 '0'...'9' => {
211231 value *= 16;
......@@ -220,20 +240,28 @@ pub fn parseCharLiteral(
220240 value += c - 'A' + 10;
221241 },
222242 else => {
223 bad_index.* = 3 + i;
224 return error.InvalidCharacter;
243 return .{ .expected_hex_digit = i };
225244 },
226245 }
227246 }
228 return value;
247 if (slice[i] != '\'') {
248 return .{ .expected_end = i };
249 }
250 return .{ .success = value };
229251 },
230252 'u' => {
231 if (slice.len < "'\\u{0}'".len or slice[3] != '{' or slice[slice.len - 2] != '}') {
232 bad_index.* = 2;
233 return error.InvalidCharacter;
253 var i: usize = 3;
254 if (slice[i] != '{') {
255 return .{ .expected_lbrace = i };
234256 }
257 i += 1;
258 if (slice[i] == '}') {
259 return .{ .empty_unicode_escape_sequence = i };
260 }
261
235262 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];
237265 switch (c) {
238266 '0'...'9' => {
239267 value *= 16;
......@@ -247,49 +275,112 @@ pub fn parseCharLiteral(
247275 value *= 16;
248276 value += c - 'A' + 10;
249277 },
250 else => {
251 bad_index.* = 4 + i;
252 return error.InvalidCharacter;
278 '}' => {
279 i += 1;
280 break;
253281 },
282 else => return .{ .expected_hex_digit_or_rbrace = i },
254283 }
255284 if (value > 0x10ffff) {
256 bad_index.* = 4 + i;
257 return error.InvalidCharacter;
285 return .{ .unicode_escape_overflow = i };
258286 }
259287 }
260 return value;
261 },
262 else => {
263 bad_index.* = 2;
264 return error.InvalidCharacter;
288 if (slice[i] != '\'') {
289 return .{ .expected_end = i };
290 }
291 return .{ .success = value };
265292 },
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 },
267299 }
268 return std.unicode.utf8Decode(slice[1 .. slice.len - 1]) catch unreachable;
269300}
270301
271302test "parseCharLiteral" {
272 var bad_index: usize = undefined;
273 try std.testing.expectEqual(try parseCharLiteral("'a'", &bad_index), 'a');
274 try std.testing.expectEqual(try parseCharLiteral("'ä'", &bad_index), 'ä');
275 try std.testing.expectEqual(try parseCharLiteral("'\\x00'", &bad_index), 0);
276 try std.testing.expectEqual(try parseCharLiteral("'\\x4f'", &bad_index), 0x4f);
277 try std.testing.expectEqual(try parseCharLiteral("'\\x4F'", &bad_index), 0x4f);
278 try std.testing.expectEqual(try parseCharLiteral("'ぁ'", &bad_index), 0x3041);
279 try std.testing.expectEqual(try parseCharLiteral("'\\u{0}'", &bad_index), 0);
280 try std.testing.expectEqual(try parseCharLiteral("'\\u{3041}'", &bad_index), 0x3041);
281 try std.testing.expectEqual(try parseCharLiteral("'\\u{7f}'", &bad_index), 0x7f);
282 try std.testing.expectEqual(try parseCharLiteral("'\\u{7FFF}'", &bad_index), 0x7FFF);
303 try std.testing.expectEqual(
304 ParsedCharLiteral{ .success = 'a' },
305 parseCharLiteral("'a'"),
306 );
307 try std.testing.expectEqual(
308 ParsedCharLiteral{ .success = 'ä' },
309 parseCharLiteral("'ä'"),
310 );
311 try std.testing.expectEqual(
312 ParsedCharLiteral{ .success = 0 },
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));
285 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\x000'", &bad_index));
286 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\y'", &bad_index));
287 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u'", &bad_index));
288 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\uFFFF'", &bad_index));
289 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{}'", &bad_index));
290 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFFFF}'", &bad_index));
291 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFF'", &bad_index));
292 try std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFF}x'", &bad_index));
344 try std.testing.expectEqual(
345 ParsedCharLiteral{ .expected_hex_digit = 4 },
346 parseCharLiteral("'\\x0'"),
347 );
348 try std.testing.expectEqual(
349 ParsedCharLiteral{ .expected_end = 5 },
350 parseCharLiteral("'\\x000'"),
351 );
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 );
293384}
294385
295386test {
lib/std/zig/ast.zig+4-2
......@@ -20,7 +20,7 @@ pub const NodeList = std.MultiArrayList(Node);
2020
2121pub const Tree = struct {
2222 /// Reference to externally-owned data.
23 source: []const u8,
23 source: [:0]const u8,
2424
2525 tokens: TokenList.Slice,
2626 /// The root AST node is assumed to be index 0. Since there can be no
......@@ -135,6 +135,8 @@ pub const Tree = struct {
135135 const token_tags = tree.tokens.items(.tag);
136136 switch (parse_error.tag) {
137137 .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 `.*`.
138140 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
139141 },
140142 .decl_between_fields => {
......@@ -284,7 +286,7 @@ pub const Tree = struct {
284286 return stream.writeAll("bit range not allowed on slices and arrays");
285287 },
286288 .invalid_token => {
287 return stream.print("invalid token '{s}'", .{
289 return stream.print("invalid token: '{s}'", .{
288290 token_tags[parse_error.token].symbol(),
289291 });
290292 },
lib/std/zig/parse.zig+1-1
......@@ -17,7 +17,7 @@ pub const Error = error{ParseError} || Allocator.Error;
1717
1818/// Result should be freed with tree.deinit() when there are
1919/// 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 {
2121 var tokens = ast.TokenList{};
2222 defer tokens.deinit(gpa);
2323
lib/std/zig/parser_test.zig+4-4
......@@ -5194,7 +5194,7 @@ const maxInt = std.math.maxInt;
51945194
51955195var 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 {
51985198 const stderr = io.getStdErr().writer();
51995199
52005200 var tree = try std.zig.parse(allocator, source);
......@@ -5222,7 +5222,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
52225222 anything_changed.* = !mem.eql(u8, formatted, source);
52235223 return formatted;
52245224}
5225fn testTransform(source: []const u8, expected_source: []const u8) !void {
5225fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {
52265226 const needed_alloc_count = x: {
52275227 // Try it once with unlimited memory, make sure it works
52285228 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 {
52685268 }
52695269 }
52705270}
5271fn testCanonical(source: []const u8) !void {
5271fn testCanonical(source: [:0]const u8) !void {
52725272 return testTransform(source, source);
52735273}
52745274
52755275const 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 {
52785278 var tree = try std.zig.parse(std.testing.allocator, source);
52795279 defer tree.deinit(std.testing.allocator);
52805280
lib/std/zig/tokenizer.zig+78-189
......@@ -326,7 +326,7 @@ pub const Token = struct {
326326};
327327
328328pub const Tokenizer = struct {
329 buffer: []const u8,
329 buffer: [:0]const u8,
330330 index: usize,
331331 pending_invalid_token: ?Token,
332332
......@@ -335,7 +335,7 @@ pub const Tokenizer = struct {
335335 std.debug.warn("{s} \"{s}\"\n", .{ @tagName(token.tag), self.buffer[token.start..token.end] });
336336 }
337337
338 pub fn init(buffer: []const u8) Tokenizer {
338 pub fn init(buffer: [:0]const u8) Tokenizer {
339339 // Skip the UTF-8 BOM if present
340340 const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else @as(usize, 0);
341341 return Tokenizer{
......@@ -373,7 +373,6 @@ pub const Tokenizer = struct {
373373 line_comment,
374374 doc_comment_start,
375375 doc_comment,
376 container_doc_comment,
377376 zero,
378377 int_literal_dec,
379378 int_literal_dec_no_underscore,
......@@ -407,10 +406,6 @@ pub const Tokenizer = struct {
407406 saw_at_sign,
408407 };
409408
410 fn isIdentifierChar(char: u8) bool {
411 return std.ascii.isAlNum(char) or char == '_';
412 }
413
414409 pub fn next(self: *Tokenizer) Token {
415410 if (self.pending_invalid_token) |token| {
416411 self.pending_invalid_token = null;
......@@ -426,10 +421,11 @@ pub const Tokenizer = struct {
426421 };
427422 var seen_escape_digits: usize = undefined;
428423 var remaining_code_units: usize = undefined;
429 while (self.index < self.buffer.len) : (self.index += 1) {
424 while (true) : (self.index += 1) {
430425 const c = self.buffer[self.index];
431426 switch (state) {
432427 .start => switch (c) {
428 0 => break,
433429 ' ', '\n', '\t', '\r' => {
434430 result.loc.start = self.index + 1;
435431 },
......@@ -555,8 +551,9 @@ pub const Tokenizer = struct {
555551 },
556552 else => {
557553 result.tag = .invalid;
554 result.loc.end = self.index;
558555 self.index += 1;
559 break;
556 return result;
560557 },
561558 },
562559
......@@ -705,18 +702,35 @@ pub const Tokenizer = struct {
705702 self.index += 1;
706703 break;
707704 },
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 },
709716 else => self.checkLiteralCharacter(),
710717 },
711718
712719 .string_literal_backslash => switch (c) {
713 '\n', '\r' => break, // Look for this error later.
720 '\n' => {
721 result.tag = .invalid;
722 break;
723 },
714724 else => {
715725 state = .string_literal;
716726 },
717727 },
718728
719729 .char_literal => switch (c) {
730 0 => {
731 result.tag = .invalid;
732 break;
733 },
720734 '\\' => {
721735 state = .char_literal_backslash;
722736 },
......@@ -742,7 +756,7 @@ pub const Tokenizer = struct {
742756 },
743757
744758 .char_literal_backslash => switch (c) {
745 '\n' => {
759 0, '\n' => {
746760 result.tag = .invalid;
747761 break;
748762 },
......@@ -774,7 +788,6 @@ pub const Tokenizer = struct {
774788 .char_literal_unicode_escape_saw_u => switch (c) {
775789 '{' => {
776790 state = .char_literal_unicode_escape;
777 seen_escape_digits = 0;
778791 },
779792 else => {
780793 result.tag = .invalid;
......@@ -783,16 +796,9 @@ pub const Tokenizer = struct {
783796 },
784797
785798 .char_literal_unicode_escape => switch (c) {
786 '0'...'9', 'a'...'f', 'A'...'F' => {
787 seen_escape_digits += 1;
788 },
799 '0'...'9', 'a'...'f', 'A'...'F' => {},
789800 '}' => {
790 if (seen_escape_digits == 0) {
791 result.tag = .invalid;
792 state = .char_literal_unicode_invalid;
793 } else {
794 state = .char_literal_end;
795 }
801 state = .char_literal_end; // too many/few digits handled later
796802 },
797803 else => {
798804 result.tag = .invalid;
......@@ -834,6 +840,7 @@ pub const Tokenizer = struct {
834840 },
835841
836842 .multiline_string_literal_line => switch (c) {
843 0 => break,
837844 '\n' => {
838845 self.index += 1;
839846 break;
......@@ -1025,12 +1032,19 @@ pub const Tokenizer = struct {
10251032 },
10261033 },
10271034 .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 },
10281042 '/' => {
10291043 state = .doc_comment_start;
10301044 },
10311045 '!' => {
10321046 result.tag = .container_doc_comment;
1033 state = .container_doc_comment;
1047 state = .doc_comment;
10341048 },
10351049 '\n' => {
10361050 state = .start;
......@@ -1046,7 +1060,7 @@ pub const Tokenizer = struct {
10461060 '/' => {
10471061 state = .line_comment;
10481062 },
1049 '\n' => {
1063 0, '\n' => {
10501064 result.tag = .doc_comment;
10511065 break;
10521066 },
......@@ -1061,6 +1075,7 @@ pub const Tokenizer = struct {
10611075 },
10621076 },
10631077 .line_comment => switch (c) {
1078 0 => break,
10641079 '\n' => {
10651080 state = .start;
10661081 result.loc.start = self.index + 1;
......@@ -1068,8 +1083,8 @@ pub const Tokenizer = struct {
10681083 '\t', '\r' => {},
10691084 else => self.checkLiteralCharacter(),
10701085 },
1071 .doc_comment, .container_doc_comment => switch (c) {
1072 '\n' => break,
1086 .doc_comment => switch (c) {
1087 0, '\n' => break,
10731088 '\t', '\r' => {},
10741089 else => self.checkLiteralCharacter(),
10751090 },
......@@ -1088,12 +1103,11 @@ pub const Tokenizer = struct {
10881103 self.index -= 1;
10891104 state = .int_literal_dec;
10901105 },
1091 else => {
1092 if (isIdentifierChar(c)) {
1093 result.tag = .invalid;
1094 }
1106 'a', 'c', 'd', 'f'...'n', 'p'...'w', 'y', 'z', 'A'...'D', 'F'...'Z' => {
1107 result.tag = .invalid;
10951108 break;
10961109 },
1110 else => break,
10971111 },
10981112 .int_literal_bin_no_underscore => switch (c) {
10991113 '0'...'1' => {
......@@ -1109,12 +1123,11 @@ pub const Tokenizer = struct {
11091123 state = .int_literal_bin_no_underscore;
11101124 },
11111125 '0'...'1' => {},
1112 else => {
1113 if (isIdentifierChar(c)) {
1114 result.tag = .invalid;
1115 }
1126 '2'...'9', 'a'...'z', 'A'...'Z' => {
1127 result.tag = .invalid;
11161128 break;
11171129 },
1130 else => break,
11181131 },
11191132 .int_literal_oct_no_underscore => switch (c) {
11201133 '0'...'7' => {
......@@ -1130,12 +1143,11 @@ pub const Tokenizer = struct {
11301143 state = .int_literal_oct_no_underscore;
11311144 },
11321145 '0'...'7' => {},
1133 else => {
1134 if (isIdentifierChar(c)) {
1135 result.tag = .invalid;
1136 }
1146 '8', '9', 'a'...'z', 'A'...'Z' => {
1147 result.tag = .invalid;
11371148 break;
11381149 },
1150 else => break,
11391151 },
11401152 .int_literal_dec_no_underscore => switch (c) {
11411153 '0'...'9' => {
......@@ -1159,12 +1171,11 @@ pub const Tokenizer = struct {
11591171 result.tag = .float_literal;
11601172 },
11611173 '0'...'9' => {},
1162 else => {
1163 if (isIdentifierChar(c)) {
1164 result.tag = .invalid;
1165 }
1174 'a'...'d', 'f'...'z', 'A'...'D', 'F'...'Z' => {
1175 result.tag = .invalid;
11661176 break;
11671177 },
1178 else => break,
11681179 },
11691180 .int_literal_hex_no_underscore => switch (c) {
11701181 '0'...'9', 'a'...'f', 'A'...'F' => {
......@@ -1188,12 +1199,11 @@ pub const Tokenizer = struct {
11881199 result.tag = .float_literal;
11891200 },
11901201 '0'...'9', 'a'...'f', 'A'...'F' => {},
1191 else => {
1192 if (isIdentifierChar(c)) {
1193 result.tag = .invalid;
1194 }
1202 'g'...'o', 'q'...'z', 'G'...'O', 'Q'...'Z' => {
1203 result.tag = .invalid;
11951204 break;
11961205 },
1206 else => break,
11971207 },
11981208 .num_dot_dec => switch (c) {
11991209 '.' => {
......@@ -1206,12 +1216,11 @@ pub const Tokenizer = struct {
12061216 result.tag = .float_literal;
12071217 state = .float_fraction_dec;
12081218 },
1209 else => {
1210 if (isIdentifierChar(c)) {
1211 result.tag = .invalid;
1212 }
1219 '_', 'a'...'z', 'A'...'Z' => {
1220 result.tag = .invalid;
12131221 break;
12141222 },
1223 else => break,
12151224 },
12161225 .num_dot_hex => switch (c) {
12171226 '.' => {
......@@ -1224,12 +1233,11 @@ pub const Tokenizer = struct {
12241233 result.tag = .float_literal;
12251234 state = .float_fraction_hex;
12261235 },
1227 else => {
1228 if (isIdentifierChar(c)) {
1229 result.tag = .invalid;
1230 }
1236 '_', 'g'...'z', 'G'...'Z' => {
1237 result.tag = .invalid;
12311238 break;
12321239 },
1240 else => break,
12331241 },
12341242 .float_fraction_dec_no_underscore => switch (c) {
12351243 '0'...'9' => {
......@@ -1248,12 +1256,11 @@ pub const Tokenizer = struct {
12481256 state = .float_exponent_unsigned;
12491257 },
12501258 '0'...'9' => {},
1251 else => {
1252 if (isIdentifierChar(c)) {
1253 result.tag = .invalid;
1254 }
1259 'a'...'d', 'f'...'z', 'A'...'D', 'F'...'Z' => {
1260 result.tag = .invalid;
12551261 break;
12561262 },
1263 else => break,
12571264 },
12581265 .float_fraction_hex_no_underscore => switch (c) {
12591266 '0'...'9', 'a'...'f', 'A'...'F' => {
......@@ -1272,12 +1279,11 @@ pub const Tokenizer = struct {
12721279 state = .float_exponent_unsigned;
12731280 },
12741281 '0'...'9', 'a'...'f', 'A'...'F' => {},
1275 else => {
1276 if (isIdentifierChar(c)) {
1277 result.tag = .invalid;
1278 }
1282 'g'...'o', 'q'...'z', 'G'...'O', 'Q'...'Z' => {
1283 result.tag = .invalid;
12791284 break;
12801285 },
1286 else => break,
12811287 },
12821288 .float_exponent_unsigned => switch (c) {
12831289 '+', '-' => {
......@@ -1303,130 +1309,11 @@ pub const Tokenizer = struct {
13031309 state = .float_exponent_num_no_underscore;
13041310 },
13051311 '0'...'9' => {},
1306 else => {
1307 if (isIdentifierChar(c)) {
1308 result.tag = .invalid;
1309 }
1312 'a'...'z', 'A'...'Z' => {
1313 result.tag = .invalid;
13101314 break;
13111315 },
1312 },
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;
1316 else => break,
14301317 },
14311318 }
14321319 }
......@@ -1566,7 +1453,7 @@ test "tokenizer - code point literal with unicode escapes" {
15661453 , &.{ .invalid, .invalid });
15671454 try testTokenize(
15681455 \\'\u{}'
1569 , &.{ .invalid, .invalid });
1456 , &.{.char_literal});
15701457 try testTokenize(
15711458 \\'\u{s}'
15721459 , &.{ .invalid, .invalid });
......@@ -2049,15 +1936,17 @@ test "tokenizer - invalid builtin identifiers" {
20491936 try testTokenize("@0()", &.{ .invalid, .integer_literal, .l_paren, .r_paren });
20501937}
20511938
2052fn testTokenize(source: []const u8, expected_tokens: []const Token.Tag) !void {
1939fn testTokenize(source: [:0]const u8, expected_tokens: []const Token.Tag) !void {
20531940 var tokenizer = Tokenizer.init(source);
20541941 for (expected_tokens) |expected_token_id| {
20551942 const token = tokenizer.next();
20561943 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 });
20581947 }
20591948 }
20601949 const last_token = tokenizer.next();
2061 try std.testing.expect(last_token.tag == .eof);
2062 try std.testing.expect(last_token.loc.start == source.len);
1950 try std.testing.expectEqual(Token.Tag.eof, last_token.tag);
1951 try std.testing.expectEqual(source.len, last_token.loc.start);
20631952}
src/AstGen.zig+321-180
......@@ -34,8 +34,9 @@ string_table: std.StringHashMapUnmanaged(u32) = .{},
3434compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
3535/// The topmost block of the current function.
3636fn_block: ?*GenZir = null,
37/// String table indexes, keeps track of all `@import` operands.
38imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
37/// Maps string table indexes to the first `@import` ZIR instruction
38/// that uses this string as the operand.
39imports: std.AutoArrayHashMapUnmanaged(u32, Zir.Inst.Index) = .{},
3940
4041const InnerError = error{ OutOfMemory, AnalysisFail };
4142
......@@ -154,7 +155,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {
154155 astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{
155156 .imports_len = @intCast(u32, astgen.imports.count()),
156157 });
157 astgen.extra.appendSliceAssumeCapacity(astgen.imports.keys());
158 astgen.extra.appendSliceAssumeCapacity(astgen.imports.values());
158159 }
159160
160161 return Zir{
......@@ -261,6 +262,23 @@ fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zi
261262 return expr(gz, scope, .{ .ty = .type_type }, type_node);
262263}
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
264282fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
265283 const astgen = gz.astgen;
266284 const tree = astgen.tree;
......@@ -1296,22 +1314,23 @@ fn structInitExpr(
12961314 const astgen = gz.astgen;
12971315 const tree = astgen.tree;
12981316
1299 if (struct_init.ast.fields.len == 0) {
1300 if (struct_init.ast.type_expr == 0) {
1317 if (struct_init.ast.type_expr == 0) {
1318 if (struct_init.ast.fields.len == 0) {
13011319 return rvalue(gz, rl, .empty_struct, node);
13021320 }
1303 array: {
1304 const node_tags = tree.nodes.items(.tag);
1305 const main_tokens = tree.nodes.items(.main_token);
1306 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1307 .array_type => tree.arrayType(struct_init.ast.type_expr),
1308 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1309 else => break :array,
1310 };
1321 } else array: {
1322 const node_tags = tree.nodes.items(.tag);
1323 const main_tokens = tree.nodes.items(.main_token);
1324 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1325 .array_type => tree.arrayType(struct_init.ast.type_expr),
1326 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1327 else => break :array,
1328 };
1329 const is_inferred_array_len = node_tags[array_type.ast.elem_count] == .identifier and
13111330 // This intentionally does not support `@"_"` syntax.
1312 if (node_tags[array_type.ast.elem_count] == .identifier and
1313 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))
1314 {
1331 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_");
1332 if (struct_init.ast.fields.len == 0) {
1333 if (is_inferred_array_len) {
13151334 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
13161335 const array_type_inst = if (array_type.ast.sentinel == 0) blk: {
13171336 break :blk try gz.addBin(.array_type, .zero_usize, elem_type);
......@@ -1322,11 +1341,18 @@ fn structInitExpr(
13221341 const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node);
13231342 return rvalue(gz, rl, result, node);
13241343 }
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 );
13251353 }
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);
13291354 }
1355
13301356 switch (rl) {
13311357 .discard => {
13321358 if (struct_init.ast.type_expr != 0)
......@@ -1570,7 +1596,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
15701596 const defer_scope = scope.cast(Scope.Defer).?;
15711597 scope = defer_scope.parent;
15721598 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);
15741600 },
15751601 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
15761602 .top => unreachable,
......@@ -1623,7 +1649,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
16231649 const defer_scope = scope.cast(Scope.Defer).?;
16241650 scope = defer_scope.parent;
16251651 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);
16271653 },
16281654 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
16291655 .namespace => break,
......@@ -1679,7 +1705,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke
16791705 }, &[_]u32{
16801706 try astgen.errNoteTok(
16811707 prev_label.token,
1682 "previous definition is here",
1708 "previous definition here",
16831709 .{},
16841710 ),
16851711 });
......@@ -1785,8 +1811,23 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
17851811 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
17861812 defer block_arena.deinit();
17871813
1814 var noreturn_src_node: ast.Node.Index = 0;
17881815 var scope = parent_scope;
17891816 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 }
17901831 switch (node_tags[statement]) {
17911832 // zig fmt: off
17921833 .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
18141855 .assign_mul => try assignOp(gz, scope, statement, .mul),
18151856 .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),
18181859 // zig fmt: on
18191860 }
18201861 }
......@@ -1823,11 +1864,14 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
18231864 try checkUsed(gz, parent_scope, scope);
18241865}
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 {
18271870 try emitDbgNode(gz, statement);
18281871 // We need to emit an error if the result is not `noreturn` or `void`, but
18291872 // we want to avoid adding the ZIR instruction if possible for performance.
18301873 const maybe_unused_result = try expr(gz, scope, .none, statement);
1874 var noreturn_src_node: ast.Node.Index = 0;
18311875 const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: {
18321876 // Note that this array becomes invalid after appending more items to it
18331877 // in the above while loop.
......@@ -2061,15 +2105,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
20612105 .extended,
20622106 => break :b false,
20632107
2064 // ZIR instructions that are always either `noreturn` or `void`.
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,
2108 // ZIR instructions that are always `noreturn`.
20732109 .@"break",
20742110 .break_inline,
20752111 .condbr,
......@@ -2078,16 +2114,30 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
20782114 .ret_node,
20792115 .ret_coerce,
20802116 .@"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,
20812134 .store,
20822135 .store_node,
20832136 .store_to_block_ptr,
20842137 .store_to_inferred_ptr,
20852138 .resolve_inferred_alloc,
2086 .repeat,
2087 .repeat_inline,
20882139 .validate_struct_init_ptr,
20892140 .validate_array_init_ptr,
2090 .panic,
20912141 .set_align_stack,
20922142 .set_cold,
20932143 .set_float_mode,
......@@ -2097,15 +2147,19 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
20972147 } else switch (maybe_unused_result) {
20982148 .none => unreachable,
20992149
2100 .void_value,
2101 .unreachable_value,
2102 => true,
2150 .unreachable_value => b: {
2151 noreturn_src_node = statement;
2152 break :b true;
2153 },
2154
2155 .void_value => true,
21032156
21042157 else => false,
21052158 };
21062159 if (!elide_check) {
21072160 _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement);
21082161 }
2162 return noreturn_src_node;
21092163}
21102164
21112165fn genDefers(
......@@ -2132,7 +2186,7 @@ fn genDefers(
21322186 const prev_in_defer = gz.in_defer;
21332187 gz.in_defer = true;
21342188 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);
21362190 },
21372191 .defer_error => {
21382192 const defer_scope = scope.cast(Scope.Defer).?;
......@@ -2142,7 +2196,7 @@ fn genDefers(
21422196 const prev_in_defer = gz.in_defer;
21432197 gz.in_defer = true;
21442198 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);
21462200 },
21472201 .namespace => unreachable,
21482202 .top => unreachable,
......@@ -2163,25 +2217,15 @@ fn checkUsed(
21632217 .gen_zir => scope = scope.cast(GenZir).?.parent,
21642218 .local_val => {
21652219 const s = scope.cast(Scope.LocalVal).?;
2166 switch (s.used) {
2167 .used => {},
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", .{}),
2220 if (!s.used) {
2221 return astgen.failTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
21732222 }
21742223 scope = s.parent;
21752224 },
21762225 .local_ptr => {
21772226 const s = scope.cast(Scope.LocalPtr).?;
2178 switch (s.used) {
2179 .used => {},
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,
2227 if (!s.used) {
2228 return astgen.failTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
21852229 }
21862230 scope = s.parent;
21872231 },
......@@ -2221,65 +2265,13 @@ fn varDecl(
22212265 const token_tags = tree.tokens.items(.tag);
22222266
22232267 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 }
22242272 const ident_name = try astgen.identAsString(name_token);
22252273
2226 // Local variables shadowing detection, including function parameters.
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 }
2274 try astgen.detectLocalShadowing(scope, ident_name, name_token);
22832275
22842276 if (var_decl.ast.init_node == 0) {
22852277 return astgen.failNode(node, "variables must be initialized", .{});
......@@ -2303,7 +2295,8 @@ fn varDecl(
23032295 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0) .{
23042296 .ty = try typeExpr(gz, scope, var_decl.ast.type_node),
23052297 } 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
23072300 const sub_scope = try block_arena.create(Scope.LocalVal);
23082301 sub_scope.* = .{
23092302 .parent = scope,
......@@ -2311,7 +2304,7 @@ fn varDecl(
23112304 .name = ident_name,
23122305 .inst = init_inst,
23132306 .token_src = name_token,
2314 .used = .constant,
2307 .id_cat = .@"local constant",
23152308 };
23162309 return &sub_scope.base;
23172310 }
......@@ -2353,7 +2346,8 @@ fn varDecl(
23532346 init_scope.rl_ptr = alloc;
23542347 }
23552348 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
23572351 const zir_tags = astgen.instructions.items(.tag);
23582352 const zir_datas = astgen.instructions.items(.data);
23592353
......@@ -2379,7 +2373,7 @@ fn varDecl(
23792373 .name = ident_name,
23802374 .inst = init_inst,
23812375 .token_src = name_token,
2382 .used = .constant,
2376 .id_cat = .@"local constant",
23832377 };
23842378 return &sub_scope.base;
23852379 }
......@@ -2409,7 +2403,7 @@ fn varDecl(
24092403 .ptr = init_scope.rl_ptr,
24102404 .token_src = name_token,
24112405 .maybe_comptime = true,
2412 .used = .constant,
2406 .id_cat = .@"local constant",
24132407 };
24142408 return &sub_scope.base;
24152409 },
......@@ -2454,7 +2448,7 @@ fn varDecl(
24542448 resolve_inferred_alloc = alloc;
24552449 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };
24562450 };
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);
24582452 if (resolve_inferred_alloc != .none) {
24592453 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
24602454 }
......@@ -2466,7 +2460,7 @@ fn varDecl(
24662460 .ptr = var_data.alloc,
24672461 .token_src = name_token,
24682462 .maybe_comptime = is_comptime,
2469 .used = .variable,
2463 .id_cat = .@"local variable",
24702464 };
24712465 return &sub_scope.base;
24722466 },
......@@ -2956,7 +2950,11 @@ fn fnDecl(
29562950 var it = fn_proto.iterate(tree.*);
29572951 while (it.next()) |param| : (i += 1) {
29582952 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 }
29602958 };
29612959 if (param.type_expr != 0)
29622960 _ = try typeExpr(&fn_gz, params_scope, param.type_expr);
......@@ -2965,7 +2963,7 @@ fn fnDecl(
29652963 const param_name = try astgen.identAsString(name_token);
29662964 // Create an arg instruction. This is needed to emit a semantic analysis
29672965 // error for shadowing decls.
2968 // TODO emit a compile error here for shadowing locals.
2966 try astgen.detectLocalShadowing(params_scope, param_name, name_token);
29692967 const arg_inst = try fn_gz.addStrTok(.arg, param_name, name_token);
29702968 const sub_scope = try astgen.arena.create(Scope.LocalVal);
29712969 sub_scope.* = .{
......@@ -2974,7 +2972,7 @@ fn fnDecl(
29742972 .name = param_name,
29752973 .inst = arg_inst,
29762974 .token_src = name_token,
2977 .used = .fn_param,
2975 .id_cat = .@"function parameter",
29782976 };
29792977 params_scope = &sub_scope.base;
29802978
......@@ -4005,7 +4003,18 @@ fn containerDecl(
40054003 return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{});
40064004 }
40074005 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 );
40094018 }
40104019 // Alignment expressions in enums are caught by the parser.
40114020 assert(member.ast.align_expr == 0);
......@@ -4523,7 +4532,7 @@ fn tryExpr(
45234532 return astgen.failNode(node, "invalid 'try' outside function scope", .{});
45244533 };
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
45284537 var block_scope = parent_gz.makeSubBlock(scope);
45294538 block_scope.setBreakResultLoc(rl);
......@@ -4638,7 +4647,7 @@ fn orelseCatchExpr(
46384647 .name = err_name,
46394648 .inst = try then_scope.addUnNode(unwrap_code_op, operand, node),
46404649 .token_src = payload,
4641 .used = .capture,
4650 .id_cat = .@"capture",
46424651 };
46434652 break :blk &err_val_scope.base;
46444653 };
......@@ -4930,7 +4939,7 @@ fn ifExpr(
49304939 .name = ident_name,
49314940 .inst = payload_inst,
49324941 .token_src = payload_token,
4933 .used = .capture,
4942 .id_cat = .@"capture",
49344943 };
49354944 break :s &payload_val_scope.base;
49364945 } else {
......@@ -4952,7 +4961,7 @@ fn ifExpr(
49524961 .name = ident_name,
49534962 .inst = payload_inst,
49544963 .token_src = ident_token,
4955 .used = .capture,
4964 .id_cat = .@"capture",
49564965 };
49574966 break :s &payload_val_scope.base;
49584967 } else {
......@@ -4993,7 +5002,7 @@ fn ifExpr(
49935002 .name = ident_name,
49945003 .inst = payload_inst,
49955004 .token_src = error_token,
4996 .used = .capture,
5005 .id_cat = .@"capture",
49975006 };
49985007 break :s &payload_val_scope.base;
49995008 } else {
......@@ -5187,7 +5196,7 @@ fn whileExpr(
51875196 .name = ident_name,
51885197 .inst = payload_inst,
51895198 .token_src = payload_token,
5190 .used = .capture,
5199 .id_cat = .@"capture",
51915200 };
51925201 break :s &payload_val_scope.base;
51935202 } else {
......@@ -5209,7 +5218,7 @@ fn whileExpr(
52095218 .name = ident_name,
52105219 .inst = payload_inst,
52115220 .token_src = ident_token,
5212 .used = .capture,
5221 .id_cat = .@"capture",
52135222 };
52145223 break :s &payload_val_scope.base;
52155224 } else {
......@@ -5266,7 +5275,7 @@ fn whileExpr(
52665275 .name = ident_name,
52675276 .inst = payload_inst,
52685277 .token_src = error_token,
5269 .used = .capture,
5278 .id_cat = .@"capture",
52705279 };
52715280 break :s &payload_val_scope.base;
52725281 } else {
......@@ -5405,7 +5414,7 @@ fn forExpr(
54055414 .name = name_str_index,
54065415 .inst = payload_inst,
54075416 .token_src = ident,
5408 .used = .capture,
5417 .id_cat = .@"capture",
54095418 };
54105419 payload_sub_scope = &payload_val_scope.base;
54115420 } else if (is_ptr) {
......@@ -5429,7 +5438,7 @@ fn forExpr(
54295438 .ptr = index_ptr,
54305439 .token_src = index_token,
54315440 .maybe_comptime = is_inline,
5432 .used = .loop_index,
5441 .id_cat = .@"loop index capture",
54335442 };
54345443 break :blk &index_scope.base;
54355444 };
......@@ -5529,7 +5538,7 @@ fn switchExpr(
55295538 &[_]u32{
55305539 try astgen.errNoteTok(
55315540 src,
5532 "previous else prong is here",
5541 "previous else prong here",
55335542 .{},
55345543 ),
55355544 },
......@@ -5542,12 +5551,12 @@ fn switchExpr(
55425551 &[_]u32{
55435552 try astgen.errNoteTok(
55445553 case_src,
5545 "else prong is here",
5554 "else prong here",
55465555 .{},
55475556 ),
55485557 try astgen.errNoteTok(
55495558 some_underscore,
5550 "'_' prong is here",
5559 "'_' prong here",
55515560 .{},
55525561 ),
55535562 },
......@@ -5570,7 +5579,7 @@ fn switchExpr(
55705579 &[_]u32{
55715580 try astgen.errNoteTok(
55725581 src,
5573 "previous '_' prong is here",
5582 "previous '_' prong here",
55745583 .{},
55755584 ),
55765585 },
......@@ -5583,12 +5592,12 @@ fn switchExpr(
55835592 &[_]u32{
55845593 try astgen.errNoteTok(
55855594 some_else,
5586 "else prong is here",
5595 "else prong here",
55875596 .{},
55885597 ),
55895598 try astgen.errNoteTok(
55905599 case_src,
5591 "'_' prong is here",
5600 "'_' prong here",
55925601 .{},
55935602 ),
55945603 },
......@@ -5674,7 +5683,7 @@ fn switchExpr(
56745683 .name = capture_name,
56755684 .inst = capture,
56765685 .token_src = payload_token,
5677 .used = .capture,
5686 .id_cat = .@"capture",
56785687 };
56795688 break :blk &capture_val_scope.base;
56805689 };
......@@ -5768,7 +5777,7 @@ fn switchExpr(
57685777 .name = capture_name,
57695778 .inst = capture,
57705779 .token_src = payload_token,
5771 .used = .capture,
5780 .id_cat = .@"capture",
57725781 };
57735782 break :blk &capture_val_scope.base;
57745783 };
......@@ -6150,10 +6159,11 @@ fn identifier(
61506159 const main_tokens = tree.nodes.items(.main_token);
61516160
61526161 const ident_token = main_tokens[ident];
6153 const ident_name = try astgen.identifierTokenString(ident_token);
6154 if (mem.eql(u8, ident_name, "_")) {
6155 return astgen.failNode(ident, "'_' may not be used as an identifier", .{});
6162 const ident_name_raw = tree.tokenSlice(ident_token);
6163 if (mem.eql(u8, ident_name_raw, "_")) {
6164 return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{});
61566165 }
6166 const ident_name = try astgen.identifierTokenString(ident_token);
61576167
61586168 if (simple_types.get(ident_name)) |zir_const_ref| {
61596169 return rvalue(gz, rl, zir_const_ref, ident);
......@@ -6197,7 +6207,7 @@ fn identifier(
61976207 const local_val = s.cast(Scope.LocalVal).?;
61986208
61996209 if (local_val.name == name_str_index) {
6200 local_val.used = .used;
6210 local_val.used = true;
62016211 // Captures of non-locals need to be emitted as decl_val or decl_ref.
62026212 // This *might* be capturable depending on if it is comptime known.
62036213 if (!hit_namespace) {
......@@ -6209,7 +6219,7 @@ fn identifier(
62096219 .local_ptr => {
62106220 const local_ptr = s.cast(Scope.LocalPtr).?;
62116221 if (local_ptr.name == name_str_index) {
6212 local_ptr.used = .used;
6222 local_ptr.used = true;
62136223 if (hit_namespace) {
62146224 if (local_ptr.maybe_comptime)
62156225 break
......@@ -6333,20 +6343,76 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
63336343 const main_token = main_tokens[node];
63346344 const slice = tree.tokenSlice(main_token);
63356345
6336 var bad_index: usize = undefined;
6337 const value = std.zig.parseCharLiteral(slice, &bad_index) catch |err| switch (err) {
6338 error.InvalidCharacter => {
6339 const bad_byte = slice[bad_index];
6346 switch (std.zig.parseCharLiteral(slice)) {
6347 .success => |codepoint| {
6348 const result = try gz.addInt(codepoint);
6349 return rvalue(gz, rl, result, node);
6350 },
6351 .invalid_escape_character => |bad_index| {
63406352 return astgen.failOff(
63416353 main_token,
63426354 @intCast(u32, bad_index),
6343 "invalid character: '{c}'\n",
6344 .{bad_byte},
6355 "invalid escape character: '{c}'",
6356 .{slice[bad_index]},
63456357 );
63466358 },
6347 };
6348 const result = try gz.addInt(value);
6349 return rvalue(gz, rl, result, node);
6359 .expected_hex_digit => |bad_index| {
6360 return astgen.failOff(
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 }
63506416}
63516417
63526418fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
......@@ -6489,7 +6555,7 @@ fn asmExpr(
64896555 .local_val => {
64906556 const local_val = s.cast(Scope.LocalVal).?;
64916557 if (local_val.name == str_index) {
6492 local_val.used = .used;
6558 local_val.used = true;
64936559 break;
64946560 }
64956561 s = local_val.parent;
......@@ -6497,7 +6563,7 @@ fn asmExpr(
64976563 .local_ptr => {
64986564 const local_ptr = s.cast(Scope.LocalPtr).?;
64996565 if (local_ptr.name == str_index) {
6500 local_ptr.used = .used;
6566 local_ptr.used = true;
65016567 break;
65026568 }
65036569 s = local_ptr.parent;
......@@ -6585,14 +6651,14 @@ fn as(
65856651 const dest_type = try typeExpr(gz, scope, lhs);
65866652 switch (rl) {
65876653 .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);
65896655 return rvalue(gz, rl, result, node);
65906656 },
65916657 .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);
65936659 },
65946660 .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);
65966662 },
65976663 }
65986664}
......@@ -6646,6 +6712,7 @@ fn asRlPtr(
66466712 parent_gz: *GenZir,
66476713 scope: *Scope,
66486714 rl: ResultLoc,
6715 src_node: ast.Node.Index,
66496716 result_ptr: Zir.Inst.Ref,
66506717 operand_node: ast.Node.Index,
66516718 dest_type: Zir.Inst.Ref,
......@@ -6659,7 +6726,7 @@ fn asRlPtr(
66596726 defer as_scope.instructions.deinit(astgen.gpa);
66606727
66616728 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);
66636730 const parent_zir = &parent_gz.instructions;
66646731 if (as_scope.rvalue_rl_count == 1) {
66656732 // Busted! This expression didn't actually need a pointer.
......@@ -6738,13 +6805,14 @@ fn typeOf(
67386805 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});
67396806 }
67406807 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);
67426810 return rvalue(gz, rl, result, node);
67436811 }
67446812 const arena = gz.astgen.arena;
67456813 var items = try arena.alloc(Zir.Inst.Ref, params.len);
67466814 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);
67486816 }
67496817
67506818 const result = try gz.addExtendedMultiOp(.typeof_peer, node, items);
......@@ -6778,7 +6846,7 @@ fn builtinCall(
67786846 if (info.param_count) |expected| {
67796847 if (expected != params.len) {
67806848 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}", .{
67826850 expected, s, params.len,
67836851 });
67846852 }
......@@ -6796,8 +6864,13 @@ fn builtinCall(
67966864 }
67976865 const str_lit_token = main_tokens[operand_node];
67986866 const str = try astgen.strLitAsString(str_lit_token);
6799 try astgen.imports.put(astgen.gpa, str.index, {});
68006867 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 }
68016874 return rvalue(gz, rl, result, node);
68026875 },
68036876 .compile_log => {
......@@ -6846,7 +6919,7 @@ fn builtinCall(
68466919 .local_val => {
68476920 const local_val = s.cast(Scope.LocalVal).?;
68486921 if (local_val.name == decl_name) {
6849 local_val.used = .used;
6922 local_val.used = true;
68506923 break;
68516924 }
68526925 s = local_val.parent;
......@@ -6856,7 +6929,7 @@ fn builtinCall(
68566929 if (local_ptr.name == decl_name) {
68576930 if (!local_ptr.maybe_comptime)
68586931 return astgen.failNode(params[0], "unable to export runtime-known value", .{});
6859 local_ptr.used = .used;
6932 local_ptr.used = true;
68606933 break;
68616934 }
68626935 s = local_ptr.parent;
......@@ -8423,15 +8496,15 @@ const Scope = struct {
84238496 top,
84248497 };
84258498
8426 // either .used or the type of the var/constant
8427 const Used = enum {
8428 fn_param,
8429 constant,
8430 variable,
8431 loop_index,
8432 capture,
8433 used,
8499 /// The category of identifier. These tag names are user-visible in compile errors.
8500 const IdCat = enum {
8501 @"function parameter",
8502 @"local constant",
8503 @"local variable",
8504 @"loop index capture",
8505 @"capture",
84348506 };
8507
84358508 /// This is always a `const` local and importantly the `inst` is a value type, not a pointer.
84368509 /// This structure lives as long as the AST generation of the Block
84378510 /// node that contains the variable.
......@@ -8446,8 +8519,9 @@ const Scope = struct {
84468519 token_src: ast.TokenIndex,
84478520 /// String table index.
84488521 name: u32,
8449 /// has this variable been referenced?
8450 used: Used,
8522 id_cat: IdCat,
8523 /// Track whether the name has been referenced.
8524 used: bool = false,
84518525 };
84528526
84538527 /// This could be a `const` or `var` local. It has a pointer instead of a value.
......@@ -8464,10 +8538,12 @@ const Scope = struct {
84648538 token_src: ast.TokenIndex,
84658539 /// String table index.
84668540 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.
84688544 maybe_comptime: bool,
8469 /// has this variable been referenced?
8470 used: Used,
8545 /// Track whether the name has been referenced.
8546 used: bool = false,
84718547 };
84728548
84738549 const Defer = struct {
......@@ -9558,6 +9634,71 @@ fn declareNewName(
95589634 }
95599635}
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
95619702fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {
95629703 var i = astgen.source_offset;
95639704 var line = astgen.source_line;
src/Compilation.zig+87-31
......@@ -670,6 +670,7 @@ pub const InitOptions = struct {
670670 use_llvm: ?bool = null,
671671 use_lld: ?bool = null,
672672 use_clang: ?bool = null,
673 use_stage1: ?bool = null,
673674 rdynamic: bool = false,
674675 strip: bool = false,
675676 single_threaded: bool = false,
......@@ -807,8 +808,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
807808
808809 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
810822 // 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
812827 // If we have no zig code to compile, no need for LLVM.
813828 if (options.root_pkg == null)
814829 break :blk false;
......@@ -817,18 +832,24 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
817832 if (ofmt == .c)
818833 break :blk false;
819834
820 // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend
835 // The stage1 compiler depends on the stage1 C++ LLVM backend
821836 // 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))
823842 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.
828844 break :blk false;
829845 };
830 if (!use_llvm and options.machine_code_model != .default) {
831 return error.MachineCodeModelNotSupported;
846 if (!use_llvm) {
847 if (options.use_llvm == true) {
848 return error.ZigCompilerNotBuiltWithLLVMExtensions;
849 }
850 if (options.machine_code_model != .default) {
851 return error.MachineCodeModelNotSupportedWithoutLlvm;
852 }
832853 }
833854
834855 const tsan = options.want_tsan orelse false;
......@@ -1344,6 +1365,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
13441365 .subsystem = options.subsystem,
13451366 .is_test = options.is_test,
13461367 .wasi_exec_model = wasi_exec_model,
1368 .use_stage1 = use_stage1,
13471369 });
13481370 errdefer bin_file.destroy();
13491371 comp.* = .{
......@@ -1486,9 +1508,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
14861508 try comp.work_queue.writeItem(.libtsan);
14871509 }
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.
14901512 // Once it is capable this condition should be removed.
1491 if (build_options.is_stage1) {
1513 if (comp.bin_file.options.use_stage1) {
14921514 if (comp.bin_file.options.include_compiler_rt) {
14931515 if (is_exe_or_dyn_lib) {
14941516 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
......@@ -1519,7 +1541,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
15191541 }
15201542 }
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) {
15231545 try comp.work_queue.writeItem(.{ .stage1_module = {} });
15241546 }
15251547
......@@ -1625,8 +1647,7 @@ pub fn update(self: *Compilation) !void {
16251647 self.c_object_work_queue.writeItemAssumeCapacity(key);
16261648 }
16271649
1628 const use_stage1 = build_options.omit_stage2 or
1629 (build_options.is_stage1 and self.bin_file.options.use_llvm);
1650 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;
16301651 if (self.bin_file.options.module) |module| {
16311652 module.compile_log_text.shrinkAndFree(module.gpa, 0);
16321653 module.generation += 1;
......@@ -1921,7 +1942,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
19211942 // (at least for now) single-threaded main work queue. However, C object compilation
19221943 // 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);
19251946 defer zir_prog_node.end();
19261947
19271948 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
19371958 while (self.astgen_work_queue.readItem()) |file| {
19381959 self.astgen_wait_group.start();
19391960 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,
19411962 });
19421963 }
19431964
......@@ -1949,13 +1970,18 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
19491970 }
19501971 }
19511972
1952 const use_stage1 = build_options.omit_stage2 or
1953 (build_options.is_stage1 and self.bin_file.options.use_llvm);
1973 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;
19541974 if (!use_stage1) {
19551975 // Iterate over all the files and look for outdated and deleted declarations.
19561976 if (self.bin_file.options.module) |mod| {
19571977 try mod.processOutdatedAndDeletedDecls();
19581978 }
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 }
19591985 }
19601986
19611987 while (self.work_queue.readItem()) |work_item| switch (work_item) {
......@@ -2284,11 +2310,20 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
22842310 };
22852311}
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
22872321fn workerAstGenFile(
22882322 comp: *Compilation,
22892323 file: *Module.Scope.File,
22902324 prog_node: *std.Progress.Node,
22912325 wg: *WaitGroup,
2326 src: AstGenSrc,
22922327) void {
22932328 defer wg.finish();
22942329
......@@ -2301,7 +2336,7 @@ fn workerAstGenFile(
23012336 error.AnalysisFail => return,
23022337 else => {
23032338 file.status = .retryable_failure;
2304 comp.reportRetryableAstGenError(file, err) catch |oom| switch (oom) {
2339 comp.reportRetryableAstGenError(src, file, err) catch |oom| switch (oom) {
23052340 // Swallowing this error is OK because it's implied to be OOM when
23062341 // there is a missing `failed_files` error message.
23072342 error.OutOfMemory => {},
......@@ -2318,8 +2353,9 @@ fn workerAstGenFile(
23182353 if (imports_index != 0) {
23192354 const imports_len = file.zir.extra[imports_index];
23202355
2321 for (file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| {
2322 const import_path = file.zir.nullTerminatedString(str_index);
2356 for (file.zir.extra[imports_index + 1 ..][0..imports_len]) |import_inst| {
2357 const inst_data = file.zir.instructions.items(.data)[import_inst].str_tok;
2358 const import_path = inst_data.get(file.zir);
23232359
23242360 const import_result = blk: {
23252361 const lock = comp.mutex.acquire();
......@@ -2331,9 +2367,13 @@ fn workerAstGenFile(
23312367 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
23322368 file.sub_file_path, import_path, import_result.file.sub_file_path,
23332369 });
2370 const sub_src: AstGenSrc = .{ .import = .{
2371 .importing_file = file,
2372 .import_inst = import_inst,
2373 } };
23342374 wg.start();
23352375 comp.thread_pool.spawn(workerAstGenFile, .{
2336 comp, import_result.file, prog_node, wg,
2376 comp, import_result.file, prog_node, wg, sub_src,
23372377 }) catch {
23382378 wg.finish();
23392379 continue;
......@@ -2544,6 +2584,7 @@ fn reportRetryableCObjectError(
25442584
25452585fn reportRetryableAstGenError(
25462586 comp: *Compilation,
2587 src: AstGenSrc,
25472588 file: *Module.Scope.File,
25482589 err: anyerror,
25492590) error{OutOfMemory}!void {
......@@ -2552,22 +2593,38 @@ fn reportRetryableAstGenError(
25522593
25532594 file.status = .retryable_failure;
25542595
2555 const src_loc: Module.SrcLoc = .{
2556 .file_scope = file,
2557 .parent_decl_node = 0,
2558 .lazy = .entire_file,
2596 const src_loc: Module.SrcLoc = switch (src) {
2597 .root => .{
2598 .file_scope = 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 },
25592612 };
25602613
25612614 const err_msg = if (file.pkg.root_src_directory.path) |dir_path|
25622615 try Module.ErrorMsg.create(
25632616 gpa,
25642617 src_loc,
2565 "unable to load {s}" ++ std.fs.path.sep_str ++ "{s}: {s}",
2566 .{ dir_path, file.sub_file_path, @errorName(err) },
2618 "unable to load '{'}" ++ std.fs.path.sep_str ++ "{'}': {s}",
2619 .{
2620 std.zig.fmtEscapes(dir_path),
2621 std.zig.fmtEscapes(file.sub_file_path),
2622 @errorName(err),
2623 },
25672624 )
25682625 else
2569 try Module.ErrorMsg.create(gpa, src_loc, "unable to load {s}: {s}", .{
2570 file.sub_file_path, @errorName(err),
2626 try Module.ErrorMsg.create(gpa, src_loc, "unable to load '{'}': {s}", .{
2627 std.zig.fmtEscapes(file.sub_file_path), @errorName(err),
25712628 });
25722629 errdefer err_msg.destroy(gpa);
25732630
......@@ -3486,8 +3543,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
34863543
34873544 const target = comp.getTarget();
34883545 const generic_arch_name = target.cpu.arch.genericName();
3489 const use_stage1 = build_options.omit_stage2 or
3490 (build_options.is_stage1 and comp.bin_file.options.use_llvm);
3546 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
34913547
34923548 @setEvalBranchQuota(4000);
34933549 try buffer.writer().print(
src/Module.zig+10
......@@ -2466,6 +2466,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
24662466 defer msg.deinit();
24672467
24682468 const token_starts = file.tree.tokens.items(.start);
2469 const token_tags = file.tree.tokens.items(.tag);
24692470
24702471 try file.tree.renderError(parse_err, msg.writer());
24712472 const err_msg = try gpa.create(ErrorMsg);
......@@ -2477,6 +2478,15 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
24772478 },
24782479 .msg = msg.toOwnedSlice(),
24792480 };
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
24812491 {
24822492 const lock = comp.mutex.acquire();
src/Zir.zig+12-5
......@@ -139,9 +139,15 @@ pub fn renderAsTextToFile(
139139 if (imports_index != 0) {
140140 try fs_file.writeAll("Imports:\n");
141141 const imports_len = scope_file.zir.extra[imports_index];
142 for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| {
143 const import_path = scope_file.zir.nullTerminatedString(str_index);
144 try fs_file.writer().print(" {s}\n", .{import_path});
142 for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |import_inst| {
143 const inst_data = writer.code.instructions.items(.data)[import_inst].str_tok;
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");
145151 }
146152 }
147153}
......@@ -2767,9 +2773,10 @@ pub const Inst = struct {
27672773 };
27682774 };
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.
27712778 pub const Imports = struct {
2772 imports_len: u32,
2779 imports_len: Zir.Inst.Index,
27732780 };
27742781};
27752782
src/link.zig+3-2
......@@ -92,6 +92,7 @@ pub const Options = struct {
9292 each_lib_rpath: bool,
9393 disable_lld_caching: bool,
9494 is_test: bool,
95 use_stage1: bool,
9596 major_subsystem_version: ?u32,
9697 minor_subsystem_version: ?u32,
9798 gc_sections: ?bool = null,
......@@ -181,7 +182,7 @@ pub const File = struct {
181182 /// rewriting it. A malicious file is detected as incremental link failure
182183 /// and does not cause Illegal Behavior. This operation is not atomic.
183184 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;
185186 if (use_stage1 or options.emit == null) {
186187 return switch (options.object_format) {
187188 .coff, .pe => &(try Coff.createEmpty(allocator, options)).base,
......@@ -507,7 +508,7 @@ pub const File = struct {
507508 // If there is no Zig code to compile, then we should skip flushing the output file because it
508509 // will not be part of the linker line anyway.
509510 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;
511512 if (use_stage1) {
512513 const obj_basename = try std.zig.binNameAlloc(arena, .{
513514 .root_name = base.options.root_name,
src/link/MachO.zig+1-1
......@@ -606,7 +606,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
606606 // If there is no Zig code to compile, then we should skip flushing the output file because it
607607 // will not be part of the linker line anyway.
608608 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;
610610 if (use_stage1) {
611611 const obj_basename = try std.zig.binNameAlloc(arena, .{
612612 .root_name = self.base.options.root_name,
src/link/Wasm.zig+1-1
......@@ -556,7 +556,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
556556 // If there is no Zig code to compile, then we should skip flushing the output file because it
557557 // will not be part of the linker line anyway.
558558 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;
560560 if (use_stage1) {
561561 const obj_basename = try std.zig.binNameAlloc(arena, .{
562562 .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
233233 } else if (mem.eql(u8, cmd, "build")) {
234234 return cmdBuild(gpa, arena, cmd_args);
235235 } else if (mem.eql(u8, cmd, "fmt")) {
236 return cmdFmt(gpa, cmd_args);
236 return cmdFmt(gpa, arena, cmd_args);
237237 } else if (mem.eql(u8, cmd, "libc")) {
238238 return cmdLibC(gpa, cmd_args);
239239 } else if (mem.eql(u8, cmd, "init-exe")) {
......@@ -350,9 +350,11 @@ const usage_build_generic =
350350 \\ -funwind-tables Always produce unwind table entries for all functions
351351 \\ -fno-unwind-tables Never produce unwind table entries
352352 \\ -fLLVM Force using LLVM as the codegen backend
353 \\ -fno-LLVM Prevent using LLVM as a codegen backend
353 \\ -fno-LLVM Prevent using LLVM as the codegen backend
354354 \\ -fClang Force using Clang as the C/C++ compilation backend
355355 \\ -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
356358 \\ --strip Omit debug symbols
357359 \\ --single-threaded Code assumes it is only used single-threaded
358360 \\ -ofmt=[mode] Override target object format
......@@ -602,6 +604,7 @@ fn buildOutputType(
602604 var use_llvm: ?bool = null;
603605 var use_lld: ?bool = null;
604606 var use_clang: ?bool = null;
607 var use_stage1: ?bool = null;
605608 var link_eh_frame_hdr = false;
606609 var link_emit_relocs = false;
607610 var each_lib_rpath: ?bool = null;
......@@ -975,6 +978,10 @@ fn buildOutputType(
975978 use_clang = true;
976979 } else if (mem.eql(u8, arg, "-fno-Clang")) {
977980 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;
978985 } else if (mem.eql(u8, arg, "-rdynamic")) {
979986 rdynamic = true;
980987 } else if (mem.eql(u8, arg, "-fsoname")) {
......@@ -2020,6 +2027,7 @@ fn buildOutputType(
20202027 .use_llvm = use_llvm,
20212028 .use_lld = use_lld,
20222029 .use_clang = use_clang,
2030 .use_stage1 = use_stage1,
20232031 .rdynamic = rdynamic,
20242032 .linker_script = linker_script,
20252033 .version_script = version_script,
......@@ -3031,12 +3039,13 @@ const Fmt = struct {
30313039 check_ast: bool,
30323040 color: Color,
30333041 gpa: *Allocator,
3042 arena: *Allocator,
30343043 out_buffer: std.ArrayList(u8),
30353044
30363045 const SeenMap = std.AutoHashMap(fs.File.INode, void);
30373046};
30383047
3039pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
3048pub fn cmdFmt(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void {
30403049 var color: Color = .auto;
30413050 var stdin_flag: bool = false;
30423051 var check_flag: bool = false;
......@@ -3094,7 +3103,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
30943103 defer tree.deinit(gpa);
30953104
30963105 for (tree.errors) |parse_error| {
3097 try printErrMsgToStdErr(gpa, parse_error, tree, "<stdin>", color);
3106 try printErrMsgToStdErr(gpa, arena, parse_error, tree, "<stdin>", color);
30983107 }
30993108 var has_ast_error = false;
31003109 if (check_ast_flag) {
......@@ -3162,6 +3171,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
31623171
31633172 var fmt = Fmt{
31643173 .gpa = gpa,
3174 .arena = arena,
31653175 .seen = Fmt.SeenMap.init(gpa),
31663176 .any_error = false,
31673177 .check_ast = check_ast_flag,
......@@ -3285,7 +3295,7 @@ fn fmtPathFile(
32853295 defer tree.deinit(fmt.gpa);
32863296
32873297 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);
32893299 }
32903300 if (tree.errors.len != 0) {
32913301 fmt.any_error = true;
......@@ -3366,12 +3376,14 @@ fn fmtPathFile(
33663376
33673377fn printErrMsgToStdErr(
33683378 gpa: *mem.Allocator,
3379 arena: *mem.Allocator,
33693380 parse_error: ast.Error,
33703381 tree: ast.Tree,
33713382 path: []const u8,
33723383 color: Color,
33733384) !void {
33743385 const lok_token = parse_error.token;
3386 const token_tags = tree.tokens.items(.tag);
33753387 const start_loc = tree.tokenLocation(0, lok_token);
33763388 const source_line = tree.source[start_loc.line_start..start_loc.line_end];
33773389
......@@ -3381,6 +3393,27 @@ fn printErrMsgToStdErr(
33813393 try tree.renderError(parse_error, writer);
33823394 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
33843417 const message: Compilation.AllErrors.Message = .{
33853418 .src = .{
33863419 .src_path = path,
......@@ -3389,6 +3422,7 @@ fn printErrMsgToStdErr(
33893422 .line = @intCast(u32, start_loc.line),
33903423 .column = @intCast(u32, start_loc.column),
33913424 .source_line = source_line,
3425 .notes = notes_buffer[0..notes_len],
33923426 },
33933427 };
33943428
......@@ -3915,7 +3949,7 @@ pub fn cmdAstCheck(
39153949 defer file.tree.deinit(gpa);
39163950
39173951 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);
39193953 }
39203954 if (file.tree.errors.len != 0) {
39213955 process.exit(1);
......@@ -4041,7 +4075,7 @@ pub fn cmdChangelist(
40414075 defer file.tree.deinit(gpa);
40424076
40434077 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);
40454079 }
40464080 if (file.tree.errors.len != 0) {
40474081 process.exit(1);
......@@ -4080,7 +4114,7 @@ pub fn cmdChangelist(
40804114 defer new_tree.deinit(gpa);
40814115
40824116 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);
40844118 }
40854119 if (new_tree.errors.len != 0) {
40864120 process.exit(1);
src/stage1.zig+9-4
......@@ -7,6 +7,7 @@ const assert = std.debug.assert;
77const mem = std.mem;
88const CrossTarget = std.zig.CrossTarget;
99const Target = std.Target;
10const builtin = @import("builtin");
1011
1112const build_options = @import("build_options");
1213const stage2 = @import("main.zig");
......@@ -16,16 +17,19 @@ const translate_c = @import("translate_c.zig");
1617const target_util = @import("target.zig");
1718
1819comptime {
19 assert(std.builtin.link_libc);
20 assert(builtin.link_libc);
2021 assert(build_options.is_stage1);
2122 assert(build_options.have_llvm);
22 _ = @import("compiler_rt");
23 if (!builtin.is_test) {
24 _ = @import("compiler_rt");
25 @export(main, .{ .name = "main" });
26 }
2327}
2428
2529pub const log = stage2.log;
2630pub 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 {
2933 std.os.argv = argv[0..@intCast(usize, argc)];
3034
3135 std.debug.maybeEnableSegfaultHandler();
......@@ -41,7 +45,7 @@ pub export fn main(argc: c_int, argv: [*][*:0]u8) c_int {
4145 for (args) |*arg, i| {
4246 arg.* = mem.spanZ(argv[i]);
4347 }
44 if (std.builtin.mode == .Debug) {
48 if (builtin.mode == .Debug) {
4549 stage2.mainArgs(gpa, arena, args) catch unreachable;
4650 } else {
4751 stage2.mainArgs(gpa, arena, args) catch |err| fatal("{s}", .{@errorName(err)});
......@@ -147,6 +151,7 @@ pub const Module = extern struct {
147151 }
148152};
149153
154pub const os_init = zig_stage1_os_init;
150155extern fn zig_stage1_os_init() void;
151156
152157pub const create = zig_stage1_create;
src/stage1/all_types.hpp-4
......@@ -2733,10 +2733,6 @@ struct IrInstSrc {
27332733 IrInst base;
27342734
27352735 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
27412737 // When analyzing IR, instructions that point to this instruction in the "old ir"
27422738 // 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) {
39153915 }
39163916 }
39173917 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"));
39193919 return;
39203920 }
39213921
......@@ -4176,7 +4176,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
41764176 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
41774177 ErrorMsg *msg = add_node_error(g, source_node,
41784178 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"));
41804180 }
41814181 variable_entry->var_type = g->builtin_types.entry_invalid;
41824182 } else {
......@@ -4205,7 +4205,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
42054205 if (want_err_msg) {
42064206 ErrorMsg *msg = add_node_error(g, source_node,
42074207 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"));
42094209 }
42104210 variable_entry->var_type = g->builtin_types.entry_invalid;
42114211 }
src/stage1/astgen.cpp+74-81
......@@ -55,7 +55,17 @@ static ErrorMsg *exec_add_error_node(CodeGen *codegen, Stage1Zir *exec, AstNode
5555
5656
5757static 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 }
5969}
6070
6171void destroy_instruction_src(IrInstSrc *inst) {
......@@ -947,7 +957,6 @@ static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *sour
947957 Stage1ZirBasicBlock *then_block, Stage1ZirBasicBlock *else_block, IrInstSrc *is_comptime)
948958{
949959 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(ag, scope, source_node);
950 inst->base.is_noreturn = true;
951960 inst->condition = condition;
952961 inst->then_block = then_block;
953962 inst->else_block = else_block;
......@@ -963,7 +972,6 @@ static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *sour
963972
964973static IrInstSrc *ir_build_return_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *operand) {
965974 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(ag, scope, source_node);
966 inst->base.is_noreturn = true;
967975 inst->operand = operand;
968976
969977 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
13031311 Stage1ZirBasicBlock *dest_block, IrInstSrc *is_comptime)
13041312{
13051313 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(ag, scope, source_node);
1306 inst->base.is_noreturn = true;
13071314 inst->dest_block = dest_block;
13081315 inst->is_comptime = is_comptime;
13091316
......@@ -1418,7 +1425,6 @@ static IrInstSrc *ir_build_container_init_fields(Stage1AstGen *ag, Scope *scope,
14181425
14191426static IrInstSrc *ir_build_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
14201427 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(ag, scope, source_node);
1421 inst->base.is_noreturn = true;
14221428 return &inst->base;
14231429}
14241430
......@@ -1718,7 +1724,6 @@ static IrInstSrcSwitchBr *ir_build_switch_br_src(Stage1AstGen *ag, Scope *scope,
17181724 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void)
17191725{
17201726 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(ag, scope, source_node);
1721 instruction->base.is_noreturn = true;
17221727 instruction->target_value = target_value;
17231728 instruction->else_block = else_block;
17241729 instruction->case_count = case_count;
......@@ -2439,7 +2444,6 @@ static IrInstSrc *ir_build_decl_ref(Stage1AstGen *ag, Scope *scope, AstNode *sou
24392444
24402445static IrInstSrc *ir_build_panic_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *msg) {
24412446 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(ag, scope, source_node);
2442 instruction->base.is_noreturn = true;
24432447 instruction->msg = msg;
24442448
24452449 ir_ref_instruction(msg, ag->current_basic_block);
......@@ -2557,7 +2561,6 @@ static IrInstSrc *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode
25572561{
25582562 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(ag, scope, source_node);
25592563 instruction->result_loc = result_loc;
2560 instruction->base.is_gen = true;
25612564
25622565 return &instruction->base;
25632566}
......@@ -2737,7 +2740,6 @@ static IrInstSrc *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *s
27372740 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)
27382741{
27392742 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(ag, scope, source_node);
2740 instruction->base.is_gen = true;
27412743 instruction->align = align;
27422744 instruction->name_hint = name_hint;
27432745 instruction->is_comptime = is_comptime;
......@@ -2752,7 +2754,6 @@ static IrInstSrc *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *sou
27522754 IrInstSrc *value, ResultLoc *result_loc)
27532755{
27542756 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(ag, scope, source_node);
2755 instruction->base.is_gen = true;
27562757 instruction->value = value;
27572758 instruction->result_loc = result_loc;
27582759
......@@ -2885,11 +2886,6 @@ static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_s
28852886 }
28862887}
28872888
2888static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) {
2889 instruction->is_gen = true;
2890 return instruction;
2891}
2892
28932889static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {
28942890 Scope *scope = inner_scope;
28952891 if (is_noreturn != nullptr) *is_noreturn = false;
......@@ -2945,11 +2941,11 @@ static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope
29452941 if (defer_expr_value == ag->codegen->invalid_inst_src)
29462942 return ag->codegen->invalid_inst_src;
29472943
2948 if (defer_expr_value->is_noreturn) {
2944 if (instr_is_unreachable(defer_expr_value)) {
29492945 if (is_noreturn != nullptr) *is_noreturn = true;
29502946 } else {
2951 ir_mark_gen(ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,
2952 defer_expr_value));
2947 ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,
2948 defer_expr_value);
29532949 }
29542950 scope = scope->parent;
29552951 continue;
......@@ -3047,7 +3043,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
30473043 ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);
30483044 }
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
30523048 size_t defer_counts[2];
30533049 ir_count_defers(ag, scope, outer_scope, defer_counts);
......@@ -3074,7 +3070,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
30743070 is_comptime = ir_build_test_comptime(ag, scope, node, is_err);
30753071 }
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);
30783074 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");
30793075
30803076 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
31123108 } else {
31133109 is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);
31143110 }
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
31173113 ir_set_cursor_at_end_and_append_block(ag, return_block);
31183114 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);
31193115 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);
31213117 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,
31223118 SpillIdRetErrCode);
31233119 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
......@@ -3173,7 +3169,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
31733169 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
31743170 ErrorMsg *msg = add_node_error(codegen, node,
31753171 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"));
31773173 }
31783174 variable_entry->var_type = codegen->builtin_types.entry_invalid;
31793175 } else {
......@@ -3195,7 +3191,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
31953191 if (want_err_msg) {
31963192 ErrorMsg *msg = add_node_error(codegen, node,
31973193 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"));
31993195 }
32003196 variable_entry->var_type = codegen->builtin_types.entry_invalid;
32013197 }
......@@ -3251,7 +3247,7 @@ static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *nam
32513247 Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
32523248 if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
32533249 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"));
32553251 return true;
32563252 }
32573253 }
......@@ -3338,7 +3334,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
33383334 child_scope = decl_var_instruction->var->child_scope;
33393335 } else if (!is_continuation_unreachable) {
33403336 // 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);
33423338 }
33433339 }
33443340
......@@ -3364,7 +3360,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
33643360 return ir_expr_wrap(ag, parent_scope, phi, result_loc);
33653361 } else {
33663362 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
33693365 if (scope_block->peer_parent != nullptr) {
33703366 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
33873383
33883384 IrInstSrc *result;
33893385 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);
33913387 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
33923388 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
33933389 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
33943390 result = ir_expr_wrap(ag, parent_scope, phi, result_loc);
33953391 } 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);
33973393 result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);
33983394 }
33993395 if (!is_return_from_fn)
......@@ -3402,14 +3398,14 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
34023398 // no need for save_err_ret_addr because this cannot return error
34033399 // 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);
34063402 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
34073403 result_loc_ret->base.id = ResultLocIdReturn;
34083404 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);
34103406 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
34113407 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);
34133409}
34143410
34153411static 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 *
36283624 return ag->codegen->invalid_inst_src;
36293625 Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;
36303626 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
36333629 ir_set_cursor_at_end_and_append_block(ag, ok_block);
36343630 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
53955391 return ag->codegen->invalid_inst_src;
53965392 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
53975393 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
54005396 ir_set_cursor_at_end_and_append_block(ag, else_block);
54015397 IrInstSrc *else_expr_result;
......@@ -5409,7 +5405,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n
54095405 }
54105406 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
54115407 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
54145410 ir_set_cursor_at_end_and_append_block(ag, endif_block);
54155411 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
......@@ -5954,12 +5950,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
59545950 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,
59555951 true, false);
59565952 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);
59585954 IrInstSrc *cond_br_inst;
59595955 if (!instr_is_unreachable(is_err)) {
59605956 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,
59615957 else_block, body_block, is_comptime);
5962 cond_br_inst->is_gen = true;
59635958 } else {
59645959 // for the purposes of the source instruction to ir_build_result_peers
59655960 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
60056000 }
60066001
60076002 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));
6009 ir_mark_gen(ir_build_br(ag, payload_scope, node, continue_block, is_comptime));
6003 ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result);
6004 ir_build_br(ag, payload_scope, node, continue_block, is_comptime);
60106005 }
60116006
60126007 if (continue_expr_node) {
......@@ -6015,8 +6010,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
60156010 if (expr_result == ag->codegen->invalid_inst_src)
60166011 return expr_result;
60176012 if (!instr_is_unreachable(expr_result)) {
6018 ir_mark_gen(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));
6013 ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result);
6014 ir_build_br(ag, payload_scope, node, cond_block, is_comptime);
60206015 }
60216016 }
60226017
......@@ -6041,7 +6036,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
60416036 if (else_result == ag->codegen->invalid_inst_src)
60426037 return else_result;
60436038 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);
60456040 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
60466041 ir_set_cursor_at_end_and_append_block(ag, end_block);
60476042 if (else_result) {
......@@ -6075,12 +6070,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
60756070 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);
60766071 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);
60776072 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);
60796074 IrInstSrc *cond_br_inst;
60806075 if (!instr_is_unreachable(is_non_null)) {
60816076 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,
60826077 body_block, else_block, is_comptime);
6083 cond_br_inst->is_gen = true;
60846078 } else {
60856079 // for the purposes of the source instruction to ir_build_result_peers
60866080 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
61236117 }
61246118
61256119 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));
6127 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));
6120 ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result);
6121 ir_build_br(ag, child_scope, node, continue_block, is_comptime);
61286122 }
61296123
61306124 if (continue_expr_node) {
......@@ -6133,8 +6127,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
61336127 if (expr_result == ag->codegen->invalid_inst_src)
61346128 return expr_result;
61356129 if (!instr_is_unreachable(expr_result)) {
6136 ir_mark_gen(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));
6130 ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result);
6131 ir_build_br(ag, child_scope, node, cond_block, is_comptime);
61386132 }
61396133 }
61406134
......@@ -6151,7 +6145,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
61516145 if (else_result == ag->codegen->invalid_inst_src)
61526146 return else_result;
61536147 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);
61556149 }
61566150 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
61576151 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
61756169 if (cond_val == ag->codegen->invalid_inst_src)
61766170 return cond_val;
61776171 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);
61796173 IrInstSrc *cond_br_inst;
61806174 if (!instr_is_unreachable(cond_val)) {
61816175 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,
61826176 body_block, else_block, is_comptime);
6183 cond_br_inst->is_gen = true;
61846177 } else {
61856178 // for the purposes of the source instruction to ir_build_result_peers
61866179 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
62196212 }
62206213
62216214 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));
6223 ir_mark_gen(ir_build_br(ag, scope, node, continue_block, is_comptime));
6215 ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result);
6216 ir_build_br(ag, scope, node, continue_block, is_comptime);
62246217 }
62256218
62266219 if (continue_expr_node) {
......@@ -6229,8 +6222,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
62296222 if (expr_result == ag->codegen->invalid_inst_src)
62306223 return expr_result;
62316224 if (!instr_is_unreachable(expr_result)) {
6232 ir_mark_gen(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));
6225 ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result);
6226 ir_build_br(ag, scope, node, cond_block, is_comptime);
62346227 }
62356228 }
62366229
......@@ -6248,7 +6241,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
62486241 if (else_result == ag->codegen->invalid_inst_src)
62496242 return else_result;
62506243 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);
62526245 }
62536246 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
62546247 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
63326325 IrInstSrc *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);
63336326 IrInstSrc *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
63346327 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));
6336 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(ag, parent_scope, node, cond,
6337 body_block, else_block, is_comptime));
6328 IrInstSrc *void_else_value = else_node ? nullptr : ir_build_const_void(ag, parent_scope, node);
6329 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, cond,
6330 body_block, else_block, is_comptime);
63386331
63396332 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
63776370 }
63786371
63796372 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));
6381 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));
6373 ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result);
6374 ir_build_br(ag, child_scope, node, continue_block, is_comptime);
63826375 }
63836376
63846377 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
63996392 if (else_result == ag->codegen->invalid_inst_src)
64006393 return else_result;
64016394 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);
64036396 }
64046397 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
64056398 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
67196712 return then_expr_result;
67206713 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
67216714 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
67246717 ir_set_cursor_at_end_and_append_block(ag, else_block);
67256718 IrInstSrc *else_expr_result;
......@@ -6733,7 +6726,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod
67336726 }
67346727 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
67356728 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
67386731 ir_set_cursor_at_end_and_append_block(ag, endif_block);
67396732 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
68026795 return then_expr_result;
68036796 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
68046797 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
68076800 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
68316824 }
68326825 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
68336826 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
68366829 ir_set_cursor_at_end_and_append_block(ag, endif_block);
68376830 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
68936886 if (expr_result == ag->codegen->invalid_inst_src)
68946887 return false;
68956888 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);
68976890 incoming_blocks->append(ag->current_basic_block);
68986891 incoming_values->append(expr_result);
68996892 return true;
......@@ -7008,8 +7001,8 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
70087001
70097002 assert(ok_bit);
70107003 assert(last_item_node);
7011 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(ag, scope, last_item_node, ok_bit,
7012 range_block_yes, range_block_no, is_comptime));
7004 IrInstSrc *br_inst = ir_build_cond_br(ag, scope, last_item_node, ok_bit,
7005 range_block_yes, range_block_no, is_comptime);
70137006 if (peer_parent->base.source_instruction == nullptr) {
70147007 peer_parent->base.source_instruction = br_inst;
70157008 }
......@@ -7033,7 +7026,7 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
70337026 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
70347027 buf_sprintf("multiple else prongs in switch expression"));
70357028 add_error_note(ag->codegen, msg, else_prong,
7036 buf_sprintf("previous else prong is here"));
7029 buf_sprintf("previous else prong here"));
70377030 return ag->codegen->invalid_inst_src;
70387031 }
70397032 else_prong = prong_node;
......@@ -7044,7 +7037,7 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
70447037 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
70457038 buf_sprintf("multiple '_' prongs in switch expression"));
70467039 add_error_note(ag->codegen, msg, underscore_prong,
7047 buf_sprintf("previous '_' prong is here"));
7040 buf_sprintf("previous '_' prong here"));
70487041 return ag->codegen->invalid_inst_src;
70497042 }
70507043 underscore_prong = prong_node;
......@@ -7056,10 +7049,10 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
70567049 buf_sprintf("else and '_' prong in switch expression"));
70577050 if (underscore_prong == prong_node)
70587051 add_error_note(ag->codegen, msg, else_prong,
7059 buf_sprintf("else prong is here"));
7052 buf_sprintf("else prong here"));
70607053 else
70617054 add_error_note(ag->codegen, msg, underscore_prong,
7062 buf_sprintf("'_' prong is here"));
7055 buf_sprintf("'_' prong here"));
70637056 return ag->codegen->invalid_inst_src;
70647057 }
70657058 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
......@@ -7349,14 +7342,14 @@ static IrInstSrc *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNo
73497342
73507343 for (size_t i = 0; i < runtime_scopes.length; i += 1) {
73517344 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);
73537346 }
73547347 runtime_scopes.deinit();
73557348
73567349 Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;
73577350 if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))
73587351 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);
73607353}
73617354
73627355static 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
74827475 return ag->codegen->invalid_inst_src;
74837476 Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;
74847477 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
74877480 ir_set_cursor_at_end_and_append_block(ag, ok_block);
74887481 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
77577750 IrInstSrc *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);
77587751 if (susp_res == ag->codegen->invalid_inst_src)
77597752 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);
77637756}
77647757
77657758static 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
80738066 }
80748067
80758068 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);
80778070 // no need for save_err_ret_addr because this cannot return error
80788071 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
80798072 result_loc_ret->base.id = ResultLocIdReturn;
80808073 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));
8082 ir_mark_gen(ir_build_return_src(ag, scope, result->base.source_node, result));
8074 ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base);
8075 ir_build_return_src(ag, scope, result->base.source_node, result);
80838076 }
80848077
80858078 return true;
src/stage1/ir.cpp+9-19
......@@ -5407,16 +5407,6 @@ static void ir_finish_bb(IrAnalyze *ira) {
54075407 ira->new_irb.current_basic_block->debug_id);
54085408 }
54095409 }
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
54205410 ir_start_next_bb(ira);
54215411}
54225412
......@@ -11107,7 +11097,7 @@ static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport
1110711097 AstNode *other_export_node = entry->value->source_node;
1110811098 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
1110911099 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"));
1111111101 return ira->codegen->invalid_inst_gen;
1111211102 }
1111311103
......@@ -11413,7 +11403,7 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern
1141311403 AstNode *other_extern_node = entry->value->source_node;
1141411404 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
1141511405 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"));
1141711407 return ira->codegen->invalid_inst_gen;
1141811408 }
1141911409
......@@ -15934,7 +15924,7 @@ static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopC
1593415924 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op);
1593515925}
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) {
1593815928 if (type_is_invalid(value->value->type))
1593915929 return ira->codegen->invalid_inst_gen;
1594015930
......@@ -15943,7 +15933,7 @@ static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrI
1594315933 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name)));
1594415934 return ira->codegen->invalid_inst_gen;
1594515935 }
15946 if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) {
15936 if (!value->value->type->data.unionation.have_explicit_tag_type) {
1594715937 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum"));
1594815938 if (value->value->type->data.unionation.decl_node != nullptr) {
1594915939 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
1690616896 }
1690716897
1690816898 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);
1691016900 if (type_is_invalid(target->value->type))
1691116901 return ira->codegen->invalid_inst_gen;
1691216902 target_type = target->value->type;
......@@ -21742,7 +21732,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
2174221732 ErrorMsg *msg = ir_add_error(ira, &start_value->base,
2174321733 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name),
2174421734 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"));
2174621736 }
2174721737 bigint_incr(&field_index);
2174821738 }
......@@ -21828,7 +21818,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
2182821818 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name;
2182921819 ErrorMsg *msg = ir_add_error(ira, &start_value->base,
2183021820 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"));
2183221822 }
2183321823 field_prev_uses[start_index] = start_value->base.source_node;
2183421824 }
......@@ -21890,7 +21880,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
2189021880 start_value->base.source_node);
2189121881 if (prev_node != nullptr) {
2189221882 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"));
2189421884 return ira->codegen->invalid_inst_gen;
2189521885 }
2189621886 }
......@@ -21975,7 +21965,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
2197521965 auto entry = prevs.put_unique(const_expr_val->data.x_type, value);
2197621966 if(entry != nullptr) {
2197721967 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"));
2197921969 prevs.deinit();
2198021970 return ira->codegen->invalid_inst_gen;
2198121971 }
src/stage1/ir_print.cpp-2
......@@ -577,8 +577,6 @@ static void ir_print_prefix_src(IrPrintSrc *irp, IrInstSrc *instruction, bool tr
577577 const char *type_name;
578578 if (instruction->id == IrInstSrcIdConst) {
579579 type_name = buf_ptr(&reinterpret_cast<IrInstSrcConst *>(instruction)->value->type->name);
580 } else if (instruction->is_noreturn) {
581 type_name = "noreturn";
582580 } else {
583581 type_name = "(unknown)";
584582 }
src/target.zig+67
......@@ -170,6 +170,73 @@ pub fn hasValgrindSupport(target: std.Target) bool {
170170 }
171171}
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
173240pub fn supportsStackProbing(target: std.Target) bool {
174241 return target.os.tag != .windows and target.os.tag != .uefi and
175242 (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;
1010const enable_wasmtime: bool = build_options.enable_wasmtime;
1111const enable_darling: bool = build_options.enable_darling;
1212const glibc_multi_install_dir: ?[]const u8 = build_options.glibc_multi_install_dir;
13const skip_compile_errors = build_options.skip_compile_errors;
1314const ThreadPool = @import("ThreadPool.zig");
1415const CrossTarget = std.zig.CrossTarget;
16const print = std.debug.print;
17const assert = std.debug.assert;
1518
1619const zig_h = link.File.C.zig_h;
1720
1821const hr = "=" ** 80;
1922
20test "self-hosted" {
23test {
24 if (build_options.is_stage1) {
25 @import("stage1.zig").os_init();
26 }
27
2128 var ctx = TestContext.init();
2229 defer ctx.deinit();
2330
24 try @import("stage2_tests").addCases(&ctx);
31 try @import("test_cases").addCases(&ctx);
2532
2633 try ctx.run();
2734}
......@@ -30,7 +37,11 @@ const ErrorMsg = union(enum) {
3037 src: struct {
3138 src_path: []const u8,
3239 msg: []const u8,
40 // maxint means match anything
41 // this is a workaround for stage1 compiler bug I ran into when making it ?u32
3342 line: u32,
43 // maxint means match anything
44 // this is a workaround for stage1 compiler bug I ran into when making it ?u32
3445 column: u32,
3546 kind: Kind,
3647 },
......@@ -74,23 +85,32 @@ const ErrorMsg = union(enum) {
7485 _ = options;
7586 switch (self) {
7687 .src => |src| {
77 return writer.print("{s}:{d}:{d}: {s}: {s}", .{
78 src.src_path,
79 src.line + 1,
80 src.column + 1,
81 @tagName(src.kind),
82 src.msg,
83 });
88 if (!std.mem.eql(u8, src.src_path, "?") or
89 src.line != std.math.maxInt(u32) or
90 src.column != std.math.maxInt(u32))
91 {
92 try writer.print("{s}:", .{src.src_path});
93 if (src.line != std.math.maxInt(u32)) {
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 });
84105 },
85106 .plain => |plain| {
86 return writer.print("{s}: {s}", .{ plain.msg, @tagName(plain.kind) });
107 return writer.print("{s}: {s}", .{ @tagName(plain.kind), plain.msg });
87108 },
88109 }
89110 }
90111};
91112
92113pub 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)
94114 cases: std.ArrayList(Case),
95115
96116 pub const Update = struct {
......@@ -127,6 +147,12 @@ pub const TestContext = struct {
127147 path: []const u8,
128148 };
129149
150 pub const Backend = enum {
151 stage1,
152 stage2,
153 llvm,
154 };
155
130156 /// A `Case` consists of a list of `Update`. The same `Compilation` is used for each
131157 /// update, so each update's source is treated as a single file being
132158 /// updated by the test harness and incrementally compiled.
......@@ -140,13 +166,20 @@ pub const TestContext = struct {
140166 /// In order to be able to run e.g. Execution updates, this must be set
141167 /// to Executable.
142168 output_mode: std.builtin.OutputMode,
169 optimize_mode: std.builtin.Mode = .Debug,
143170 updates: std.ArrayList(Update),
144171 object_format: ?std.Target.ObjectFormat = null,
145172 emit_h: bool = false,
146 llvm_backend: bool = false,
173 is_test: bool = false,
174 expect_exact: bool = false,
175 backend: Backend = .stage2,
147176
148177 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
150183 /// Adds a subcase in which the module is updated with `src`, and a C
151184 /// header is generated.
152185 pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {
......@@ -201,8 +234,14 @@ pub const TestContext = struct {
201234 const kind_text = it.next() orelse @panic("missing 'error'/'note'");
202235 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");
205 const column = std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number");
237 const line: ?u32 = if (std.mem.eql(u8, line_text, "?"))
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");
206245 const kind: ErrorMsg.Kind = if (std.mem.eql(u8, kind_text, " error"))
207246 .@"error"
208247 else if (std.mem.eql(u8, kind_text, " note"))
......@@ -210,16 +249,28 @@ pub const TestContext = struct {
210249 else
211250 @panic("expected 'error'/'note'");
212251
213 if (line == 0 or column == 0) {
214 @panic("line and column must be specified starting at one");
215 }
252 const line_0based: u32 = if (line) |n| blk: {
253 if (n == 0) {
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
217268 array[i] = .{
218269 .src = .{
219270 .src_path = src_path,
220271 .msg = msg,
221 .line = line - 1,
222 .column = column - 1,
272 .line = line_0based,
273 .column = column_0based,
223274 .kind = kind,
224275 },
225276 };
......@@ -254,11 +305,6 @@ pub const TestContext = struct {
254305 return ctx.addExe(name, target);
255306 }
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
262308 pub fn exeFromCompiledC(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {
263309 const prefixed_name = std.fmt.allocPrint(ctx.cases.allocator, "CBE: {s}", .{name}) catch
264310 @panic("out of memory");
......@@ -282,7 +328,7 @@ pub const TestContext = struct {
282328 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
283329 .output_mode = .Exe,
284330 .files = std.ArrayList(File).init(ctx.cases.allocator),
285 .llvm_backend = true,
331 .backend = .llvm,
286332 }) catch @panic("out of memory");
287333 return &ctx.cases.items[ctx.cases.items.len - 1];
288334 }
......@@ -302,6 +348,22 @@ pub const TestContext = struct {
302348 return &ctx.cases.items[ctx.cases.items.len - 1];
303349 }
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
305367 /// Adds a test case for Zig input, producing an object file.
306368 pub fn obj(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {
307369 return ctx.addObj(name, target);
......@@ -333,6 +395,45 @@ pub const TestContext = struct {
333395 ctx.addC(name, target).addHeader(src, zig_h ++ out);
334396 }
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
336437 pub fn addCompareOutput(
337438 ctx: *TestContext,
338439 name: []const u8,
......@@ -386,18 +487,6 @@ pub const TestContext = struct {
386487 ctx.addTransform(name, target, src, result);
387488 }
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
401490 pub fn addError(
402491 ctx: *TestContext,
403492 name: []const u8,
......@@ -555,7 +644,7 @@ pub const TestContext = struct {
555644 continue;
556645
557646 // 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)
559648 continue;
560649
561650 var prg_node = root_node.start(case.name, case.updates.items.len);
......@@ -567,7 +656,7 @@ pub const TestContext = struct {
567656 progress.initial_delay_ns = 0;
568657 progress.refresh_rate_ns = 0;
569658
570 self.runOneCase(
659 runOneCase(
571660 std.testing.allocator,
572661 &prg_node,
573662 case,
......@@ -576,17 +665,16 @@ pub const TestContext = struct {
576665 global_cache_directory,
577666 ) catch |err| {
578667 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) });
580669 };
581670 }
582671 if (fail_count != 0) {
583 std.debug.print("{d} tests failed\n", .{fail_count});
672 print("{d} tests failed\n", .{fail_count});
584673 return error.TestFailed;
585674 }
586675 }
587676
588677 fn runOneCase(
589 self: *TestContext,
590678 allocator: *Allocator,
591679 root_node: *std.Progress.Node,
592680 case: Case,
......@@ -594,7 +682,6 @@ pub const TestContext = struct {
594682 thread_pool: *ThreadPool,
595683 global_cache_directory: Compilation.Directory,
596684 ) !void {
597 _ = self;
598685 const target_info = try std.zig.system.NativeTargetInfo.detect(allocator, case.target);
599686 const target = target_info.target;
600687
......@@ -607,14 +694,155 @@ pub const TestContext = struct {
607694
608695 var cache_dir = try tmp.dir.makeOpenPath("zig-cache", .{});
609696 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
611841 const zig_cache_directory: Compilation.Directory = .{
612842 .handle = cache_dir,
613 .path = try std.fs.path.join(arena, &[_][]const u8{ tmp_dir_path, "zig-cache" }),
843 .path = local_cache_path,
614844 };
615845
616 const tmp_src_path = "test_case.zig";
617
618846 var root_pkg: Package = .{
619847 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
620848 .root_src_path = tmp_src_path,
......@@ -640,6 +868,14 @@ pub const TestContext = struct {
640868 .directory = emit_directory,
641869 .basename = "test_case.h",
642870 } 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 };
643879 const comp = try Compilation.create(allocator, .{
644880 .local_cache_directory = zig_cache_directory,
645881 .global_cache_directory = global_cache_directory,
......@@ -651,8 +887,8 @@ pub const TestContext = struct {
651887 // and linking. This will require a rework to support multi-file
652888 // tests.
653889 .output_mode = case.output_mode,
654 // TODO: support testing optimizations
655 .optimize_mode = .Debug,
890 .is_test = case.is_test,
891 .optimize_mode = case.optimize_mode,
656892 .emit_bin = emit_bin,
657893 .emit_h = emit_h,
658894 .root_pkg = &root_pkg,
......@@ -661,17 +897,13 @@ pub const TestContext = struct {
661897 .is_native_os = case.target.isNativeOs(),
662898 .is_native_abi = case.target.isNativeAbi(),
663899 .dynamic_linker = target_info.dynamic_linker.get(),
664 .link_libc = case.llvm_backend,
665 .use_llvm = case.llvm_backend,
666 .use_lld = case.llvm_backend,
900 .link_libc = case.backend == .llvm,
901 .use_llvm = use_llvm,
902 .use_stage1 = use_stage1,
667903 .self_exe_path = std.testing.zig_exe_path,
668904 });
669905 defer comp.destroy();
670906
671 for (case.files.items) |file| {
672 try tmp.dir.writeFile(file.path, file.src);
673 }
674
675907 for (case.updates.items) |update, update_index| {
676908 var update_node = root_node.start("update", 3);
677909 update_node.activate();
......@@ -692,19 +924,19 @@ pub const TestContext = struct {
692924 var all_errors = try comp.getAllErrorsAlloc();
693925 defer all_errors.deinit(allocator);
694926 if (all_errors.list.len != 0) {
695 std.debug.print(
927 print(
696928 "\nCase '{s}': unexpected errors at update_index={d}:\n{s}\n",
697929 .{ case.name, update_index, hr },
698930 );
699931 for (all_errors.list) |err_msg| {
700932 switch (err_msg) {
701933 .src => |src| {
702 std.debug.print("{s}:{d}:{d}: error: {s}\n{s}\n", .{
934 print("{s}:{d}:{d}: error: {s}\n{s}\n", .{
703935 src.src_path, src.line + 1, src.column + 1, src.msg, hr,
704936 });
705937 },
706938 .plain => |plain| {
707 std.debug.print("error: {s}\n{s}\n", .{ plain.msg, hr });
939 print("error: {s}\n{s}\n", .{ plain.msg, hr });
708940 },
709941 }
710942 }
......@@ -757,10 +989,20 @@ pub const TestContext = struct {
757989 const src_path_ok = case_msg.src.src_path.len == 0 or
758990 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
7601000 if (src_path_ok and
761 actual_msg.line == case_msg.src.line and
762 actual_msg.column == case_msg.src.column and
763 std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and
1001 (case_msg.src.line == std.math.maxInt(u32) or
1002 actual_msg.line == case_msg.src.line) and
1003 (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
7641006 case_msg.src.kind == .@"error")
7651007 {
7661008 handled_errors[i] = true;
......@@ -779,7 +1021,7 @@ pub const TestContext = struct {
7791021 },
7801022 }
7811023 } else {
782 std.debug.print(
1024 print(
7831025 "\nUnexpected error:\n{s}\n{}\n{s}",
7841026 .{ hr, ErrorMsg.init(actual_error, .@"error"), hr },
7851027 );
......@@ -796,9 +1038,19 @@ pub const TestContext = struct {
7961038 }
7971039 if (ex_tag != .src) continue;
7981040
799 if (actual_msg.line == case_msg.src.line and
800 actual_msg.column == case_msg.src.column and
801 std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and
1041 const expected_msg = try std.mem.replaceOwned(
1042 u8,
1043 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
8021054 case_msg.src.kind == .note)
8031055 {
8041056 handled_errors[i] = true;
......@@ -817,7 +1069,7 @@ pub const TestContext = struct {
8171069 },
8181070 }
8191071 } else {
820 std.debug.print(
1072 print(
8211073 "\nUnexpected note:\n{s}\n{}\n{s}",
8221074 .{ hr, ErrorMsg.init(note.*, .note), hr },
8231075 );
......@@ -827,7 +1079,7 @@ pub const TestContext = struct {
8271079
8281080 for (handled_errors) |handled, i| {
8291081 if (!handled) {
830 std.debug.print(
1082 print(
8311083 "\nExpected error not found:\n{s}\n{}\n{s}",
8321084 .{ hr, case_error_list[i], hr },
8331085 );
......@@ -836,7 +1088,7 @@ pub const TestContext = struct {
8361088 }
8371089
8381090 if (any_failed) {
839 std.debug.print("\nupdate_index={d} ", .{update_index});
1091 print("\nupdate_index={d} ", .{update_index});
8401092 return error.WrongCompileErrors;
8411093 }
8421094 },
......@@ -932,7 +1184,7 @@ pub const TestContext = struct {
9321184 .cwd_dir = tmp.dir,
9331185 .cwd = tmp_dir_path,
9341186 }) 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", .{
9361188 update_index, @errorName(err),
9371189 });
9381190 dumpArgs(argv.items);
......@@ -947,7 +1199,7 @@ pub const TestContext = struct {
9471199 switch (exec_result.term) {
9481200 .Exited => |code| {
9491201 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", .{
9511203 exec_result.stderr, case.name, code,
9521204 });
9531205 dumpArgs(argv.items);
......@@ -955,7 +1207,7 @@ pub const TestContext = struct {
9551207 }
9561208 },
9571209 else => {
958 std.debug.print("\n{s}\n{s}: execution crashed:\n", .{
1210 print("\n{s}\n{s}: execution crashed:\n", .{
9591211 exec_result.stderr, case.name,
9601212 });
9611213 dumpArgs(argv.items);
......@@ -974,7 +1226,9 @@ pub const TestContext = struct {
9741226
9751227fn dumpArgs(argv: []const []const u8) void {
9761228 for (argv) |arg| {
977 std.debug.print("{s} ", .{arg});
1229 print("{s} ", .{arg});
9781230 }
979 std.debug.print("\n", .{});
1231 print("\n", .{});
9801232}
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 {
754754 });
755755
756756 return std.zig.ast.Tree{
757 .source = ctx.buf.toOwnedSlice(),
757 .source = try ctx.buf.toOwnedSliceSentinel(0),
758758 .tokens = ctx.tokens.toOwnedSlice(),
759759 .nodes = ctx.nodes.toOwnedSlice(),
760760 .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 @@
1const tests = @import("tests.zig");
21const std = @import("std");
2const TestContext = @import("../src/test.zig").TestContext;
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add("std.fmt error for unused arguments",
4pub fn addCases(ctx: *TestContext) !void {
5 ctx.exeErrStage1("std.fmt error for unused arguments",
66 \\pub fn main() !void {
77 \\ @import("std").debug.print("{d} {d} {d} {d} {d}", .{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});
88 \\}
99 , &.{
10 \\error: 10 unused arguments in "{d} {d} {d} {d} {d}"
10 "?:?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'",
1111 });
1212
13 cases.add("lazy pointer with undefined element type",
13 ctx.objErrStage1("lazy pointer with undefined element type",
1414 \\export fn foo() void {
1515 \\ comptime var T: type = undefined;
1616 \\ const S = struct { x: *T };
1717 \\ const I = @typeInfo(S);
18 \\ _ = I;
1819 \\}
1920 , &[_][]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",
2122 });
2223
23 cases.add("pointer arithmetic on pointer-to-array",
24 ctx.objErrStage1("pointer arithmetic on pointer-to-array",
2425 \\export fn foo() void {
2526 \\ var x: [10]u8 = undefined;
2627 \\ var y = &x;
2728 \\ var z = y + 1;
29 \\ _ = z;
2830 \\}
2931 , &[_][]const u8{
3032 "tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'",
3133 });
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",
3436 \\comptime {
3537 \\ const c: [][]const u8 = &.{"hello", "world" };
38 \\ _ = c;
3639 \\}
3740 \\comptime {
3841 \\ const c: *[2][]const u8 = &.{"hello", "world" };
42 \\ _ = c;
3943 \\}
4044 \\const S = struct {a: u8 = 1, b: u32 = 2};
4145 \\comptime {
4246 \\ const c: *S = &.{};
47 \\ _ = c;
4348 \\}
4449 , &[_][]const u8{
4550 "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'",
47 "tmp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",
51 "tmp.zig:6:33: error: expected type '*[2][]const u8', found '*const struct:6:33'",
52 "tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'",
4853 });
4954
50 cases.add("@Type() union payload is undefined",
55 ctx.objErrStage1("@Type() union payload is undefined",
5156 \\const Foo = @Type(@import("std").builtin.TypeInfo{
5257 \\ .Struct = undefined,
5358 \\});
......@@ -56,7 +61,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5661 "tmp.zig:1:50: error: use of undefined value here causes undefined behavior",
5762 });
5863
59 cases.add("wrong initializer for union payload of type 'type'",
64 ctx.objErrStage1("wrong initializer for union payload of type 'type'",
6065 \\const U = union(enum) {
6166 \\ A: type,
6267 \\};
......@@ -71,7 +76,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7176 "tmp.zig:9:8: error: use of undefined value here causes undefined behavior",
7277 });
7378
74 cases.add("union with too small explicit signed tag type",
79 ctx.objErrStage1("union with too small explicit signed tag type",
7580 \\const U = union(enum(i2)) {
7681 \\ A: u8,
7782 \\ B: u8,
......@@ -86,7 +91,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8691 "tmp.zig:1:22: note: type i2 cannot fit values in range 0...3",
8792 });
8893
89 cases.add("union with too small explicit unsigned tag type",
94 ctx.objErrStage1("union with too small explicit unsigned tag type",
9095 \\const U = union(enum(u2)) {
9196 \\ A: u8,
9297 \\ B: u8,
......@@ -102,56 +107,60 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
102107 "tmp.zig:1:22: note: type u2 cannot fit values in range 0...4",
103108 });
104109
105 cases.addCase(x: {
106 var tc = cases.create("callconv(.Interrupt) on unsupported platform",
110 {
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(
107118 \\export fn entry() callconv(.Interrupt) void {}
108119 , &[_][]const u8{
109120 "tmp.zig:1:28: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64",
110121 });
111 tc.target = std.zig.CrossTarget{
112 .cpu_arch = .aarch64,
122 }
123 {
124 var case = ctx.obj("callconv(.Signal) on unsupported platform", .{
125 .cpu_arch = .x86_64,
113126 .os_tag = .linux,
114127 .abi = .none,
115 };
116 break :x tc;
117 });
118
119 cases.addCase(x: {
120 var tc = cases.create("callconv(.Signal) on unsupported platform",
128 });
129 case.backend = .stage1;
130 case.addError(
121131 \\export fn entry() callconv(.Signal) void {}
122132 , &[_][]const u8{
123133 "tmp.zig:1:28: error: callconv 'Signal' is only available on AVR, not x86_64",
124134 });
125 tc.target = std.zig.CrossTarget{
135 }
136 {
137 const case = ctx.obj("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform", .{
126138 .cpu_arch = .x86_64,
127139 .os_tag = .linux,
128140 .abi = .none,
129 };
130 break :x tc;
131 });
132 cases.addCase(x: {
133 var tc = cases.create("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform",
141 });
142 case.backend = .stage1;
143 case.addError(
134144 \\const F1 = fn () callconv(.Stdcall) void;
135145 \\const F2 = fn () callconv(.Fastcall) void;
136146 \\const F3 = fn () callconv(.Thiscall) void;
137 \\export fn entry1() void { var a: F1 = undefined; }
138 \\export fn entry2() void { var a: F2 = undefined; }
139 \\export fn entry3() void { var a: F3 = undefined; }
147 \\export fn entry1() void { var a: F1 = undefined; _ = a; }
148 \\export fn entry2() void { var a: F2 = undefined; _ = a; }
149 \\export fn entry3() void { var a: F3 = undefined; _ = a; }
140150 , &[_][]const u8{
141151 "tmp.zig:1:27: error: callconv 'Stdcall' is only available on x86, not x86_64",
142152 "tmp.zig:2:27: error: callconv 'Fastcall' is only available on x86, not x86_64",
143153 "tmp.zig:3:27: error: callconv 'Thiscall' is only available on x86, not x86_64",
144154 });
145 tc.target = std.zig.CrossTarget{
155 }
156 {
157 const case = ctx.obj("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform", .{
146158 .cpu_arch = .x86_64,
147159 .os_tag = .linux,
148160 .abi = .none,
149 };
150 break :x tc;
151 });
152
153 cases.addCase(x: {
154 var tc = cases.create("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform",
161 });
162 case.backend = .stage1;
163 case.addError(
155164 \\export fn entry1() callconv(.Stdcall) void {}
156165 \\export fn entry2() callconv(.Fastcall) void {}
157166 \\export fn entry3() callconv(.Thiscall) void {}
......@@ -160,30 +169,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
160169 "tmp.zig:2:29: error: callconv 'Fastcall' is only available on x86, not x86_64",
161170 "tmp.zig:3:29: error: callconv 'Thiscall' is only available on x86, not x86_64",
162171 });
163 tc.target = std.zig.CrossTarget{
172 }
173 {
174 const case = ctx.obj("callconv(.Vectorcall) on unsupported platform", .{
164175 .cpu_arch = .x86_64,
165176 .os_tag = .linux,
166177 .abi = .none,
167 };
168 break :x tc;
169 });
170
171 cases.addCase(x: {
172 var tc = cases.create("callconv(.Vectorcall) on unsupported platform",
178 });
179 case.backend = .stage1;
180 case.addError(
173181 \\export fn entry() callconv(.Vectorcall) void {}
174182 , &[_][]const u8{
175183 "tmp.zig:1:28: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64",
176184 });
177 tc.target = std.zig.CrossTarget{
185 }
186 {
187 const case = ctx.obj("callconv(.APCS, .AAPCS, .AAPCSVFP) on unsupported platform", .{
178188 .cpu_arch = .x86_64,
179189 .os_tag = .linux,
180190 .abi = .none,
181 };
182 break :x tc;
183 });
184
185 cases.addCase(x: {
186 var tc = cases.create("callconv(.APCS, .AAPCS, .AAPCSVFP) on unsupported platform",
191 });
192 case.backend = .stage1;
193 case.addError(
187194 \\export fn entry1() callconv(.APCS) void {}
188195 \\export fn entry2() callconv(.AAPCS) void {}
189196 \\export fn entry3() callconv(.AAPCSVFP) void {}
......@@ -192,15 +199,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
192199 "tmp.zig:2:29: error: callconv 'AAPCS' is only available on ARM, not x86_64",
193200 "tmp.zig:3:29: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64",
194201 });
195 tc.target = std.zig.CrossTarget{
196 .cpu_arch = .x86_64,
197 .os_tag = .linux,
198 .abi = .none,
199 };
200 break :x tc;
201 });
202 }
202203
203 cases.add("unreachable executed at comptime",
204 ctx.objErrStage1("unreachable executed at comptime",
204205 \\fn foo(comptime x: i32) i32 {
205206 \\ comptime {
206207 \\ if (x >= 0) return -x;
......@@ -215,7 +216,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
215216 "tmp.zig:8:12: note: called from here",
216217 });
217218
218 cases.add("@Type with TypeInfo.Int",
219 ctx.objErrStage1("@Type with TypeInfo.Int",
219220 \\const builtin = @import("std").builtin;
220221 \\export fn entry() void {
221222 \\ _ = @Type(builtin.TypeInfo.Int {
......@@ -227,7 +228,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
227228 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",
228229 });
229230
230 cases.add("indexing a undefined slice at comptime",
231 ctx.objErrStage1("indexing a undefined slice at comptime",
231232 \\comptime {
232233 \\ var slice: []u8 = undefined;
233234 \\ slice[0] = 2;
......@@ -236,7 +237,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
236237 "tmp.zig:3:10: error: index 0 outside slice of size 0",
237238 });
238239
239 cases.add("array in c exported function",
240 ctx.objErrStage1("array in c exported function",
240241 \\export fn zig_array(x: [10]u8) void {
241242 \\try expect(std.mem.eql(u8, &x, "1234567890"));
242243 \\}
......@@ -249,7 +250,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
249250 "tmp.zig:5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'",
250251 });
251252
252 cases.add("@Type for exhaustive enum with undefined tag type",
253 ctx.objErrStage1("@Type for exhaustive enum with undefined tag type",
253254 \\const TypeInfo = @import("std").builtin.TypeInfo;
254255 \\const Tag = @Type(.{
255256 \\ .Enum = .{
......@@ -267,19 +268,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
267268 "tmp.zig:2:20: error: use of undefined value here causes undefined behavior",
268269 });
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",
271272 \\pub const E = enum(u31) { A, B, C };
272273 \\pub const S = extern struct {
273274 \\ e: E,
274275 \\};
275276 \\export fn entry() void {
276277 \\ const s: S = undefined;
278 \\ _ = s;
277279 \\}
278280 , &[_][]const u8{
279281 "tmp.zig:3:5: error: extern structs cannot contain fields of type 'E'",
280282 });
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",
283285 \\const TypeInfo = @import("std").builtin.TypeInfo;
284286 \\const Tag = @Type(.{
285287 \\ .Enum = .{
......@@ -297,7 +299,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
297299 "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",
298300 });
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",
301303 \\pub const E = enum {
302304 \\@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",
303305 \\@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",
......@@ -333,12 +335,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
333335 \\export fn entry() void {
334336 \\ if (@typeInfo(E).Enum.tag_type != u8) @compileError("did not infer u8 tag type");
335337 \\ const s: S = undefined;
338 \\ _ = s;
336339 \\}
337340 , &[_][]const u8{
338341 "tmp.zig:31:5: error: extern structs cannot contain fields of type 'E'",
339342 });
340343
341 cases.add("@Type for tagged union with extra enum field",
344 ctx.objErrStage1("@Type for tagged union with extra enum field",
342345 \\const TypeInfo = @import("std").builtin.TypeInfo;
343346 \\const Tag = @Type(.{
344347 \\ .Enum = .{
......@@ -373,7 +376,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
373376 "tmp.zig:27:24: note: referenced here",
374377 });
375378
376 cases.add("field access of opaque type",
379 ctx.objErrStage1("field access of opaque type",
377380 \\const MyType = opaque {};
378381 \\
379382 \\export fn entry() bool {
......@@ -388,16 +391,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
388391 "tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType'",
389392 });
390393
391 cases.add("opaque type with field",
394 ctx.objErrStage1("opaque type with field",
392395 \\const Opaque = opaque { foo: i32 };
393396 \\export fn entry() void {
394397 \\ const foo: ?*Opaque = null;
398 \\ _ = foo;
395399 \\}
396400 , &[_][]const u8{
397401 "tmp.zig:1:25: error: opaque types cannot have fields",
398402 });
399403
400 cases.add("@Type(.Fn) with is_generic = true",
404 ctx.objErrStage1("@Type(.Fn) with is_generic = true",
401405 \\const Foo = @Type(.{
402406 \\ .Fn = .{
403407 \\ .calling_convention = .Unspecified,
......@@ -413,7 +417,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
413417 "tmp.zig:1:20: error: TypeInfo.Fn.is_generic must be false for @Type",
414418 });
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",
417421 \\const Foo = @Type(.{
418422 \\ .Fn = .{
419423 \\ .calling_convention = .Unspecified,
......@@ -429,7 +433,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
429433 "tmp.zig:1:20: error: varargs functions must have C calling convention",
430434 });
431435
432 cases.add("@Type(.Fn) with return_type = null",
436 ctx.objErrStage1("@Type(.Fn) with return_type = null",
433437 \\const Foo = @Type(.{
434438 \\ .Fn = .{
435439 \\ .calling_convention = .Unspecified,
......@@ -445,7 +449,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
445449 "tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type",
446450 });
447451
448 cases.add("@Type for union with opaque field",
452 ctx.objErrStage1("@Type for union with opaque field",
449453 \\const TypeInfo = @import("std").builtin.TypeInfo;
450454 \\const Untagged = @Type(.{
451455 \\ .Union = .{
......@@ -465,23 +469,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
465469 "tmp.zig:13:17: note: referenced here",
466470 });
467471
468 cases.add("slice sentinel mismatch",
472 ctx.objErrStage1("slice sentinel mismatch",
469473 \\export fn entry() void {
470474 \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };
475 \\ _ = x;
471476 \\}
472477 , &[_][]const u8{
473478 "tmp.zig:2:62: error: index 3 outside vector of size 3",
474479 });
475480
476 cases.add("slice sentinel mismatch",
481 ctx.objErrStage1("slice sentinel mismatch",
477482 \\export fn entry() void {
478483 \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 };
484 \\ _ = y;
479485 \\}
480486 , &[_][]const u8{
481487 "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",
482488 });
483489
484 cases.add("@Type for union with zero fields",
490 ctx.objErrStage1("@Type for union with zero fields",
485491 \\const TypeInfo = @import("std").builtin.TypeInfo;
486492 \\const Untagged = @Type(.{
487493 \\ .Union = .{
......@@ -499,7 +505,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
499505 "tmp.zig:11:17: note: referenced here",
500506 });
501507
502 cases.add("@Type for exhaustive enum with zero fields",
508 ctx.objErrStage1("@Type for exhaustive enum with zero fields",
503509 \\const TypeInfo = @import("std").builtin.TypeInfo;
504510 \\const Tag = @Type(.{
505511 \\ .Enum = .{
......@@ -518,7 +524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
518524 "tmp.zig:12:9: note: referenced here",
519525 });
520526
521 cases.add("@Type for tagged union with extra union field",
527 ctx.objErrStage1("@Type for tagged union with extra union field",
522528 \\const TypeInfo = @import("std").builtin.TypeInfo;
523529 \\const Tag = @Type(.{
524530 \\ .Enum = .{
......@@ -554,7 +560,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
554560 "tmp.zig:27:24: note: referenced here",
555561 });
556562
557 cases.add("@Type with undefined",
563 ctx.objErrStage1("@Type with undefined",
558564 \\comptime {
559565 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
560566 \\}
......@@ -573,7 +579,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
573579 "tmp.zig:5:16: error: use of undefined value here causes undefined behavior",
574580 });
575581
576 cases.add("struct with declarations unavailable for @Type",
582 ctx.objErrStage1("struct with declarations unavailable for @Type",
577583 \\export fn entry() void {
578584 \\ _ = @Type(@typeInfo(struct { const foo = 1; }));
579585 \\}
......@@ -581,7 +587,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
581587 "tmp.zig:2:15: error: TypeInfo.Struct.decls must be empty for @Type",
582588 });
583589
584 cases.add("enum with declarations unavailable for @Type",
590 ctx.objErrStage1("enum with declarations unavailable for @Type",
585591 \\export fn entry() void {
586592 \\ _ = @Type(@typeInfo(enum { foo, const bar = 1; }));
587593 \\}
......@@ -589,36 +595,44 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
589595 "tmp.zig:2:15: error: TypeInfo.Enum.decls must be empty for @Type",
590596 });
591597
592 cases.addTest("reject extern variables with initializers",
598 ctx.testErrStage1("reject extern variables with initializers",
593599 \\extern var foo: int = 2;
594600 , &[_][]const u8{
595 "tmp.zig:1:1: error: extern variables have no initializers",
601 "tmp.zig:1:23: error: extern variables have no initializers",
596602 });
597603
598 cases.addTest("duplicate/unused labels",
604 ctx.testErrStage1("duplicate/unused labels",
599605 \\comptime {
600606 \\ blk: { blk: while (false) {} }
607 \\}
608 \\comptime {
601609 \\ blk: while (false) { blk: for (@as([0]void, undefined)) |_| {} }
610 \\}
611 \\comptime {
602612 \\ blk: for (@as([0]void, undefined)) |_| { blk: {} }
603613 \\}
604614 \\comptime {
605615 \\ blk: {}
616 \\}
617 \\comptime {
606618 \\ blk: while(false) {}
619 \\}
620 \\comptime {
607621 \\ blk: for(@as([0]void, undefined)) |_| {}
608622 \\}
609623 , &[_][]const u8{
610 "tmp.zig:2:17: error: redeclaration of label 'blk'",
611 "tmp.zig:2:10: note: previous declaration is here",
612 "tmp.zig:3:31: error: redeclaration of label 'blk'",
613 "tmp.zig:3:10: note: previous declaration is here",
614 "tmp.zig:4:51: error: redeclaration of label 'blk'",
615 "tmp.zig:4:10: note: previous declaration is here",
616 "tmp.zig:7:10: error: unused block label",
617 "tmp.zig:8:10: error: unused while label",
618 "tmp.zig:9:10: error: unused for label",
624 "tmp.zig:2:12: error: redefinition of label 'blk'",
625 "tmp.zig:2:5: note: previous definition here",
626 "tmp.zig:5:26: error: redefinition of label 'blk'",
627 "tmp.zig:5:5: note: previous definition here",
628 "tmp.zig:8:46: error: redefinition of label 'blk'",
629 "tmp.zig:8:5: note: previous definition here",
630 "tmp.zig:11:5: error: unused block label",
631 "tmp.zig:14:5: error: unused while loop label",
632 "tmp.zig:17:5: error: unused for loop label",
619633 });
620634
621 cases.addTest("@alignCast of zero sized types",
635 ctx.testErrStage1("@alignCast of zero sized types",
622636 \\export fn foo() void {
623637 \\ const a: *void = undefined;
624638 \\ _ = @alignCast(2, a);
......@@ -633,7 +647,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
633647 \\}
634648 \\export fn qux() void {
635649 \\ const a = struct {
636 \\ fn a(comptime b: u32) void {}
650 \\ fn a(comptime b: u32) void { _ = b; }
637651 \\ }.a;
638652 \\ _ = @alignCast(2, a);
639653 \\}
......@@ -644,7 +658,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
644658 "tmp.zig:17:23: error: cannot adjust alignment of zero sized type 'fn(u32) anytype'",
645659 });
646660
647 cases.addTest("invalid non-exhaustive enum to union",
661 ctx.testErrStage1("invalid non-exhaustive enum to union",
648662 \\const E = enum(u8) {
649663 \\ a,
650664 \\ b,
......@@ -657,17 +671,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
657671 \\export fn foo() void {
658672 \\ var e = @intToEnum(E, 15);
659673 \\ var u: U = e;
674 \\ _ = u;
660675 \\}
661676 \\export fn bar() void {
662677 \\ const e = @intToEnum(E, 15);
663678 \\ var u: U = e;
679 \\ _ = u;
664680 \\}
665681 , &[_][]const u8{
666682 "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",
668684 });
669685
670 cases.addTest("switching with exhaustive enum has '_' prong ",
686 ctx.testErrStage1("switching with exhaustive enum has '_' prong ",
671687 \\const E = enum{
672688 \\ a,
673689 \\ b,
......@@ -684,7 +700,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
684700 "tmp.zig:7:5: error: switch on exhaustive enum has `_` prong",
685701 });
686702
687 cases.addTest("invalid pointer with @Type",
703 ctx.testErrStage1("invalid pointer with @Type",
688704 \\export fn entry() void {
689705 \\ _ = @Type(.{ .Pointer = .{
690706 \\ .size = .One,
......@@ -700,7 +716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
700716 "tmp.zig:2:16: error: sentinels are only allowed on slices and unknown-length pointers",
701717 });
702718
703 cases.addTest("helpful return type error message",
719 ctx.testErrStage1("helpful return type error message",
704720 \\export fn foo() u32 {
705721 \\ return error.Ohno;
706722 \\}
......@@ -728,7 +744,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
728744 "tmp.zig:14:5: note: cannot store an error in type 'u32'",
729745 });
730746
731 cases.addTest("int/float conversion to comptime_int/float",
747 ctx.testErrStage1("int/float conversion to comptime_int/float",
732748 \\export fn foo() void {
733749 \\ var a: f32 = 2;
734750 \\ _ = @floatToInt(comptime_int, a);
......@@ -744,16 +760,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
744760 "tmp.zig:7:9: note: referenced here",
745761 });
746762
747 cases.add("extern variable has no type",
763 ctx.objErrStage1("extern variable has no type",
748764 \\extern var foo;
749765 \\pub export fn entry() void {
750766 \\ foo;
751767 \\}
752768 , &[_][]const u8{
753 "tmp.zig:1:1: error: unable to infer variable type",
769 "tmp.zig:1:8: error: unable to infer variable type",
754770 });
755771
756 cases.add("@src outside function",
772 ctx.objErrStage1("@src outside function",
757773 \\comptime {
758774 \\ @src();
759775 \\}
......@@ -761,7 +777,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
761777 "tmp.zig:2:5: error: @src outside function",
762778 });
763779
764 cases.add("call assigned to constant",
780 ctx.objErrStage1("call assigned to constant",
765781 \\const Foo = struct {
766782 \\ x: i32,
767783 \\};
......@@ -784,15 +800,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
784800 "tmp.zig:16:14: error: cannot assign to constant",
785801 });
786802
787 cases.add("invalid pointer syntax",
803 ctx.objErrStage1("invalid pointer syntax",
788804 \\export fn foo() void {
789805 \\ var guid: *:0 const u8 = undefined;
790806 \\}
791807 , &[_][]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 ':'",
793809 });
794810
795 cases.add("declaration between fields",
811 ctx.objErrStage1("declaration between fields",
796812 \\const S = struct {
797813 \\ const foo = 2;
798814 \\ const bar = 2;
......@@ -810,16 +826,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
810826 "tmp.zig:6:5: error: declarations are not allowed between container fields",
811827 });
812828
813 cases.add("non-extern function with var args",
829 ctx.objErrStage1("non-extern function with var args",
814830 \\fn foo(args: ...) void {}
815831 \\export fn entry() void {
816832 \\ foo();
817833 \\}
818834 , &[_][]const u8{
819 "tmp.zig:1:1: error: non-extern function is variadic",
835 "tmp.zig:1:14: error: expected type expression, found '...'",
820836 });
821837
822 cases.addTest("invalid int casts",
838 ctx.testErrStage1("invalid int casts",
823839 \\export fn foo() void {
824840 \\ var a: u32 = 2;
825841 \\ _ = @intCast(comptime_int, a);
......@@ -847,7 +863,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
847863 "tmp.zig:15:9: note: referenced here",
848864 });
849865
850 cases.addTest("invalid float casts",
866 ctx.testErrStage1("invalid float casts",
851867 \\export fn foo() void {
852868 \\ var a: f32 = 2;
853869 \\ _ = @floatCast(comptime_float, a);
......@@ -875,7 +891,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
875891 "tmp.zig:15:9: note: referenced here",
876892 });
877893
878 cases.addTest("invalid assignments",
894 ctx.testErrStage1("invalid assignments",
879895 \\export fn entry1() void {
880896 \\ var a: []const u8 = "foo";
881897 \\ a[0..2] = "bar";
......@@ -893,7 +909,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
893909 "tmp.zig:10:7: error: invalid left-hand side to assignment",
894910 });
895911
896 cases.addTest("reassign to array parameter",
912 ctx.testErrStage1("reassign to array parameter",
897913 \\fn reassign(a: [3]f32) void {
898914 \\ a = [3]f32{4, 5, 6};
899915 \\}
......@@ -904,7 +920,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
904920 "tmp.zig:2:15: error: cannot assign to constant",
905921 });
906922
907 cases.addTest("reassign to slice parameter",
923 ctx.testErrStage1("reassign to slice parameter",
908924 \\pub fn reassign(s: []const u8) void {
909925 \\ s = s[0..];
910926 \\}
......@@ -915,7 +931,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
915931 "tmp.zig:2:10: error: cannot assign to constant",
916932 });
917933
918 cases.addTest("reassign to struct parameter",
934 ctx.testErrStage1("reassign to struct parameter",
919935 \\const S = struct {
920936 \\ x: u32,
921937 \\};
......@@ -929,7 +945,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
929945 "tmp.zig:5:10: error: cannot assign to constant",
930946 });
931947
932 cases.addTest("reference to const data",
948 ctx.testErrStage1("reference to const data",
933949 \\export fn foo() void {
934950 \\ var ptr = &[_]u8{0,0,0,0};
935951 \\ ptr[1] = 2;
......@@ -957,7 +973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
957973 "tmp.zig:19:13: error: cannot assign to constant",
958974 });
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",
961977 \\pub const fnty1 = ?fn (i8) void;
962978 \\pub const fnty2 = ?fn (u64) void;
963979 \\export fn entry() void {
......@@ -970,7 +986,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
970986 "tmp.zig:6:9: note: optional type child 'fn(u64) void' cannot cast into optional type child 'fn(i8) void'",
971987 });
972988
973 cases.addTest("unused variable error on errdefer",
989 ctx.testErrStage1("unused variable error on errdefer",
974990 \\fn foo() !void {
975991 \\ errdefer |a| unreachable;
976992 \\ return error.A;
......@@ -982,18 +998,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
982998 "tmp.zig:2:15: error: unused variable: 'a'",
983999 });
9841000
985 cases.addTest("comparison of non-tagged union and enum literal",
1001 ctx.testErrStage1("comparison of non-tagged union and enum literal",
9861002 \\export fn entry() void {
9871003 \\ const U = union { A: u32, B: u64 };
9881004 \\ var u = U{ .A = 42 };
9891005 \\ var ok = u == .A;
1006 \\ _ = ok;
9901007 \\}
9911008 , &[_][]const u8{
9921009 "tmp.zig:4:16: error: comparison of union and enum literal is only valid for tagged union types",
9931010 "tmp.zig:2:15: note: type U is not a tagged union",
9941011 });
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",
9971014 \\export fn entry() void {
9981015 \\ const S = struct {
9991016 \\ fn a() void {
......@@ -1025,7 +1042,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10251042 "tmp.zig:17:17: error: RHS of shift is too large for LHS type",
10261043 });
10271044
1028 cases.addTest("combination of nosuspend and async",
1045 ctx.testErrStage1("combination of nosuspend and async",
10291046 \\export fn entry() void {
10301047 \\ nosuspend {
10311048 \\ const bar = async foo();
......@@ -1035,10 +1052,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10351052 \\}
10361053 \\fn foo() void {}
10371054 , &[_][]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",
10391057 });
10401058
1041 cases.add("atomicrmw with bool op not .Xchg",
1059 ctx.objErrStage1("atomicrmw with bool op not .Xchg",
10421060 \\export fn entry() void {
10431061 \\ var x = false;
10441062 \\ _ = @atomicRmw(bool, &x, .Add, true, .SeqCst);
......@@ -1047,7 +1065,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10471065 "tmp.zig:3:30: error: @atomicRmw with bool only allowed with .Xchg",
10481066 });
10491067
1050 cases.addTest("@TypeOf with no arguments",
1068 ctx.testErrStage1("@TypeOf with no arguments",
10511069 \\export fn entry() void {
10521070 \\ _ = @TypeOf();
10531071 \\}
......@@ -1055,7 +1073,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10551073 "tmp.zig:2:9: error: expected at least 1 argument, found 0",
10561074 });
10571075
1058 cases.addTest("@TypeOf with incompatible arguments",
1076 ctx.testErrStage1("@TypeOf with incompatible arguments",
10591077 \\export fn entry() void {
10601078 \\ var var_1: f32 = undefined;
10611079 \\ var var_2: u32 = undefined;
......@@ -1065,7 +1083,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10651083 "tmp.zig:4:9: error: incompatible types: 'f32' and 'u32'",
10661084 });
10671085
1068 cases.addTest("type mismatch with tuple concatenation",
1086 ctx.testErrStage1("type mismatch with tuple concatenation",
10691087 \\export fn entry() void {
10701088 \\ var x = .{};
10711089 \\ x = x ++ .{ 1, 2, 3 };
......@@ -1074,7 +1092,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10741092 "tmp.zig:3:11: error: expected type 'struct:2:14', found 'struct:3:11'",
10751093 });
10761094
1077 cases.addTest("@tagName on invalid value of non-exhaustive enum",
1095 ctx.testErrStage1("@tagName on invalid value of non-exhaustive enum",
10781096 \\test "enum" {
10791097 \\ const E = enum(u8) {A, B, _};
10801098 \\ _ = @tagName(@intToEnum(E, 5));
......@@ -1083,16 +1101,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10831101 "tmp.zig:3:18: error: no tag by value 5",
10841102 });
10851103
1086 cases.addTest("@ptrToInt with pointer to zero-sized type",
1104 ctx.testErrStage1("@ptrToInt with pointer to zero-sized type",
10871105 \\export fn entry() void {
10881106 \\ var pointer: ?*u0 = null;
10891107 \\ var x = @ptrToInt(pointer);
1108 \\ _ = x;
10901109 \\}
10911110 , &[_][]const u8{
10921111 "tmp.zig:3:23: error: pointer to size 0 type has no address",
10931112 });
10941113
1095 cases.addTest("access invalid @typeInfo decl",
1114 ctx.testErrStage1("access invalid @typeInfo decl",
10961115 \\const A = B;
10971116 \\test "Crash" {
10981117 \\ _ = @typeInfo(@This()).Struct.decls[0];
......@@ -1101,7 +1120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11011120 "tmp.zig:1:11: error: use of undeclared identifier 'B'",
11021121 });
11031122
1104 cases.addTest("reject extern function definitions with body",
1123 ctx.testErrStage1("reject extern function definitions with body",
11051124 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 {
11061125 \\ return a + b;
11071126 \\}
......@@ -1109,7 +1128,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11091128 "tmp.zig:1:1: error: extern functions have no body",
11101129 });
11111130
1112 cases.addTest("duplicate field in anonymous struct literal",
1131 ctx.testErrStage1("duplicate field in anonymous struct literal",
11131132 \\export fn entry() void {
11141133 \\ const anon = .{
11151134 \\ .inner = .{
......@@ -1119,31 +1138,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11191138 \\ .a = .{},
11201139 \\ },
11211140 \\ };
1141 \\ _ = anon;
11221142 \\}
11231143 , &[_][]const u8{
11241144 "tmp.zig:7:13: error: duplicate field",
11251145 "tmp.zig:4:13: note: other field here",
11261146 });
11271147
1128 cases.addTest("type mismatch in C prototype with varargs",
1148 ctx.testErrStage1("type mismatch in C prototype with varargs",
11291149 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;
11301150 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;
11311151 \\
11321152 \\export fn main() void {
11331153 \\ const x: fn_ty = fn_decl;
1154 \\ _ = x;
11341155 \\}
11351156 , &[_][]const u8{
11361157 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
11371158 });
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",
11401161 \\export const foo = @typeInfo(@This()).Struct.decls;
11411162 , &[_][]const u8{
11421163 "tmp.zig:1:20: error: dependency loop detected",
11431164 "tmp.zig:1:45: note: referenced here",
11441165 });
11451166
1146 cases.add("function call assigned to incorrect type",
1167 ctx.objErrStage1("function call assigned to incorrect type",
11471168 \\export fn entry() void {
11481169 \\ var arr: [4]f32 = undefined;
11491170 \\ arr = concat();
......@@ -1155,7 +1176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11551176 "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'",
11561177 });
11571178
1158 cases.add("generic function call assigned to incorrect type",
1179 ctx.objErrStage1("generic function call assigned to incorrect type",
11591180 \\pub export fn entry() void {
11601181 \\ var res: []i32 = undefined;
11611182 \\ res = myAlloc(i32);
......@@ -1167,12 +1188,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11671188 "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32",
11681189 });
11691190
1170 cases.addTest("non-exhaustive enums",
1191 ctx.testErrStage1("non-exhaustive enum marker assigned a value",
11711192 \\const A = enum {
11721193 \\ a,
11731194 \\ b,
11741195 \\ _ = 1,
11751196 \\};
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",
11761210 \\const B = enum(u1) {
11771211 \\ a,
11781212 \\ _,
......@@ -1184,18 +1218,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11841218 \\ _,
11851219 \\};
11861220 \\pub export fn entry() void {
1187 \\ _ = A;
11881221 \\ _ = B;
11891222 \\ _ = C;
11901223 \\}
11911224 , &[_][]const u8{
1192 "tmp.zig:4:5: error: value assigned to '_' field of non-exhaustive enum",
1193 "error: non-exhaustive enum must specify size",
1194 "error: non-exhaustive enum specifies every value",
1195 "error: '_' field of non-exhaustive enum must be last",
1225 "tmp.zig:3:5: error: '_' field of non-exhaustive enum must be last",
1226 "tmp.zig:6:11: error: non-exhaustive enum specifies every value",
11961227 });
11971228
1198 cases.addTest("switching with non-exhaustive enums",
1229 ctx.testErrStage1("switching with non-exhaustive enums",
11991230 \\const E = enum(u8) {
12001231 \\ a,
12011232 \\ b,
......@@ -1228,7 +1259,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12281259 "tmp.zig:21:5: error: `_` prong not allowed when switching on tagged union",
12291260 });
12301261
1231 cases.add("switch expression - unreachable else prong (bool)",
1262 ctx.objErrStage1("switch expression - unreachable else prong (bool)",
12321263 \\fn foo(x: bool) void {
12331264 \\ switch (x) {
12341265 \\ true => {},
......@@ -1241,7 +1272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12411272 "tmp.zig:5:9: error: unreachable else prong, all cases already handled",
12421273 });
12431274
1244 cases.add("switch expression - unreachable else prong (u1)",
1275 ctx.objErrStage1("switch expression - unreachable else prong (u1)",
12451276 \\fn foo(x: u1) void {
12461277 \\ switch (x) {
12471278 \\ 0 => {},
......@@ -1254,7 +1285,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12541285 "tmp.zig:5:9: error: unreachable else prong, all cases already handled",
12551286 });
12561287
1257 cases.add("switch expression - unreachable else prong (u2)",
1288 ctx.objErrStage1("switch expression - unreachable else prong (u2)",
12581289 \\fn foo(x: u2) void {
12591290 \\ switch (x) {
12601291 \\ 0 => {},
......@@ -1269,7 +1300,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12691300 "tmp.zig:7:9: error: unreachable else prong, all cases already handled",
12701301 });
12711302
1272 cases.add("switch expression - unreachable else prong (range u8)",
1303 ctx.objErrStage1("switch expression - unreachable else prong (range u8)",
12731304 \\fn foo(x: u8) void {
12741305 \\ switch (x) {
12751306 \\ 0 => {},
......@@ -1285,7 +1316,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12851316 "tmp.zig:8:9: error: unreachable else prong, all cases already handled",
12861317 });
12871318
1288 cases.add("switch expression - unreachable else prong (range i8)",
1319 ctx.objErrStage1("switch expression - unreachable else prong (range i8)",
12891320 \\fn foo(x: i8) void {
12901321 \\ switch (x) {
12911322 \\ -128...0 => {},
......@@ -1301,7 +1332,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13011332 "tmp.zig:8:9: error: unreachable else prong, all cases already handled",
13021333 });
13031334
1304 cases.add("switch expression - unreachable else prong (enum)",
1335 ctx.objErrStage1("switch expression - unreachable else prong (enum)",
13051336 \\const TestEnum = enum{ T1, T2 };
13061337 \\
13071338 \\fn err(x: u8) TestEnum {
......@@ -1324,7 +1355,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13241355 "tmp.zig:14:9: error: unreachable else prong, all cases already handled",
13251356 });
13261357
1327 cases.addTest("@export with empty name string",
1358 ctx.testErrStage1("@export with empty name string",
13281359 \\pub export fn entry() void { }
13291360 \\comptime {
13301361 \\ @export(entry, .{ .name = "" });
......@@ -1333,7 +1364,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13331364 "tmp.zig:3:5: error: exported symbol name cannot be empty",
13341365 });
13351366
1336 cases.addTest("switch ranges endpoints are validated",
1367 ctx.testErrStage1("switch ranges endpoints are validated",
13371368 \\pub export fn entry() void {
13381369 \\ var x: i32 = 0;
13391370 \\ switch (x) {
......@@ -1347,16 +1378,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13471378 "tmp.zig:5:9: error: range start value is greater than the end value",
13481379 });
13491380
1350 cases.addTest("errors in for loop bodies are propagated",
1381 ctx.testErrStage1("errors in for loop bodies are propagated",
13511382 \\pub export fn entry() void {
13521383 \\ var arr: [100]u8 = undefined;
13531384 \\ for (arr) |bits| _ = @popCount(bits);
13541385 \\}
13551386 , &[_][]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",
13571388 });
13581389
1359 cases.addTest("@call rejects non comptime-known fn - always_inline",
1390 ctx.testErrStage1("@call rejects non comptime-known fn - always_inline",
13601391 \\pub export fn entry() void {
13611392 \\ var call_me: fn () void = undefined;
13621393 \\ @call(.{ .modifier = .always_inline }, call_me, .{});
......@@ -1365,7 +1396,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13651396 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function",
13661397 });
13671398
1368 cases.addTest("@call rejects non comptime-known fn - compile_time",
1399 ctx.testErrStage1("@call rejects non comptime-known fn - compile_time",
13691400 \\pub export fn entry() void {
13701401 \\ var call_me: fn () void = undefined;
13711402 \\ @call(.{ .modifier = .compile_time }, call_me, .{});
......@@ -1374,19 +1405,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13741405 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function",
13751406 });
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",
13781409 \\pub export fn entry() void {
13791410 \\ const bitfield = struct {
13801411 \\ e: u8,
13811412 \\ e: u8,
13821413 \\ };
13831414 \\ var a = .{@sizeOf(bitfield)};
1415 \\ _ = a;
13841416 \\}
13851417 , &[_][]const u8{
13861418 "tmp.zig:4:9: error: duplicate struct field: 'e'",
13871419 });
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",
13901422 \\pub fn A() type {
13911423 \\ return Q;
13921424 \\}
......@@ -1398,15 +1430,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13981430 "tmp.zig:2:12: error: use of undeclared identifier 'Q'",
13991431 });
14001432
1401 cases.add("bitCast to enum type",
1433 ctx.objErrStage1("bitCast to enum type",
14021434 \\export fn entry() void {
14031435 \\ const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));
1436 \\ _ = y;
14041437 \\}
14051438 , &[_][]const u8{
14061439 "tmp.zig:2:24: error: cannot cast a value of type 'y'",
14071440 });
14081441
1409 cases.add("comparing against undefined produces undefined value",
1442 ctx.objErrStage1("comparing against undefined produces undefined value",
14101443 \\export fn entry() void {
14111444 \\ if (2 == undefined) {}
14121445 \\}
......@@ -1414,17 +1447,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14141447 "tmp.zig:2:11: error: use of undefined value here causes undefined behavior",
14151448 });
14161449
1417 cases.add("comptime ptrcast of zero-sized type",
1450 ctx.objErrStage1("comptime ptrcast of zero-sized type",
14181451 \\fn foo() void {
14191452 \\ const node: struct {} = undefined;
14201453 \\ const vla_ptr = @ptrCast([*]const u8, &node);
1454 \\ _ = vla_ptr;
14211455 \\}
14221456 \\comptime { foo(); }
14231457 , &[_][]const u8{
14241458 "tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation",
14251459 });
14261460
1427 cases.add("slice sentinel mismatch",
1461 ctx.objErrStage1("slice sentinel mismatch",
14281462 \\fn foo() [:0]u8 {
14291463 \\ var x: []u8 = undefined;
14301464 \\ return x;
......@@ -1435,7 +1469,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14351469 "tmp.zig:3:12: note: destination pointer requires a terminating '0' sentinel",
14361470 });
14371471
1438 cases.add("cmpxchg with float",
1472 ctx.objErrStage1("cmpxchg with float",
14391473 \\export fn entry() void {
14401474 \\ var x: f32 = 0;
14411475 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);
......@@ -1444,7 +1478,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14441478 "tmp.zig:3:22: error: expected bool, integer, enum or pointer type, found 'f32'",
14451479 });
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",
14481482 \\export fn entry() void {
14491483 \\ var x: f32 = 0;
14501484 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);
......@@ -1453,15 +1487,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14531487 "tmp.zig:3:29: error: @atomicRmw with float only allowed with .Xchg, .Add and .Sub",
14541488 });
14551489
1456 cases.add("intToPtr with misaligned address",
1490 ctx.objErrStage1("intToPtr with misaligned address",
14571491 \\pub fn main() void {
14581492 \\ var y = @intToPtr([*]align(4) u8, 5);
1493 \\ _ = y;
14591494 \\}
14601495 , &[_][]const u8{
14611496 "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address",
14621497 });
14631498
1464 cases.add("invalid float literal",
1499 ctx.objErrStage1("invalid float literal",
14651500 \\const std = @import("std");
14661501 \\
14671502 \\pub fn main() void {
......@@ -1473,170 +1508,209 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14731508 "tmp.zig:5:29: error: invalid token: '.'",
14741509 });
14751510
1476 cases.add("invalid exponent in float literal - 1",
1511 ctx.objErrStage1("invalid exponent in float literal - 1",
14771512 \\fn main() void {
14781513 \\ var bad: f128 = 0x1.0p1ab1;
1514 \\ _ = bad;
14791515 \\}
14801516 , &[_][]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'",
14821519 });
14831520
1484 cases.add("invalid exponent in float literal - 2",
1521 ctx.objErrStage1("invalid exponent in float literal - 2",
14851522 \\fn main() void {
14861523 \\ var bad: f128 = 0x1.0p50F;
1524 \\ _ = bad;
14871525 \\}
14881526 , &[_][]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'",
14901529 });
14911530
1492 cases.add("invalid underscore placement in float literal - 1",
1531 ctx.objErrStage1("invalid underscore placement in float literal - 1",
14931532 \\fn main() void {
14941533 \\ var bad: f128 = 0._0;
1534 \\ _ = bad;
14951535 \\}
14961536 , &[_][]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: '_'",
14981539 });
14991540
1500 cases.add("invalid underscore placement in float literal - 2",
1541 ctx.objErrStage1("invalid underscore placement in float literal - 2",
15011542 \\fn main() void {
15021543 \\ var bad: f128 = 0_.0;
1544 \\ _ = bad;
15031545 \\}
15041546 , &[_][]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: '.'",
15061549 });
15071550
1508 cases.add("invalid underscore placement in float literal - 3",
1551 ctx.objErrStage1("invalid underscore placement in float literal - 3",
15091552 \\fn main() void {
15101553 \\ var bad: f128 = 0.0_;
1554 \\ _ = bad;
15111555 \\}
15121556 , &[_][]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: ';'",
15141559 });
15151560
1516 cases.add("invalid underscore placement in float literal - 4",
1561 ctx.objErrStage1("invalid underscore placement in float literal - 4",
15171562 \\fn main() void {
15181563 \\ var bad: f128 = 1.0e_1;
1564 \\ _ = bad;
15191565 \\}
15201566 , &[_][]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: '_'",
15221569 });
15231570
1524 cases.add("invalid underscore placement in float literal - 5",
1571 ctx.objErrStage1("invalid underscore placement in float literal - 5",
15251572 \\fn main() void {
15261573 \\ var bad: f128 = 1.0e+_1;
1574 \\ _ = bad;
15271575 \\}
15281576 , &[_][]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: '_'",
15301579 });
15311580
1532 cases.add("invalid underscore placement in float literal - 6",
1581 ctx.objErrStage1("invalid underscore placement in float literal - 6",
15331582 \\fn main() void {
15341583 \\ var bad: f128 = 1.0e-_1;
1584 \\ _ = bad;
15351585 \\}
15361586 , &[_][]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: '_'",
15381589 });
15391590
1540 cases.add("invalid underscore placement in float literal - 7",
1591 ctx.objErrStage1("invalid underscore placement in float literal - 7",
15411592 \\fn main() void {
15421593 \\ var bad: f128 = 1.0e-1_;
1594 \\ _ = bad;
15431595 \\}
15441596 , &[_][]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: ';'",
15461599 });
15471600
1548 cases.add("invalid underscore placement in float literal - 9",
1601 ctx.objErrStage1("invalid underscore placement in float literal - 9",
15491602 \\fn main() void {
15501603 \\ var bad: f128 = 1__0.0e-1;
1604 \\ _ = bad;
15511605 \\}
15521606 , &[_][]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: '_'",
15541609 });
15551610
1556 cases.add("invalid underscore placement in float literal - 10",
1611 ctx.objErrStage1("invalid underscore placement in float literal - 10",
15571612 \\fn main() void {
15581613 \\ var bad: f128 = 1.0__0e-1;
1614 \\ _ = bad;
15591615 \\}
15601616 , &[_][]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: '_'",
15621619 });
15631620
1564 cases.add("invalid underscore placement in float literal - 11",
1621 ctx.objErrStage1("invalid underscore placement in float literal - 11",
15651622 \\fn main() void {
15661623 \\ var bad: f128 = 1.0e-1__0;
1624 \\ _ = bad;
15671625 \\}
15681626 , &[_][]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: '_'",
15701629 });
15711630
1572 cases.add("invalid underscore placement in float literal - 12",
1631 ctx.objErrStage1("invalid underscore placement in float literal - 12",
15731632 \\fn main() void {
15741633 \\ var bad: f128 = 0_x0.0;
1634 \\ _ = bad;
15751635 \\}
15761636 , &[_][]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'",
15781639 });
15791640
1580 cases.add("invalid underscore placement in float literal - 13",
1641 ctx.objErrStage1("invalid underscore placement in float literal - 13",
15811642 \\fn main() void {
15821643 \\ var bad: f128 = 0x_0.0;
1644 \\ _ = bad;
15831645 \\}
15841646 , &[_][]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: '_'",
15861649 });
15871650
1588 cases.add("invalid underscore placement in float literal - 14",
1651 ctx.objErrStage1("invalid underscore placement in float literal - 14",
15891652 \\fn main() void {
15901653 \\ var bad: f128 = 0x0.0_p1;
1654 \\ _ = bad;
15911655 \\}
15921656 , &[_][]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'",
15941659 });
15951660
1596 cases.add("invalid underscore placement in int literal - 1",
1661 ctx.objErrStage1("invalid underscore placement in int literal - 1",
15971662 \\fn main() void {
15981663 \\ var bad: u128 = 0010_;
1664 \\ _ = bad;
15991665 \\}
16001666 , &[_][]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: ';'",
16021669 });
16031670
1604 cases.add("invalid underscore placement in int literal - 2",
1671 ctx.objErrStage1("invalid underscore placement in int literal - 2",
16051672 \\fn main() void {
16061673 \\ var bad: u128 = 0b0010_;
1674 \\ _ = bad;
16071675 \\}
16081676 , &[_][]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: ';'",
16101679 });
16111680
1612 cases.add("invalid underscore placement in int literal - 3",
1681 ctx.objErrStage1("invalid underscore placement in int literal - 3",
16131682 \\fn main() void {
16141683 \\ var bad: u128 = 0o0010_;
1684 \\ _ = bad;
16151685 \\}
16161686 , &[_][]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: ';'",
16181689 });
16191690
1620 cases.add("invalid underscore placement in int literal - 4",
1691 ctx.objErrStage1("invalid underscore placement in int literal - 4",
16211692 \\fn main() void {
16221693 \\ var bad: u128 = 0x0010_;
1694 \\ _ = bad;
16231695 \\}
16241696 , &[_][]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: ';'",
16261699 });
16271700
1628 cases.add("comptime struct field, no init value",
1701 ctx.objErrStage1("comptime struct field, no init value",
16291702 \\const Foo = struct {
16301703 \\ comptime b: i32,
16311704 \\};
16321705 \\export fn entry() void {
16331706 \\ var f: Foo = undefined;
1707 \\ _ = f;
16341708 \\}
16351709 , &[_][]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",
16371711 });
16381712
1639 cases.add("bad usage of @call",
1713 ctx.objErrStage1("bad usage of @call",
16401714 \\export fn entry1() void {
16411715 \\ @call(.{}, foo, {});
16421716 \\}
......@@ -1665,20 +1739,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
16651739 "tmp.zig:15:5: error: the specified modifier requires a comptime-known function",
16661740 });
16671741
1668 cases.add("exported async function",
1742 ctx.objErrStage1("exported async function",
16691743 \\export fn foo() callconv(.Async) void {}
16701744 , &[_][]const u8{
16711745 "tmp.zig:1:1: error: exported function cannot be async",
16721746 });
16731747
1674 cases.addExe("main missing name",
1748 ctx.exeErrStage1("main missing name",
16751749 \\pub fn (main) void {}
16761750 , &[_][]const u8{
16771751 "tmp.zig:1:5: error: missing function name",
16781752 });
16791753
1680 cases.addCase(x: {
1681 var tc = cases.create("call with new stack on unsupported target",
1754 {
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(
16821762 \\var buf: [10]u8 align(16) = undefined;
16831763 \\export fn entry() void {
16841764 \\ @call(.{.stack = &buf}, foo, .{});
......@@ -1687,17 +1767,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
16871767 , &[_][]const u8{
16881768 "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack",
16891769 });
1690 tc.target = std.zig.CrossTarget{
1691 .cpu_arch = .wasm32,
1692 .os_tag = .wasi,
1693 .abi = .none,
1694 };
1695 break :x tc;
1696 });
1770 }
16971771
16981772 // Note: One of the error messages here is backwards. It would be nice to fix, but that's not
16991773 // 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",
17011775 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
17021776 \\ return ptr;
17031777 \\}
......@@ -1706,9 +1780,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17061780 \\}
17071781 \\export fn entry3() void {
17081782 \\ var array: [2:0]u8 = [_:255]u8{1, 2};
1783 \\ _ = array;
17091784 \\}
17101785 \\export fn entry4() void {
17111786 \\ var array: [2:0]u8 = [_]u8{1, 2};
1787 \\ _ = array;
17121788 \\}
17131789 , &[_][]const u8{
17141790 "tmp.zig:2:12: error: expected type '[*:0]u8', found '[*:255]u8'",
......@@ -1718,11 +1794,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17181794
17191795 "tmp.zig:8:35: error: expected type '[2:255]u8', found '[2:0]u8'",
17201796 "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'",
1722 "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",
1797 "tmp.zig:12:31: error: expected type '[2:0]u8', found '[2]u8'",
1798 "tmp.zig:12:31: note: destination array requires a terminating '0' sentinel",
17231799 });
17241800
1725 cases.add("empty switch on an integer",
1801 ctx.objErrStage1("empty switch on an integer",
17261802 \\export fn entry() void {
17271803 \\ var x: u32 = 0;
17281804 \\ switch(x) {}
......@@ -1731,7 +1807,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17311807 "tmp.zig:3:5: error: switch must handle all possibilities",
17321808 });
17331809
1734 cases.add("incorrect return type",
1810 ctx.objErrStage1("incorrect return type",
17351811 \\ pub export fn entry() void{
17361812 \\ _ = foo();
17371813 \\ }
......@@ -1751,12 +1827,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17511827 "tmp.zig:8:16: error: expected type 'A', found 'B'",
17521828 });
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",
17551831 \\const Foo = struct {
17561832 \\ ptr: ?*usize,
17571833 \\ uval: u32,
17581834 \\};
17591835 \\fn get_uval(x: u32) !u32 {
1836 \\ _ = x;
17601837 \\ return error.NotFound;
17611838 \\}
17621839 \\export fn entry() void {
......@@ -1764,12 +1841,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17641841 \\ .ptr = null,
17651842 \\ .uval = get_uval(42),
17661843 \\ };
1844 \\ _ = afoo;
17671845 \\}
17681846 , &[_][]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'",
17701848 });
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",
17731851 \\fn maybe(is: bool) ?u8 {
17741852 \\ if (is) return @as(u8, 10) else return null;
17751853 \\}
......@@ -1782,12 +1860,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17821860 \\export fn entry() void {
17831861 \\ var u = U{ .Ye = maybe(false) };
17841862 \\ var s = S{ .num = maybe(false) };
1863 \\ _ = u;
1864 \\ _ = s;
17851865 \\}
17861866 , &[_][]const u8{
17871867 "tmp.zig:11:27: error: expected type 'u8', found '?u8'",
17881868 });
17891869
1790 cases.add("missing result type for phi node",
1870 ctx.objErrStage1("missing result type for phi node",
17911871 \\fn foo() !void {
17921872 \\ return anyerror.Foo;
17931873 \\}
......@@ -1798,7 +1878,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
17981878 "tmp.zig:5:17: error: integer value 0 cannot be coerced to type 'void'",
17991879 });
18001880
1801 cases.add("atomicrmw with enum op not .Xchg",
1881 ctx.objErrStage1("atomicrmw with enum op not .Xchg",
18021882 \\export fn entry() void {
18031883 \\ const E = enum(u8) {
18041884 \\ a,
......@@ -1813,7 +1893,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18131893 "tmp.zig:9:27: error: @atomicRmw with enum only allowed with .Xchg",
18141894 });
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",
18171897 \\extern fn puts(s: [*:0]const u8) c_int;
18181898 \\pub fn main() void {
18191899 \\ const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};
......@@ -1824,7 +1904,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18241904 "tmp.zig:5:14: error: expected type '[*:0]const u8', found '[*]const u8'",
18251905 });
18261906
1827 cases.add("atomic orderings of atomicStore Acquire or AcqRel",
1907 ctx.objErrStage1("atomic orderings of atomicStore Acquire or AcqRel",
18281908 \\export fn entry() void {
18291909 \\ var x: u32 = 0;
18301910 \\ @atomicStore(u32, &x, 1, .Acquire);
......@@ -1833,7 +1913,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18331913 "tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel",
18341914 });
18351915
1836 cases.add("missing const in slice with nested array type",
1916 ctx.objErrStage1("missing const in slice with nested array type",
18371917 \\const Geo3DTex2D = struct { vertices: [][2]f32 };
18381918 \\pub fn getGeo3DTex2D() Geo3DTex2D {
18391919 \\ return Geo3DTex2D{
......@@ -1844,12 +1924,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18441924 \\}
18451925 \\export fn entry() void {
18461926 \\ var geo_data = getGeo3DTex2D();
1927 \\ _ = geo_data;
18471928 \\}
18481929 , &[_][]const u8{
18491930 "tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'",
18501931 });
18511932
1852 cases.add("slicing of global undefined pointer",
1933 ctx.objErrStage1("slicing of global undefined pointer",
18531934 \\var buf: *[1]u8 = undefined;
18541935 \\export fn entry() void {
18551936 \\ _ = buf[0..1];
......@@ -1858,18 +1939,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18581939 "tmp.zig:3:12: error: non-zero length slice of undefined pointer",
18591940 });
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",
18621943 \\const MenuEffect = enum {};
1863 \\fn func(effect: MenuEffect) void {}
1944 \\fn func(effect: MenuEffect) void { _ = effect; }
18641945 \\export fn entry() void {
18651946 \\ func(MenuEffect.ThisDoesNotExist);
18661947 \\}
18671948 , &[_][]const u8{
1868 "tmp.zig:1:20: error: enums must have 1 or more fields",
1869 "tmp.zig:4:20: note: referenced here",
1949 "tmp.zig:1:20: error: enum declarations must have at least one tag",
18701950 });
18711951
1872 cases.add("store vector pointer with unknown runtime index",
1952 ctx.objErrStage1("store vector pointer with unknown runtime index",
18731953 \\export fn entry() void {
18741954 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
18751955 \\
......@@ -1884,22 +1964,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18841964 "tmp.zig:9:8: error: unable to determine vector element index of type '*align(16:0:4:?) i32",
18851965 });
18861966
1887 cases.add("load vector pointer with unknown runtime index",
1967 ctx.objErrStage1("load vector pointer with unknown runtime index",
18881968 \\export fn entry() void {
18891969 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
18901970 \\
18911971 \\ var i: u32 = 0;
18921972 \\ var x = loadv(&v[i]);
1973 \\ _ = x;
18931974 \\}
18941975 \\
18951976 \\fn loadv(ptr: anytype) i32 {
18961977 \\ return ptr.*;
18971978 \\}
18981979 , &[_][]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",
19001981 });
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",
19031984 \\const resolutions = [*][*]const u8{
19041985 \\ "[320 240 ]",
19051986 \\ null,
......@@ -1911,7 +1992,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19111992 "tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'",
19121993 });
19131994
1914 cases.add("comparison with error union and error value",
1995 ctx.objErrStage1("comparison with error union and error value",
19151996 \\export fn entry() void {
19161997 \\ var number_or_error: anyerror!i32 = error.SomethingAwful;
19171998 \\ _ = number_or_error == error.SomethingAwful;
......@@ -1920,7 +2001,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19202001 "tmp.zig:3:25: error: operator not allowed for type 'anyerror!i32'",
19212002 });
19222003
1923 cases.add("switch with overlapping case ranges",
2004 ctx.objErrStage1("switch with overlapping case ranges",
19242005 \\export fn entry() void {
19252006 \\ var q: u8 = 0;
19262007 \\ switch (q) {
......@@ -1932,28 +2013,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19322013 "tmp.zig:5:9: error: duplicate switch value",
19332014 });
19342015
1935 cases.add("invalid optional type in extern struct",
2016 ctx.objErrStage1("invalid optional type in extern struct",
19362017 \\const stroo = extern struct {
19372018 \\ moo: ?[*c]u8,
19382019 \\};
1939 \\export fn testf(fluff: *stroo) void {}
2020 \\export fn testf(fluff: *stroo) void { _ = fluff; }
19402021 , &[_][]const u8{
19412022 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?[*c]u8'",
19422023 });
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",
19452026 \\fn foo() anyerror!u32 {
19462027 \\ return 1;
19472028 \\}
19482029 \\
19492030 \\export fn entry() void {
19502031 \\ const x = -foo();
2032 \\ _ = x;
19512033 \\}
19522034 , &[_][]const u8{
19532035 "tmp.zig:6:15: error: negation of type 'anyerror!u32'",
19542036 });
19552037
1956 cases.add("attempt to create 17 bit float type",
2038 ctx.objErrStage1("attempt to create 17 bit float type",
19572039 \\const builtin = @import("std").builtin;
19582040 \\comptime {
19592041 \\ _ = @Type(builtin.TypeInfo { .Float = builtin.TypeInfo.Float { .bits = 17 } });
......@@ -1962,7 +2044,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19622044 "tmp.zig:3:32: error: 17-bit float unsupported",
19632045 });
19642046
1965 cases.add("wrong type for @Type",
2047 ctx.objErrStage1("wrong type for @Type",
19662048 \\export fn entry() void {
19672049 \\ _ = @Type(0);
19682050 \\}
......@@ -1970,7 +2052,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19702052 "tmp.zig:2:15: error: expected type 'std.builtin.TypeInfo', found 'comptime_int'",
19712053 });
19722054
1973 cases.add("@Type with non-constant expression",
2055 ctx.objErrStage1("@Type with non-constant expression",
19742056 \\const builtin = @import("std").builtin;
19752057 \\var globalTypeInfo : builtin.TypeInfo = undefined;
19762058 \\export fn entry() void {
......@@ -1980,7 +2062,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19802062 "tmp.zig:4:15: error: unable to evaluate constant expression",
19812063 });
19822064
1983 cases.add("wrong type for argument tuple to @asyncCall",
2065 ctx.objErrStage1("wrong type for argument tuple to @asyncCall",
19842066 \\export fn entry1() void {
19852067 \\ var frame: @Frame(foo) = undefined;
19862068 \\ @asyncCall(&frame, {}, foo, {});
......@@ -1993,7 +2075,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19932075 "tmp.zig:3:33: error: expected tuple or struct, found 'void'",
19942076 });
19952077
1996 cases.add("wrong type for result ptr to @asyncCall",
2078 ctx.objErrStage1("wrong type for result ptr to @asyncCall",
19972079 \\export fn entry() void {
19982080 \\ _ = async amain();
19992081 \\}
......@@ -2008,25 +2090,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
20082090 "tmp.zig:6:37: error: expected type '*i32', found 'bool'",
20092091 });
20102092
2011 cases.add("shift amount has to be an integer type",
2093 ctx.objErrStage1("shift amount has to be an integer type",
20122094 \\export fn entry() void {
20132095 \\ const x = 1 << &@as(u8, 10);
2096 \\ _ = x;
20142097 \\}
20152098 , &[_][]const u8{
20162099 "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*const u8'",
20172100 "tmp.zig:2:17: note: referenced here",
20182101 });
20192102
2020 cases.add("bit shifting only works on integer types",
2103 ctx.objErrStage1("bit shifting only works on integer types",
20212104 \\export fn entry() void {
20222105 \\ const x = &@as(u8, 1) << 10;
2106 \\ _ = x;
20232107 \\}
20242108 , &[_][]const u8{
20252109 "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*const u8'",
20262110 "tmp.zig:2:27: note: referenced here",
20272111 });
20282112
2029 cases.add("struct depends on itself via optional field",
2113 ctx.objErrStage1("struct depends on itself via optional field",
20302114 \\const LhsExpr = struct {
20312115 \\ rhsExpr: ?AstObject,
20322116 \\};
......@@ -2036,6 +2120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
20362120 \\export fn entry() void {
20372121 \\ const lhsExpr = LhsExpr{ .rhsExpr = null };
20382122 \\ const obj = AstObject{ .lhsExpr = lhsExpr };
2123 \\ _ = obj;
20392124 \\}
20402125 , &[_][]const u8{
20412126 "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",
......@@ -2043,51 +2128,54 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
20432128 "tmp.zig:2:5: note: while checking this field",
20442129 });
20452130
2046 cases.add("alignment of enum field specified",
2131 ctx.objErrStage1("alignment of enum field specified",
20472132 \\const Number = enum {
20482133 \\ a,
20492134 \\ b align(i32),
20502135 \\};
20512136 \\export fn entry1() void {
20522137 \\ var x: Number = undefined;
2138 \\ _ = x;
20532139 \\}
20542140 , &[_][]const u8{
2055 "tmp.zig:3:13: error: structs and unions, not enums, support field alignment",
2056 "tmp.zig:1:16: note: consider 'union(enum)' here",
2141 "tmp.zig:3:7: error: expected ',', found 'align'",
20572142 });
20582143
2059 cases.add("bad alignment type",
2144 ctx.objErrStage1("bad alignment type",
20602145 \\export fn entry1() void {
20612146 \\ var x: []align(true) i32 = undefined;
2147 \\ _ = x;
20622148 \\}
20632149 \\export fn entry2() void {
20642150 \\ var x: *align(@as(f64, 12.34)) i32 = undefined;
2151 \\ _ = x;
20652152 \\}
20662153 , &[_][]const u8{
20672154 "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'",
20692156 });
20702157
2071 cases.addCase(x: {
2072 var tc = cases.create("variable in inline assembly template cannot be found",
2158 {
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(
20732166 \\export fn entry() void {
20742167 \\ var sp = asm volatile (
20752168 \\ "mov %[foo], sp"
20762169 \\ : [bar] "=r" (-> usize)
20772170 \\ );
2171 \\ _ = sp;
20782172 \\}
20792173 , &[_][]const u8{
20802174 "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs",
20812175 });
2082 tc.target = std.zig.CrossTarget{
2083 .cpu_arch = .x86_64,
2084 .os_tag = .linux,
2085 .abi = .gnu,
2086 };
2087 break :x tc;
2088 });
2176 }
20892177
2090 cases.add("indirect recursion of async functions detected",
2178 ctx.objErrStage1("indirect recursion of async functions detected",
20912179 \\var frame: ?anyframe = null;
20922180 \\
20932181 \\export fn a() void {
......@@ -2122,7 +2210,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
21222210 "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSumIndirect)' here",
21232211 });
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",
21262214 \\export fn a() void {
21272215 \\ var non_async_fn: fn () void = undefined;
21282216 \\ non_async_fn = func;
......@@ -2136,20 +2224,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
21362224 "tmp.zig:6:5: note: suspends here",
21372225 });
21382226
2139 cases.add("bad alignment in @asyncCall",
2140 \\export fn entry() void {
2141 \\ var ptr: fn () callconv(.Async) void = func;
2142 \\ var bytes: [64]u8 = undefined;
2143 \\ _ = @asyncCall(&bytes, {}, ptr, .{});
2144 \\}
2145 \\fn func() callconv(.Async) void {}
2146 , &[_][]const u8{
2147 // Split the check in two as the alignment value is target dependent.
2148 "tmp.zig:4:21: error: expected type '[]align(",
2149 ") u8', found '*[64]u8'",
2150 });
2227 {
2228 const case = ctx.obj("bad alignment in @asyncCall", .{
2229 .cpu_arch = .aarch64,
2230 .os_tag = .linux,
2231 .abi = .none,
2232 });
2233 case.backend = .stage1;
2234 case.addError(
2235 \\export fn entry() void {
2236 \\ var ptr: fn () callconv(.Async) void = func;
2237 \\ var bytes: [64]u8 = undefined;
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",
21532247 \\export fn entry() void {
21542248 \\ @fence(.Monotonic);
21552249 \\}
......@@ -2157,20 +2251,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
21572251 "tmp.zig:2:12: error: atomic ordering must be Acquire or stricter",
21582252 });
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",
21612255 \\export fn a() void {
21622256 \\ var x: [10]u8 = undefined;
21632257 \\ var y: []align(16) u8 = &x;
2258 \\ _ = y;
21642259 \\}
21652260 , &[_][]const u8{
21662261 "tmp.zig:3:30: error: expected type '[]align(16) u8', found '*[10]u8'",
21672262 });
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)",
21702265 \\export fn entry() void {
21712266 \\ var damn = Container{
21722267 \\ .not_optional = getOptional(i32),
21732268 \\ };
2269 \\ _ = damn;
21742270 \\}
21752271 \\pub fn getOptional(comptime T: type) ?T {
21762272 \\ return 0;
......@@ -2182,11 +2278,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
21822278 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",
21832279 });
21842280
2185 cases.add("result location incompatibility mismatching handle_is_ptr",
2281 ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr",
21862282 \\export fn entry() void {
21872283 \\ var damn = Container{
21882284 \\ .not_optional = getOptional(),
21892285 \\ };
2286 \\ _ = damn;
21902287 \\}
21912288 \\pub fn getOptional() ?i32 {
21922289 \\ return 0;
......@@ -2198,7 +2295,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
21982295 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",
21992296 });
22002297
2201 cases.add("const frame cast to anyframe",
2298 ctx.objErrStage1("const frame cast to anyframe",
22022299 \\export fn a() void {
22032300 \\ const f = async func();
22042301 \\ resume f;
......@@ -2206,6 +2303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22062303 \\export fn b() void {
22072304 \\ const f = async func();
22082305 \\ var x: anyframe = &f;
2306 \\ _ = x;
22092307 \\}
22102308 \\fn func() void {
22112309 \\ suspend {}
......@@ -2215,27 +2313,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22152313 "tmp.zig:7:24: error: expected type 'anyframe', found '*const @Frame(func)'",
22162314 });
22172315
2218 cases.add("prevent bad implicit casting of anyframe types",
2316 ctx.objErrStage1("prevent bad implicit casting of anyframe types",
22192317 \\export fn a() void {
22202318 \\ var x: anyframe = undefined;
22212319 \\ var y: anyframe->i32 = x;
2320 \\ _ = y;
22222321 \\}
22232322 \\export fn b() void {
22242323 \\ var x: i32 = undefined;
22252324 \\ var y: anyframe->i32 = x;
2325 \\ _ = y;
22262326 \\}
22272327 \\export fn c() void {
22282328 \\ var x: @Frame(func) = undefined;
22292329 \\ var y: anyframe->i32 = &x;
2330 \\ _ = y;
22302331 \\}
22312332 \\fn func() void {}
22322333 , &[_][]const u8{
22332334 "tmp.zig:3:28: error: expected type 'anyframe->i32', found 'anyframe'",
2234 "tmp.zig:7:28: error: expected type 'anyframe->i32', found 'i32'",
2235 "tmp.zig:11:29: error: expected type 'anyframe->i32', found '*@Frame(func)'",
2335 "tmp.zig:8:28: error: expected type 'anyframe->i32', found 'i32'",
2336 "tmp.zig:13:29: error: expected type 'anyframe->i32', found '*@Frame(func)'",
22362337 });
22372338
2238 cases.add("wrong frame type used for async call",
2339 ctx.objErrStage1("wrong frame type used for async call",
22392340 \\export fn entry() void {
22402341 \\ var frame: @Frame(foo) = undefined;
22412342 \\ frame = async bar();
......@@ -2250,18 +2351,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22502351 "tmp.zig:3:13: error: expected type '*@Frame(bar)', found '*@Frame(foo)'",
22512352 });
22522353
2253 cases.add("@Frame() of generic function",
2354 ctx.objErrStage1("@Frame() of generic function",
22542355 \\export fn entry() void {
22552356 \\ var frame: @Frame(func) = undefined;
2357 \\ _ = frame;
22562358 \\}
22572359 \\fn func(comptime T: type) void {
22582360 \\ var x: T = undefined;
2361 \\ _ = x;
22592362 \\}
22602363 , &[_][]const u8{
22612364 "tmp.zig:2:16: error: @Frame() of generic function",
22622365 });
22632366
2264 cases.add("@frame() causes function to be async",
2367 ctx.objErrStage1("@frame() causes function to be async",
22652368 \\export fn entry() void {
22662369 \\ func();
22672370 \\}
......@@ -2273,10 +2376,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22732376 "tmp.zig:5:9: note: @frame() causes function to be async",
22742377 });
22752378
2276 cases.add("invalid suspend in exported function",
2379 ctx.objErrStage1("invalid suspend in exported function",
22772380 \\export fn entry() void {
22782381 \\ var frame = async func();
22792382 \\ var result = await frame;
2383 \\ _ = result;
22802384 \\}
22812385 \\fn func() void {
22822386 \\ suspend {}
......@@ -2286,7 +2390,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22862390 "tmp.zig:3:18: note: await here is a suspend point",
22872391 });
22882392
2289 cases.add("async function indirectly depends on its own frame",
2393 ctx.objErrStage1("async function indirectly depends on its own frame",
22902394 \\export fn entry() void {
22912395 \\ _ = async amain();
22922396 \\}
......@@ -2295,6 +2399,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22952399 \\}
22962400 \\fn other() void {
22972401 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
2402 \\ _ = x;
22982403 \\}
22992404 , &[_][]const u8{
23002405 "tmp.zig:4:1: error: unable to determine async function frame of 'amain'",
......@@ -2302,19 +2407,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23022407 "tmp.zig:8:13: note: referenced here",
23032408 });
23042409
2305 cases.add("async function depends on its own frame",
2410 ctx.objErrStage1("async function depends on its own frame",
23062411 \\export fn entry() void {
23072412 \\ _ = async amain();
23082413 \\}
23092414 \\fn amain() callconv(.Async) void {
23102415 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
2416 \\ _ = x;
23112417 \\}
23122418 , &[_][]const u8{
23132419 "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet",
23142420 "tmp.zig:5:13: note: referenced here",
23152421 });
23162422
2317 cases.add("non async function pointer passed to @asyncCall",
2423 ctx.objErrStage1("non async function pointer passed to @asyncCall",
23182424 \\export fn entry() void {
23192425 \\ var ptr = afunc;
23202426 \\ var bytes: [100]u8 align(16) = undefined;
......@@ -2325,7 +2431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23252431 "tmp.zig:4:32: error: expected async function, found 'fn() void'",
23262432 });
23272433
2328 cases.add("runtime-known async function called",
2434 ctx.objErrStage1("runtime-known async function called",
23292435 \\export fn entry() void {
23302436 \\ _ = async amain();
23312437 \\}
......@@ -2338,7 +2444,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23382444 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",
23392445 });
23402446
2341 cases.add("runtime-known function called with async keyword",
2447 ctx.objErrStage1("runtime-known function called with async keyword",
23422448 \\export fn entry() void {
23432449 \\ var ptr = afunc;
23442450 \\ _ = async ptr();
......@@ -2349,7 +2455,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23492455 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",
23502456 });
23512457
2352 cases.add("function with ccc indirectly calling async function",
2458 ctx.objErrStage1("function with ccc indirectly calling async function",
23532459 \\export fn entry() void {
23542460 \\ foo();
23552461 \\}
......@@ -2366,7 +2472,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23662472 "tmp.zig:8:5: note: suspends here",
23672473 });
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",
23702476 \\const Union = union(enum) {
23712477 \\ A: usize,
23722478 \\ B: isize,
......@@ -2374,7 +2480,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23742480 \\comptime {
23752481 \\ var u = Union{ .A = 8 };
23762482 \\ switch (u) {
2377 \\ .A, .B => |e| unreachable,
2483 \\ .A, .B => |e| {
2484 \\ _ = e;
2485 \\ unreachable;
2486 \\ },
23782487 \\ }
23792488 \\}
23802489 , &[_][]const u8{
......@@ -2383,7 +2492,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23832492 "tmp.zig:8:13: note: type 'isize' here",
23842493 });
23852494
2386 cases.add("wrong type to @hasField",
2495 ctx.objErrStage1("wrong type to @hasField",
23872496 \\export fn entry() bool {
23882497 \\ return @hasField(i32, "hi");
23892498 \\}
......@@ -2391,44 +2500,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
23912500 "tmp.zig:2:22: error: type 'i32' does not support @hasField",
23922501 });
23932502
2394 cases.add("slice passed as array init type with elems",
2503 ctx.objErrStage1("slice passed as array init type with elems",
23952504 \\export fn entry() void {
23962505 \\ const x = []u8{1, 2};
2506 \\ _ = x;
23972507 \\}
23982508 , &[_][]const u8{
23992509 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",
24002510 });
24012511
2402 cases.add("slice passed as array init type",
2512 ctx.objErrStage1("slice passed as array init type",
24032513 \\export fn entry() void {
24042514 \\ const x = []u8{};
2515 \\ _ = x;
24052516 \\}
24062517 , &[_][]const u8{
24072518 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",
24082519 });
24092520
2410 cases.add("inferred array size invalid here",
2521 ctx.objErrStage1("inferred array size invalid here",
24112522 \\export fn entry() void {
24122523 \\ const x = [_]u8;
2524 \\ _ = x;
24132525 \\}
24142526 \\export fn entry2() void {
24152527 \\ const S = struct { a: *const [_]u8 };
24162528 \\ var a = .{ S{} };
2529 \\ _ = a;
24172530 \\}
24182531 , &[_][]const u8{
2419 "tmp.zig:2:15: error: inferred array size invalid here",
2420 "tmp.zig:5:34: error: inferred array size invalid here",
2532 "tmp.zig:2:16: error: unable to infer array size",
2533 "tmp.zig:6:35: error: unable to infer array size",
24212534 });
24222535
2423 cases.add("initializing array with struct syntax",
2536 ctx.objErrStage1("initializing array with struct syntax",
24242537 \\export fn entry() void {
24252538 \\ const x = [_]u8{ .y = 2 };
2539 \\ _ = x;
24262540 \\}
24272541 , &[_][]const u8{
24282542 "tmp.zig:2:15: error: initializing array with struct syntax",
24292543 });
24302544
2431 cases.add("compile error in struct init expression",
2545 ctx.objErrStage1("compile error in struct init expression",
24322546 \\const Foo = struct {
24332547 \\ a: i32 = crap,
24342548 \\ b: i32,
......@@ -2437,23 +2551,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
24372551 \\ var x = Foo{
24382552 \\ .b = 5,
24392553 \\ };
2554 \\ _ = x;
24402555 \\}
24412556 , &[_][]const u8{
24422557 "tmp.zig:2:14: error: use of undeclared identifier 'crap'",
24432558 });
24442559
2445 cases.add("undefined as field type is rejected",
2560 ctx.objErrStage1("undefined as field type is rejected",
24462561 \\const Foo = struct {
24472562 \\ a: undefined,
24482563 \\};
24492564 \\export fn entry1() void {
24502565 \\ const foo: Foo = undefined;
2566 \\ _ = foo;
24512567 \\}
24522568 , &[_][]const u8{
24532569 "tmp.zig:2:8: error: use of undefined value here causes undefined behavior",
24542570 });
24552571
2456 cases.add("@hasDecl with non-container",
2572 ctx.objErrStage1("@hasDecl with non-container",
24572573 \\export fn entry() void {
24582574 \\ _ = @hasDecl(i32, "hi");
24592575 \\}
......@@ -2461,16 +2577,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
24612577 "tmp.zig:2:18: error: expected struct, enum, or union; found 'i32'",
24622578 });
24632579
2464 cases.add("field access of slices",
2580 ctx.objErrStage1("field access of slices",
24652581 \\export fn entry() void {
24662582 \\ var slice: []i32 = undefined;
24672583 \\ const info = @TypeOf(slice).unknown;
2584 \\ _ = info;
24682585 \\}
24692586 , &[_][]const u8{
24702587 "tmp.zig:3:32: error: type 'type' does not support field access",
24712588 });
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",
24742591 \\export fn func() void {
24752592 \\ var strValue: [*c]u8 = undefined;
24762593 \\ strValue = strValue orelse "";
......@@ -2480,19 +2597,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
24802597 "tmp.zig:3:32: note: cast discards const qualifier",
24812598 });
24822599
2483 cases.add("overflow in enum value allocation",
2600 ctx.objErrStage1("overflow in enum value allocation",
24842601 \\const Moo = enum(u8) {
24852602 \\ Last = 255,
24862603 \\ Over,
24872604 \\};
24882605 \\pub fn main() void {
24892606 \\ var y = Moo.Last;
2607 \\ _ = y;
24902608 \\}
24912609 , &[_][]const u8{
24922610 "tmp.zig:3:5: error: enumeration value 256 too large for type 'u8'",
24932611 });
24942612
2495 cases.add("attempt to cast enum literal to error",
2613 ctx.objErrStage1("attempt to cast enum literal to error",
24962614 \\export fn entry() void {
24972615 \\ switch (error.Hi) {
24982616 \\ .Hi => {},
......@@ -2502,7 +2620,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25022620 "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'",
25032621 });
25042622
2505 cases.add("@sizeOf bad type",
2623 ctx.objErrStage1("@sizeOf bad type",
25062624 \\export fn entry() usize {
25072625 \\ return @sizeOf(@TypeOf(null));
25082626 \\}
......@@ -2510,7 +2628,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25102628 "tmp.zig:2:20: error: no size available for type '(null)'",
25112629 });
25122630
2513 cases.add("generic function where return type is self-referenced",
2631 ctx.objErrStage1("generic function where return type is self-referenced",
25142632 \\fn Foo(comptime T: type) Foo(T) {
25152633 \\ return struct{ x: T };
25162634 \\}
......@@ -2518,34 +2636,37 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25182636 \\ const t = Foo(u32) {
25192637 \\ .x = 1
25202638 \\ };
2639 \\ _ = t;
25212640 \\}
25222641 , &[_][]const u8{
25232642 "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches",
25242643 "tmp.zig:5:18: note: referenced here",
25252644 });
25262645
2527 cases.add("@ptrToInt 0 to non optional pointer",
2646 ctx.objErrStage1("@ptrToInt 0 to non optional pointer",
25282647 \\export fn entry() void {
25292648 \\ var b = @intToPtr(*i32, 0);
2649 \\ _ = b;
25302650 \\}
25312651 , &[_][]const u8{
25322652 "tmp.zig:2:13: error: pointer type '*i32' does not allow address zero",
25332653 });
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",
25362656 \\const Foo = enum {
25372657 \\ a,
25382658 \\ b,
25392659 \\};
25402660 \\export fn entry() void {
25412661 \\ const x: Foo = .c;
2662 \\ _ = x;
25422663 \\}
25432664 , &[_][]const u8{
25442665 "tmp.zig:6:20: error: enum 'Foo' has no field named 'c'",
25452666 "tmp.zig:1:13: note: 'Foo' declared here",
25462667 });
25472668
2548 cases.add("discarding error value",
2669 ctx.objErrStage1("discarding error value",
25492670 \\export fn entry() void {
25502671 \\ _ = foo();
25512672 \\}
......@@ -2556,7 +2677,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25562677 "tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`",
25572678 });
25582679
2559 cases.add("volatile on global assembly",
2680 ctx.objErrStage1("volatile on global assembly",
25602681 \\comptime {
25612682 \\ asm volatile ("");
25622683 \\}
......@@ -2564,7 +2685,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25642685 "tmp.zig:2:9: error: volatile is meaningless on global assembly",
25652686 });
25662687
2567 cases.add("invalid multiple dereferences",
2688 ctx.objErrStage1("invalid multiple dereferences",
25682689 \\export fn a() void {
25692690 \\ var box = Box{ .field = 0 };
25702691 \\ box.*.field = 1;
......@@ -2582,13 +2703,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25822703 "tmp.zig:8:13: error: attempt to dereference non-pointer type 'Box'",
25832704 });
25842705
2585 cases.add("usingnamespace with wrong type",
2706 ctx.objErrStage1("usingnamespace with wrong type",
25862707 \\usingnamespace void;
25872708 , &[_][]const u8{
25882709 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
25892710 });
25902711
2591 cases.add("ignored expression in while continuation",
2712 ctx.objErrStage1("ignored expression in while continuation",
25922713 \\export fn a() void {
25932714 \\ while (true) : (bad()) {}
25942715 \\}
......@@ -2609,31 +2730,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26092730 "tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if`",
26102731 });
26112732
2612 cases.add("empty while loop body",
2733 ctx.objErrStage1("empty while loop body",
26132734 \\export fn a() void {
26142735 \\ while(true);
26152736 \\}
26162737 , &[_][]const u8{
2617 "tmp.zig:2:16: error: expected loop body, found ';'",
2738 "tmp.zig:2:16: error: expected block or assignment, found ';'",
26182739 });
26192740
2620 cases.add("empty for loop body",
2741 ctx.objErrStage1("empty for loop body",
26212742 \\export fn a() void {
26222743 \\ for(undefined) |x|;
26232744 \\}
26242745 , &[_][]const u8{
2625 "tmp.zig:2:23: error: expected loop body, found ';'",
2746 "tmp.zig:2:23: error: expected block or assignment, found ';'",
26262747 });
26272748
2628 cases.add("empty if body",
2749 ctx.objErrStage1("empty if body",
26292750 \\export fn a() void {
26302751 \\ if(true);
26312752 \\}
26322753 , &[_][]const u8{
2633 "tmp.zig:2:13: error: expected if body, found ';'",
2754 "tmp.zig:2:13: error: expected block or assignment, found ';'",
26342755 });
26352756
2636 cases.add("import outside package path",
2757 ctx.objErrStage1("import outside package path",
26372758 \\comptime{
26382759 \\ _ = @import("../a.zig");
26392760 \\}
......@@ -2641,14 +2762,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26412762 "tmp.zig:2:9: error: import of file outside package path: '../a.zig'",
26422763 });
26432764
2644 cases.add("bogus compile var",
2765 ctx.objErrStage1("bogus compile var",
26452766 \\const x = @import("builtin").bogus;
26462767 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }
26472768 , &[_][]const u8{
26482769 "tmp.zig:1:29: error: container 'builtin' has no member called 'bogus'",
26492770 });
26502771
2651 cases.add("wrong panic signature, runtime function",
2772 ctx.objErrStage1("wrong panic signature, runtime function",
26522773 \\test "" {}
26532774 \\
26542775 \\pub fn panic() void {}
......@@ -2657,8 +2778,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26572778 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn() void'",
26582779 });
26592780
2660 cases.add("wrong panic signature, generic function",
2781 ctx.objErrStage1("wrong panic signature, generic function",
26612782 \\pub fn panic(comptime msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
2783 \\ _ = msg; _ = error_return_trace;
26622784 \\ while (true) {}
26632785 \\}
26642786 , &[_][]const u8{
......@@ -2666,14 +2788,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26662788 "note: only one of the functions is generic",
26672789 });
26682790
2669 cases.add("direct struct loop",
2791 ctx.objErrStage1("direct struct loop",
26702792 \\const A = struct { a : A, };
26712793 \\export fn entry() usize { return @sizeOf(A); }
26722794 , &[_][]const u8{
26732795 "tmp.zig:1:11: error: struct 'A' depends on itself",
26742796 });
26752797
2676 cases.add("indirect struct loop",
2798 ctx.objErrStage1("indirect struct loop",
26772799 \\const A = struct { b : B, };
26782800 \\const B = struct { c : C, };
26792801 \\const C = struct { a : A, };
......@@ -2682,7 +2804,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26822804 "tmp.zig:1:11: error: struct 'A' depends on itself",
26832805 });
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",
26862808 \\const Foo = struct {
26872809 \\ x: Foo,
26882810 \\};
......@@ -2697,23 +2819,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26972819 "tmp.zig:8:28: note: referenced here",
26982820 });
26992821
2700 cases.add("enum field value references enum",
2701 \\pub const Foo = extern enum {
2822 ctx.objErrStage1("enum field value references enum",
2823 \\pub const Foo = enum(c_int) {
27022824 \\ A = Foo.B,
27032825 \\ C = D,
27042826 \\};
27052827 \\export fn entry() void {
27062828 \\ var s: Foo = Foo.E;
2829 \\ _ = s;
27072830 \\}
27082831 , &[_][]const u8{
27092832 "tmp.zig:1:17: error: enum 'Foo' depends on itself",
27102833 });
27112834
2712 cases.add("top level decl dependency loop",
2835 ctx.objErrStage1("top level decl dependency loop",
27132836 \\const a : @TypeOf(b) = 0;
27142837 \\const b : @TypeOf(a) = 0;
27152838 \\export fn entry() void {
27162839 \\ const c = a + b;
2840 \\ _ = c;
27172841 \\}
27182842 , &[_][]const u8{
27192843 "tmp.zig:2:19: error: dependency loop detected",
......@@ -2721,7 +2845,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27212845 "tmp.zig:4:15: note: referenced here",
27222846 });
27232847
2724 cases.addTest("not an enum type",
2848 ctx.testErrStage1("not an enum type",
27252849 \\export fn entry() void {
27262850 \\ var self: Error = undefined;
27272851 \\ switch (self) {
......@@ -2739,18 +2863,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27392863 "tmp.zig:4:9: error: expected type '@typeInfo(Error).Union.tag_type.?', found 'type'",
27402864 });
27412865
2742 cases.addTest("binary OR operator on error sets",
2866 ctx.testErrStage1("binary OR operator on error sets",
27432867 \\pub const A = error.A;
27442868 \\pub const AB = A | error.B;
27452869 \\export fn entry() void {
27462870 \\ var x: AB = undefined;
2871 \\ _ = x;
27472872 \\}
27482873 , &[_][]const u8{
27492874 "tmp.zig:2:18: error: invalid operands to binary expression: 'error{A}' and 'error{B}'",
27502875 });
27512876
27522877 if (std.Target.current.os.tag == .linux) {
2753 cases.addTest("implicit dependency on libc",
2878 ctx.testErrStage1("implicit dependency on libc",
27542879 \\extern "c" fn exit(u8) void;
27552880 \\export fn entry() void {
27562881 \\ exit(0);
......@@ -2759,7 +2884,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27592884 "tmp.zig:3:5: error: dependency on libc must be explicitly specified in the build command",
27602885 });
27612886
2762 cases.addTest("libc headers note",
2887 ctx.testErrStage1("libc headers note",
27632888 \\const c = @cImport(@cInclude("stdio.h"));
27642889 \\export fn entry() void {
27652890 \\ _ = c.printf("hello, world!\n");
......@@ -2770,18 +2895,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27702895 });
27712896 }
27722897
2773 cases.addTest("comptime vector overflow shows the index",
2898 ctx.testErrStage1("comptime vector overflow shows the index",
27742899 \\comptime {
27752900 \\ var a: @import("std").meta.Vector(4, u8) = [_]u8{ 1, 2, 255, 4 };
27762901 \\ var b: @import("std").meta.Vector(4, u8) = [_]u8{ 5, 6, 1, 8 };
27772902 \\ var x = a + b;
2903 \\ _ = x;
27782904 \\}
27792905 , &[_][]const u8{
27802906 "tmp.zig:4:15: error: operation caused overflow",
27812907 "tmp.zig:4:15: note: when computing vector element at index 2",
27822908 });
27832909
2784 cases.addTest("packed struct with fields of not allowed types",
2910 ctx.testErrStage1("packed struct with fields of not allowed types",
27852911 \\const A = packed struct {
27862912 \\ x: anyerror,
27872913 \\};
......@@ -2805,24 +2931,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
28052931 \\};
28062932 \\export fn entry1() void {
28072933 \\ var a: A = undefined;
2934 \\ _ = a;
28082935 \\}
28092936 \\export fn entry2() void {
28102937 \\ var b: B = undefined;
2938 \\ _ = b;
28112939 \\}
28122940 \\export fn entry3() void {
28132941 \\ var r: C = undefined;
2942 \\ _ = r;
28142943 \\}
28152944 \\export fn entry4() void {
28162945 \\ var d: D = undefined;
2946 \\ _ = d;
28172947 \\}
28182948 \\export fn entry5() void {
28192949 \\ var e: E = undefined;
2950 \\ _ = e;
28202951 \\}
28212952 \\export fn entry6() void {
28222953 \\ var f: F = undefined;
2954 \\ _ = f;
28232955 \\}
28242956 \\export fn entry7() void {
28252957 \\ var g: G = undefined;
2958 \\ _ = g;
28262959 \\}
28272960 \\const S = struct {
28282961 \\ x: i32,
......@@ -2843,42 +2976,40 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
28432976 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",
28442977 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",
28452978 "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",
28472980 });
28482981
2849 cases.addCase(x: {
2850 var tc = cases.create("deduplicate undeclared identifier",
2851 \\export fn a() void {
2852 \\ x += 1;
2853 \\}
2854 \\export fn b() void {
2855 \\ x += 1;
2856 \\}
2857 , &[_][]const u8{
2858 "tmp.zig:2:5: error: use of undeclared identifier 'x'",
2859 });
2860 tc.expect_exact = true;
2861 break :x tc;
2982 ctx.objErrStage1("deduplicate undeclared identifier",
2983 \\export fn a() void {
2984 \\ x += 1;
2985 \\}
2986 \\export fn b() void {
2987 \\ x += 1;
2988 \\}
2989 , &[_][]const u8{
2990 "tmp.zig:2:5: error: use of undeclared identifier 'x'",
28622991 });
28632992
2864 cases.add("export generic function",
2993 ctx.objErrStage1("export generic function",
28652994 \\export fn foo(num: anytype) i32 {
2995 \\ _ = num;
28662996 \\ return 0;
28672997 \\}
28682998 , &[_][]const u8{
28692999 "tmp.zig:1:15: error: parameter of type 'anytype' not allowed in function with calling convention 'C'",
28703000 });
28713001
2872 cases.add("C pointer to c_void",
3002 ctx.objErrStage1("C pointer to c_void",
28733003 \\export fn a() void {
28743004 \\ var x: *c_void = undefined;
28753005 \\ var y: [*c]c_void = x;
3006 \\ _ = y;
28763007 \\}
28773008 , &[_][]const u8{
28783009 "tmp.zig:3:16: error: C pointers cannot point to opaque types",
28793010 });
28803011
2881 cases.add("directly embedding opaque type in struct and union",
3012 ctx.objErrStage1("directly embedding opaque type in struct and union",
28823013 \\const O = opaque {};
28833014 \\const Foo = struct {
28843015 \\ o: O,
......@@ -2889,74 +3020,85 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
28893020 \\};
28903021 \\export fn a() void {
28913022 \\ var foo: Foo = undefined;
3023 \\ _ = foo;
28923024 \\}
28933025 \\export fn b() void {
28943026 \\ var bar: Bar = undefined;
3027 \\ _ = bar;
28953028 \\}
28963029 \\export fn c() void {
28973030 \\ var baz: *opaque {} = undefined;
28983031 \\ const qux = .{baz.*};
3032 \\ _ = qux;
28993033 \\}
29003034 , &[_][]const u8{
29013035 "tmp.zig:3:5: error: opaque types have unknown size and therefore cannot be directly embedded in structs",
29023036 "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",
29043038 });
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",
29073041 \\export fn a() void {
29083042 \\ var x: [*c]u8 = undefined;
29093043 \\ var y: *align(4) u8 = x;
3044 \\ _ = y;
29103045 \\}
29113046 \\export fn b() void {
29123047 \\ var x: [*c]const u8 = undefined;
29133048 \\ var y: *u8 = x;
3049 \\ _ = y;
29143050 \\}
29153051 \\export fn c() void {
29163052 \\ var x: [*c]u8 = undefined;
29173053 \\ var y: *u32 = x;
3054 \\ _ = y;
29183055 \\}
29193056 \\export fn d() void {
29203057 \\ var y: *align(1) u32 = undefined;
29213058 \\ var x: [*c]u32 = y;
3059 \\ _ = x;
29223060 \\}
29233061 \\export fn e() void {
29243062 \\ var y: *const u8 = undefined;
29253063 \\ var x: [*c]u8 = y;
3064 \\ _ = x;
29263065 \\}
29273066 \\export fn f() void {
29283067 \\ var y: *u8 = undefined;
29293068 \\ var x: [*c]u32 = y;
3069 \\ _ = x;
29303070 \\}
29313071 , &[_][]const u8{
29323072 "tmp.zig:3:27: error: cast increases pointer alignment",
2933 "tmp.zig:7:18: error: cast discards const qualifier",
2934 "tmp.zig:11: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'",
2936 "tmp.zig:15:22: error: cast increases pointer alignment",
2937 "tmp.zig:19:21: error: cast discards const qualifier",
2938 "tmp.zig:23:22: error: expected type '[*c]u32', found '*u8'",
3073 "tmp.zig:8:18: error: cast discards const qualifier",
3074 "tmp.zig:13:19: error: expected type '*u32', found '[*c]u8'",
3075 "tmp.zig:13:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'",
3076 "tmp.zig:18:22: error: cast increases pointer alignment",
3077 "tmp.zig:23:21: error: cast discards const qualifier",
3078 "tmp.zig:28:22: error: expected type '[*c]u32', found '*u8'",
29393079 });
29403080
2941 cases.add("implicit casting null c pointer to zig pointer",
3081 ctx.objErrStage1("implicit casting null c pointer to zig pointer",
29423082 \\comptime {
29433083 \\ var c_ptr: [*c]u8 = 0;
29443084 \\ var zig_ptr: *u8 = c_ptr;
3085 \\ _ = zig_ptr;
29453086 \\}
29463087 , &[_][]const u8{
29473088 "tmp.zig:3:24: error: null pointer casted to type '*u8'",
29483089 });
29493090
2950 cases.add("implicit casting undefined c pointer to zig pointer",
3091 ctx.objErrStage1("implicit casting undefined c pointer to zig pointer",
29513092 \\comptime {
29523093 \\ var c_ptr: [*c]u8 = undefined;
29533094 \\ var zig_ptr: *u8 = c_ptr;
3095 \\ _ = zig_ptr;
29543096 \\}
29553097 , &[_][]const u8{
29563098 "tmp.zig:3:24: error: use of undefined value here causes undefined behavior",
29573099 });
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",
29603102 \\export fn entry() void {
29613103 \\ var slice: []const u8 = "aoeu";
29623104 \\ const opt_many_ptr: [*]const u8 = slice.ptr;
......@@ -2970,6 +3112,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
29703112 \\ var opt_many_ptr: [*]u8 = slice.ptr;
29713113 \\ var ptr_opt_many_ptr = &opt_many_ptr;
29723114 \\ var c_ptr: [*c][*c]const u8 = ptr_opt_many_ptr;
3115 \\ _ = c_ptr;
29733116 \\}
29743117 , &[_][]const u8{
29753118 "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 {
29803123 "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'",
29813124 });
29823125
2983 cases.add("implicit casting too big integers to C pointers",
3126 ctx.objErrStage1("implicit casting too big integers to C pointers",
29843127 \\export fn a() void {
29853128 \\ var ptr: [*c]u8 = (1 << 64) + 1;
3129 \\ _ = ptr;
29863130 \\}
29873131 \\export fn b() void {
29883132 \\ var x: u65 = 0x1234;
29893133 \\ var ptr: [*c]u8 = x;
3134 \\ _ = ptr;
29903135 \\}
29913136 , &[_][]const u8{
29923137 "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'",
29943139 });
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",
29973142 \\const Foo = struct {};
29983143 \\export fn a() void {
29993144 \\ const T = [*c]Foo;
30003145 \\ var t: T = undefined;
3146 \\ _ = t;
30013147 \\}
30023148 , &[_][]const u8{
30033149 "tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
30043150 });
30053151
3006 cases.addCase(x: {
3007 var tc = cases.create("compile log statement warning deduplication in generic fn",
3008 \\export fn entry() void {
3009 \\ inner(1);
3010 \\ inner(2);
3011 \\}
3012 \\fn inner(comptime n: usize) void {
3013 \\ comptime var i = 0;
3014 \\ inline while (i < n) : (i += 1) { @compileLog("!@#$"); }
3015 \\}
3016 , &[_][]const u8{
3017 "tmp.zig:7:39: error: found compile log statement",
3018 });
3019 tc.expect_exact = true;
3020 break :x tc;
3152 ctx.objErrStage1("compile log statement warning deduplication in generic fn",
3153 \\export fn entry() void {
3154 \\ inner(1);
3155 \\ inner(2);
3156 \\}
3157 \\fn inner(comptime n: usize) void {
3158 \\ comptime var i = 0;
3159 \\ inline while (i < n) : (i += 1) { @compileLog("!@#$"); }
3160 \\}
3161 , &[_][]const u8{
3162 "tmp.zig:7:39: error: found compile log statement",
30213163 });
30223164
3023 cases.add("assign to invalid dereference",
3165 ctx.objErrStage1("assign to invalid dereference",
30243166 \\export fn entry() void {
30253167 \\ 'a'.* = 1;
30263168 \\}
......@@ -3028,54 +3170,58 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30283170 "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'",
30293171 });
30303172
3031 cases.add("take slice of invalid dereference",
3173 ctx.objErrStage1("take slice of invalid dereference",
30323174 \\export fn entry() void {
30333175 \\ const x = 'a'.*[0..];
3176 \\ _ = x;
30343177 \\}
30353178 , &[_][]const u8{
30363179 "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'",
30373180 });
30383181
3039 cases.add("@truncate undefined value",
3182 ctx.objErrStage1("@truncate undefined value",
30403183 \\export fn entry() void {
30413184 \\ var z = @truncate(u8, @as(u16, undefined));
3185 \\ _ = z;
30423186 \\}
30433187 , &[_][]const u8{
30443188 "tmp.zig:2:27: error: use of undefined value here causes undefined behavior",
30453189 });
30463190
3047 cases.addTest("return invalid type from test",
3191 ctx.testErrStage1("return invalid type from test",
30483192 \\test "example" { return 1; }
30493193 , &[_][]const u8{
30503194 "tmp.zig:1:25: error: expected type 'void', found 'comptime_int'",
30513195 });
30523196
3053 cases.add("threadlocal qualifier on const",
3197 ctx.objErrStage1("threadlocal qualifier on const",
30543198 \\threadlocal const x: i32 = 1234;
30553199 \\export fn entry() i32 {
30563200 \\ return x;
30573201 \\}
30583202 , &[_][]const u8{
3059 "tmp.zig:1:13: error: threadlocal variable cannot be constant",
3203 "tmp.zig:1:1: error: threadlocal variable cannot be constant",
30603204 });
30613205
3062 cases.add("@bitCast same size but bit count mismatch",
3206 ctx.objErrStage1("@bitCast same size but bit count mismatch",
30633207 \\export fn entry(byte: u8) void {
30643208 \\ var oops = @bitCast(u7, byte);
3209 \\ _ = oops;
30653210 \\}
30663211 , &[_][]const u8{
30673212 "tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
30683213 });
30693214
3070 cases.add("@bitCast with different sizes inside an expression",
3215 ctx.objErrStage1("@bitCast with different sizes inside an expression",
30713216 \\export fn entry() void {
30723217 \\ var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf);
3218 \\ _ = foo;
30733219 \\}
30743220 , &[_][]const u8{
30753221 "tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4",
30763222 });
30773223
3078 cases.add("attempted `&&`",
3224 ctx.objErrStage1("attempted `&&`",
30793225 \\export fn entry(a: bool, b: bool) i32 {
30803226 \\ if (a && b) {
30813227 \\ return 1234;
......@@ -3083,10 +3229,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30833229 \\ return 5678;
30843230 \\}
30853231 , &[_][]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",
30873233 });
30883234
3089 cases.add("attempted `||` on boolean values",
3235 ctx.objErrStage1("attempted `||` on boolean values",
30903236 \\export fn entry(a: bool, b: bool) i32 {
30913237 \\ if (a || b) {
30923238 \\ return 1234;
......@@ -3098,7 +3244,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30983244 "tmp.zig:2:11: note: `||` merges error sets; `or` performs boolean OR",
30993245 });
31003246
3101 cases.add("compile log a pointer to an opaque value",
3247 ctx.objErrStage1("compile log a pointer to an opaque value",
31023248 \\export fn entry() void {
31033249 \\ @compileLog(@ptrCast(*const c_void, &entry));
31043250 \\}
......@@ -3106,13 +3252,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
31063252 "tmp.zig:2:5: error: found compile log statement",
31073253 });
31083254
3109 cases.add("duplicate boolean switch value",
3255 ctx.objErrStage1("duplicate boolean switch value",
31103256 \\comptime {
31113257 \\ const x = switch (true) {
31123258 \\ true => false,
31133259 \\ false => true,
31143260 \\ true => false,
31153261 \\ };
3262 \\ _ = x;
31163263 \\}
31173264 \\comptime {
31183265 \\ const x = switch (true) {
......@@ -3120,42 +3267,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
31203267 \\ true => false,
31213268 \\ false => true,
31223269 \\ };
3270 \\ _ = x;
31233271 \\}
31243272 , &[_][]const u8{
31253273 "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",
31273275 });
31283276
3129 cases.add("missing boolean switch value",
3277 ctx.objErrStage1("missing boolean switch value",
31303278 \\comptime {
31313279 \\ const x = switch (true) {
31323280 \\ true => false,
31333281 \\ };
3282 \\ _ = x;
31343283 \\}
31353284 \\comptime {
31363285 \\ const x = switch (true) {
31373286 \\ false => true,
31383287 \\ };
3288 \\ _ = x;
31393289 \\}
31403290 , &[_][]const u8{
31413291 "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",
31433293 });
31443294
3145 cases.add("reading past end of pointer casted array",
3295 ctx.objErrStage1("reading past end of pointer casted array",
31463296 \\comptime {
31473297 \\ const array: [4]u8 = "aoeu".*;
31483298 \\ const sub_array = array[1..];
31493299 \\ const int_ptr = @ptrCast(*const u24, sub_array);
31503300 \\ const deref = int_ptr.*;
3301 \\ _ = deref;
31513302 \\}
31523303 , &[_][]const u8{
31533304 "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes",
31543305 });
31553306
3156 cases.add("error note for function parameter incompatibility",
3157 \\fn do_the_thing(func: fn (arg: i32) void) void {}
3158 \\fn bar(arg: bool) void {}
3307 ctx.objErrStage1("error note for function parameter incompatibility",
3308 \\fn do_the_thing(func: fn (arg: i32) void) void { _ = func; }
3309 \\fn bar(arg: bool) void { _ = arg; }
31593310 \\export fn entry() void {
31603311 \\ do_the_thing(bar);
31613312 \\}
......@@ -3163,56 +3314,63 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
31633314 "tmp.zig:4:18: error: expected type 'fn(i32) void', found 'fn(bool) void",
31643315 "tmp.zig:4:18: note: parameter 0: 'bool' cannot cast into 'i32'",
31653316 });
3166 cases.add("cast negative value to unsigned integer",
3317 ctx.objErrStage1("cast negative value to unsigned integer",
31673318 \\comptime {
31683319 \\ const value: i32 = -1;
31693320 \\ const unsigned = @intCast(u32, value);
3321 \\ _ = unsigned;
31703322 \\}
31713323 \\export fn entry1() void {
31723324 \\ const value: i32 = -1;
31733325 \\ const unsigned: u32 = value;
3326 \\ _ = unsigned;
31743327 \\}
31753328 , &[_][]const u8{
31763329 "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'",
31783331 });
31793332
3180 cases.add("integer cast truncates bits",
3333 ctx.objErrStage1("integer cast truncates bits",
31813334 \\export fn entry1() void {
31823335 \\ const spartan_count: u16 = 300;
31833336 \\ const byte = @intCast(u8, spartan_count);
3337 \\ _ = byte;
31843338 \\}
31853339 \\export fn entry2() void {
31863340 \\ const spartan_count: u16 = 300;
31873341 \\ const byte: u8 = spartan_count;
3342 \\ _ = byte;
31883343 \\}
31893344 \\export fn entry3() void {
31903345 \\ var spartan_count: u16 = 300;
31913346 \\ var byte: u8 = spartan_count;
3347 \\ _ = byte;
31923348 \\}
31933349 \\export fn entry4() void {
31943350 \\ var signed: i8 = -1;
31953351 \\ var unsigned: u64 = signed;
3352 \\ _ = unsigned;
31963353 \\}
31973354 , &[_][]const u8{
31983355 "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'",
3200 "tmp.zig:11: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",
3202 "tmp.zig:15: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",
3356 "tmp.zig:8:22: error: integer value 300 cannot be coerced to type 'u8'",
3357 "tmp.zig:13:20: error: expected type 'u8', found 'u16'",
3358 "tmp.zig:13:20: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values",
3359 "tmp.zig:18:25: error: expected type 'u64', found 'i8'",
3360 "tmp.zig:18:25: note: unsigned 64-bit int cannot represent all possible signed 8-bit values",
32043361 });
32053362
3206 cases.add("comptime implicit cast f64 to f32",
3363 ctx.objErrStage1("comptime implicit cast f64 to f32",
32073364 \\export fn entry() void {
32083365 \\ const x: f64 = 16777217;
32093366 \\ const y: f32 = x;
3367 \\ _ = y;
32103368 \\}
32113369 , &[_][]const u8{
32123370 "tmp.zig:3:20: error: cast of value 16777217.000000 to type 'f32' loses information",
32133371 });
32143372
3215 cases.add("implicit cast from f64 to f32",
3373 ctx.objErrStage1("implicit cast from f64 to f32",
32163374 \\var x: f64 = 1.0;
32173375 \\var y: f32 = x;
32183376 \\
......@@ -3221,41 +3379,46 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
32213379 "tmp.zig:2:14: error: expected type 'f32', found 'f64'",
32223380 });
32233381
3224 cases.add("exceeded maximum bit width of integer",
3382 ctx.objErrStage1("exceeded maximum bit width of integer",
32253383 \\export fn entry1() void {
32263384 \\ const T = u65536;
3385 \\ _ = T;
32273386 \\}
32283387 \\export fn entry2() void {
32293388 \\ var x: i65536 = 1;
3389 \\ _ = x;
32303390 \\}
32313391 , &[_][]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",
32333394 });
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",
32363397 \\const Car = struct {
32373398 \\ foo: *SymbolThatDoesNotExist,
32383399 \\ pub fn init() !Car {}
32393400 \\};
32403401 \\export fn entry() void {
32413402 \\ const car = Car.init();
3403 \\ _ = car;
32423404 \\}
32433405 , &[_][]const u8{
32443406 "tmp.zig:2:11: error: use of undeclared identifier 'SymbolThatDoesNotExist'",
32453407 });
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",
32483410 \\export fn entry() void {
32493411 \\ var a: u32 = 1;
32503412 \\ var ptr: *align(@alignOf(u32)) c_void = &a;
32513413 \\ var b: *u32 = @ptrCast(*u32, ptr);
32523414 \\ var ptr2: *c_void = &b;
3415 \\ _ = ptr2;
32533416 \\}
32543417 , &[_][]const u8{
32553418 "tmp.zig:5:26: error: expected type '*c_void', found '**u32'",
32563419 });
32573420
3258 cases.add("runtime index into comptime type slice",
3421 ctx.objErrStage1("runtime index into comptime type slice",
32593422 \\const Struct = struct {
32603423 \\ a: u32,
32613424 \\};
......@@ -3265,12 +3428,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
32653428 \\export fn entry() void {
32663429 \\ const index = getIndex();
32673430 \\ const field = @typeInfo(Struct).Struct.fields[index];
3431 \\ _ = field;
32683432 \\}
32693433 , &[_][]const u8{
32703434 "tmp.zig:9:51: error: values of type 'std.builtin.StructField' must be comptime known, but index value is runtime known",
32713435 });
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",
32743438 \\fn Foo(comptime T: type) type {
32753439 \\ @compileLog(@typeName(T));
32763440 \\ return T;
......@@ -3283,25 +3447,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
32833447 "tmp.zig:2:5: error: found compile log statement",
32843448 });
32853449
3286 cases.add("comptime slice of an undefined slice",
3450 ctx.objErrStage1("comptime slice of an undefined slice",
32873451 \\comptime {
32883452 \\ var a: []u8 = undefined;
32893453 \\ var b = a[0..10];
3454 \\ _ = b;
32903455 \\}
32913456 , &[_][]const u8{
32923457 "tmp.zig:3:14: error: slice of undefined",
32933458 });
32943459
3295 cases.add("implicit cast const array to mutable slice",
3460 ctx.objErrStage1("implicit cast const array to mutable slice",
32963461 \\export fn entry() void {
32973462 \\ const buffer: [1]u8 = [_]u8{8};
32983463 \\ const sliceA: []u8 = &buffer;
3464 \\ _ = sliceA;
32993465 \\}
33003466 , &[_][]const u8{
33013467 "tmp.zig:3:27: error: expected type '[]u8', found '*const [1]u8'",
33023468 });
33033469
3304 cases.add("deref slice and get len field",
3470 ctx.objErrStage1("deref slice and get len field",
33053471 \\export fn entry() void {
33063472 \\ var a: []u8 = undefined;
33073473 \\ _ = a.*.len;
......@@ -3310,7 +3476,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33103476 "tmp.zig:3:10: error: attempt to dereference non-pointer type '[]u8'",
33113477 });
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",
33143480 \\export fn entry() bool {
33153481 \\ var x: u0 = 0;
33163482 \\ const p = @ptrCast(?*u0, &x);
......@@ -3322,7 +3488,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33223488 "tmp.zig:3:24: note: '?*u0' has in-memory bits",
33233489 });
33243490
3325 cases.add("comparing a non-optional pointer against null",
3491 ctx.objErrStage1("comparing a non-optional pointer against null",
33263492 \\export fn entry() void {
33273493 \\ var x: i32 = 1;
33283494 \\ _ = &x == null;
......@@ -3331,21 +3497,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33313497 "tmp.zig:3:12: error: comparison of '*i32' with null",
33323498 });
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",
33353501 \\export fn foo() void {
33363502 \\ const Errors = u8 || u16;
3503 \\ _ = Errors;
33373504 \\}
33383505 \\export fn bar() void {
33393506 \\ const Errors = error{} || u16;
3507 \\ _ = Errors;
33403508 \\}
33413509 , &[_][]const u8{
33423510 "tmp.zig:2:20: error: expected error set type, found type 'u8'",
33433511 "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'",
3345 "tmp.zig:5:28: note: `||` merges error sets; `or` performs boolean OR",
3512 "tmp.zig:6:31: error: expected error set type, found type 'u16'",
3513 "tmp.zig:6:28: note: `||` merges error sets; `or` performs boolean OR",
33463514 });
33473515
3348 cases.add("variable initialization compile error then referenced",
3516 ctx.objErrStage1("variable initialization compile error then referenced",
33493517 \\fn Undeclared() type {
33503518 \\ return T;
33513519 \\}
......@@ -3357,12 +3525,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33573525 \\}
33583526 \\export fn entry() void {
33593527 \\ const S = Gen();
3528 \\ _ = S;
33603529 \\}
33613530 , &[_][]const u8{
33623531 "tmp.zig:2:12: error: use of undeclared identifier 'T'",
33633532 });
33643533
3365 cases.add("refer to the type of a generic function",
3534 ctx.objErrStage1("refer to the type of a generic function",
33663535 \\export fn entry() void {
33673536 \\ const Func = fn (type) void;
33683537 \\ const f: Func = undefined;
......@@ -3372,7 +3541,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33723541 "tmp.zig:4:5: error: use of undefined value here causes undefined behavior",
33733542 });
33743543
3375 cases.add("accessing runtime parameter from outer function",
3544 ctx.objErrStage1("accessing runtime parameter from outer function",
33763545 \\fn outer(y: u32) fn (u32) u32 {
33773546 \\ const st = struct {
33783547 \\ fn get(z: u32) u32 {
......@@ -3384,6 +3553,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33843553 \\export fn entry() void {
33853554 \\ var func = outer(10);
33863555 \\ var x = func(3);
3556 \\ _ = x;
33873557 \\}
33883558 , &[_][]const u8{
33893559 "tmp.zig:4:24: error: 'y' not accessible from inner function",
......@@ -3391,69 +3561,74 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
33913561 "tmp.zig:1:10: note: declared here",
33923562 });
33933563
3394 cases.add("non int passed to @intToFloat",
3564 ctx.objErrStage1("non int passed to @intToFloat",
33953565 \\export fn entry() void {
33963566 \\ const x = @intToFloat(f32, 1.1);
3567 \\ _ = x;
33973568 \\}
33983569 , &[_][]const u8{
33993570 "tmp.zig:2:32: error: expected int type, found 'comptime_float'",
34003571 });
34013572
3402 cases.add("non float passed to @floatToInt",
3573 ctx.objErrStage1("non float passed to @floatToInt",
34033574 \\export fn entry() void {
34043575 \\ const x = @floatToInt(i32, @as(i32, 54));
3576 \\ _ = x;
34053577 \\}
34063578 , &[_][]const u8{
34073579 "tmp.zig:2:32: error: expected float type, found 'i32'",
34083580 });
34093581
3410 cases.add("out of range comptime_int passed to @floatToInt",
3582 ctx.objErrStage1("out of range comptime_int passed to @floatToInt",
34113583 \\export fn entry() void {
34123584 \\ const x = @floatToInt(i8, 200);
3585 \\ _ = x;
34133586 \\}
34143587 , &[_][]const u8{
34153588 "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'",
34163589 });
34173590
3418 cases.add("load too many bytes from comptime reinterpreted pointer",
3591 ctx.objErrStage1("load too many bytes from comptime reinterpreted pointer",
34193592 \\export fn entry() void {
34203593 \\ const float: f32 = 5.99999999999994648725e-01;
34213594 \\ const float_ptr = &float;
34223595 \\ const int_ptr = @ptrCast(*const i64, float_ptr);
34233596 \\ const int_val = int_ptr.*;
3597 \\ _ = int_val;
34243598 \\}
34253599 , &[_][]const u8{
34263600 "tmp.zig:5:28: error: attempt to read 8 bytes from pointer to f32 which is 4 bytes",
34273601 });
34283602
3429 cases.add("invalid type used in array type",
3603 ctx.objErrStage1("invalid type used in array type",
34303604 \\const Item = struct {
34313605 \\ field: SomeNonexistentType,
34323606 \\};
34333607 \\var items: [100]Item = undefined;
34343608 \\export fn entry() void {
34353609 \\ const a = items[0];
3610 \\ _ = a;
34363611 \\}
34373612 , &[_][]const u8{
34383613 "tmp.zig:2:12: error: use of undeclared identifier 'SomeNonexistentType'",
34393614 });
34403615
3441 cases.add("comptime continue inside runtime catch",
3442 \\export fn entry(c: bool) void {
3616 ctx.objErrStage1("comptime continue inside runtime catch",
3617 \\export fn entry() void {
34433618 \\ const ints = [_]u8{ 1, 2 };
34443619 \\ inline for (ints) |_| {
3445 \\ bad() catch |_| continue;
3620 \\ bad() catch continue;
34463621 \\ }
34473622 \\}
34483623 \\fn bad() !void {
34493624 \\ return error.Bad;
34503625 \\}
34513626 , &[_][]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",
34533628 "tmp.zig:4:15: note: runtime block created here",
34543629 });
34553630
3456 cases.add("comptime continue inside runtime switch",
3631 ctx.objErrStage1("comptime continue inside runtime switch",
34573632 \\export fn entry() void {
34583633 \\ var p: i32 = undefined;
34593634 \\ comptime var q = true;
......@@ -3470,7 +3645,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
34703645 "tmp.zig:5:9: note: runtime block created here",
34713646 });
34723647
3473 cases.add("comptime continue inside runtime while error",
3648 ctx.objErrStage1("comptime continue inside runtime while error",
34743649 \\export fn entry() void {
34753650 \\ var p: anyerror!usize = undefined;
34763651 \\ comptime var q = true;
......@@ -3486,7 +3661,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
34863661 "tmp.zig:5:9: note: runtime block created here",
34873662 });
34883663
3489 cases.add("comptime continue inside runtime while optional",
3664 ctx.objErrStage1("comptime continue inside runtime while optional",
34903665 \\export fn entry() void {
34913666 \\ var p: ?usize = undefined;
34923667 \\ comptime var q = true;
......@@ -3500,7 +3675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35003675 "tmp.zig:5:9: note: runtime block created here",
35013676 });
35023677
3503 cases.add("comptime continue inside runtime while bool",
3678 ctx.objErrStage1("comptime continue inside runtime while bool",
35043679 \\export fn entry() void {
35053680 \\ var p: usize = undefined;
35063681 \\ comptime var q = true;
......@@ -3514,7 +3689,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35143689 "tmp.zig:5:9: note: runtime block created here",
35153690 });
35163691
3517 cases.add("comptime continue inside runtime if error",
3692 ctx.objErrStage1("comptime continue inside runtime if error",
35183693 \\export fn entry() void {
35193694 \\ var p: anyerror!i32 = undefined;
35203695 \\ comptime var q = true;
......@@ -3528,7 +3703,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35283703 "tmp.zig:5:9: note: runtime block created here",
35293704 });
35303705
3531 cases.add("comptime continue inside runtime if optional",
3706 ctx.objErrStage1("comptime continue inside runtime if optional",
35323707 \\export fn entry() void {
35333708 \\ var p: ?i32 = undefined;
35343709 \\ comptime var q = true;
......@@ -3542,7 +3717,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35423717 "tmp.zig:5:9: note: runtime block created here",
35433718 });
35443719
3545 cases.add("comptime continue inside runtime if bool",
3720 ctx.objErrStage1("comptime continue inside runtime if bool",
35463721 \\export fn entry() void {
35473722 \\ var p: usize = undefined;
35483723 \\ comptime var q = true;
......@@ -3556,22 +3731,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35563731 "tmp.zig:5:9: note: runtime block created here",
35573732 });
35583733
3559 cases.add("switch with invalid expression parameter",
3734 ctx.objErrStage1("switch with invalid expression parameter",
35603735 \\export fn entry() void {
35613736 \\ Test(i32);
35623737 \\}
35633738 \\fn Test(comptime T: type) void {
35643739 \\ const x = switch (T) {
3565 \\ []u8 => |x| 123,
3566 \\ i32 => |x| 456,
3740 \\ []u8 => |x| x,
3741 \\ i32 => |x| x,
35673742 \\ else => unreachable,
35683743 \\ };
3744 \\ _ = x;
35693745 \\}
35703746 , &[_][]const u8{
35713747 "tmp.zig:7:17: error: switch on type 'type' provides no expression parameter",
35723748 });
35733749
3574 cases.add("function prototype with no body",
3750 ctx.objErrStage1("function prototype with no body",
35753751 \\fn foo() void;
35763752 \\export fn entry() void {
35773753 \\ foo();
......@@ -3580,7 +3756,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35803756 "tmp.zig:1:1: error: non-extern function has no body",
35813757 });
35823758
3583 cases.add("@frame() called outside of function definition",
3759 ctx.objErrStage1("@frame() called outside of function definition",
35843760 \\var handle_undef: anyframe = undefined;
35853761 \\var handle_dummy: anyframe = @frame();
35863762 \\export fn entry() bool {
......@@ -3590,16 +3766,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35903766 "tmp.zig:2:30: error: @frame() called outside of function definition",
35913767 });
35923768
3593 cases.add("`_` is not a declarable symbol",
3769 ctx.objErrStage1("`_` is not a declarable symbol",
35943770 \\export fn f1() usize {
35953771 \\ var _: usize = 2;
35963772 \\ return _;
35973773 \\}
35983774 , &[_][]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",
36003776 });
36013777
3602 cases.add("`_` should not be usable inside for",
3778 ctx.objErrStage1("`_` should not be usable inside for",
36033779 \\export fn returns() void {
36043780 \\ for ([_]void{}) |_, i| {
36053781 \\ for ([_]void{}) |_, j| {
......@@ -3608,10 +3784,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
36083784 \\ }
36093785 \\}
36103786 , &[_][]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",
36123788 });
36133789
3614 cases.add("`_` should not be usable inside while",
3790 ctx.objErrStage1("`_` should not be usable inside while",
36153791 \\export fn returns() void {
36163792 \\ while (optionalReturn()) |_| {
36173793 \\ while (optionalReturn()) |_| {
......@@ -3623,10 +3799,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
36233799 \\ return 1;
36243800 \\}
36253801 , &[_][]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",
36273803 });
36283804
3629 cases.add("`_` should not be usable inside while else",
3805 ctx.objErrStage1("`_` should not be usable inside while else",
36303806 \\export fn returns() void {
36313807 \\ while (optionalReturnError()) |_| {
36323808 \\ while (optionalReturnError()) |_| {
......@@ -3640,10 +3816,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
36403816 \\ return error.optionalReturnError;
36413817 \\}
36423818 , &[_][]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",
36443820 });
36453821
3646 cases.add("while loop body expression ignored",
3822 ctx.objErrStage1("while loop body expression ignored",
36473823 \\fn returns() usize {
36483824 \\ return 2;
36493825 \\}
......@@ -3664,7 +3840,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
36643840 "tmp.zig:13:26: error: expression value is ignored",
36653841 });
36663842
3667 cases.add("missing parameter name of generic function",
3843 ctx.objErrStage1("missing parameter name of generic function",
36683844 \\fn dump(anytype) void {}
36693845 \\export fn entry() void {
36703846 \\ var a: u8 = 9;
......@@ -3674,20 +3850,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
36743850 "tmp.zig:1:9: error: missing parameter name",
36753851 });
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",
36783854 \\const Foo = struct {
36793855 \\ name: []const u8,
36803856 \\ T: type,
36813857 \\};
36823858 \\export fn entry() void {
36833859 \\ const xx: [2]Foo = undefined;
3684 \\ for (xx) |f| {}
3860 \\ for (xx) |f| { _ = f;}
36853861 \\}
36863862 , &[_][]const u8{
36873863 "tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known",
36883864 });
36893865
3690 cases.add("generic fn as parameter without comptime keyword",
3866 ctx.objErrStage1("generic fn as parameter without comptime keyword",
36913867 \\fn f(_: fn (anytype) void) void {}
36923868 \\fn g(_: anytype) void {}
36933869 \\export fn entry() void {
......@@ -3697,7 +3873,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
36973873 "tmp.zig:1:9: error: parameter of type 'fn(anytype) anytype' must be declared comptime",
36983874 });
36993875
3700 cases.add("optional pointer to void in extern struct",
3876 ctx.objErrStage1("optional pointer to void in extern struct",
37013877 \\const Foo = extern struct {
37023878 \\ x: ?*const void,
37033879 \\};
......@@ -3705,12 +3881,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37053881 \\ foo: Foo,
37063882 \\ y: i32,
37073883 \\};
3708 \\export fn entry(bar: *Bar) void {}
3884 \\export fn entry(bar: *Bar) void {_ = bar;}
37093885 , &[_][]const u8{
37103886 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void'",
37113887 });
37123888
3713 cases.add("use of comptime-known undefined function value",
3889 ctx.objErrStage1("use of comptime-known undefined function value",
37143890 \\const Cmd = struct {
37153891 \\ exec: fn () void,
37163892 \\};
......@@ -3722,7 +3898,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37223898 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior",
37233899 });
37243900
3725 cases.add("use of comptime-known undefined function value",
3901 ctx.objErrStage1("use of comptime-known undefined function value",
37263902 \\const Cmd = struct {
37273903 \\ exec: fn () void,
37283904 \\};
......@@ -3734,16 +3910,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37343910 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior",
37353911 });
37363912
3737 cases.add("bad @alignCast at comptime",
3913 ctx.objErrStage1("bad @alignCast at comptime",
37383914 \\comptime {
37393915 \\ const ptr = @intToPtr(*align(1) i32, 0x1);
37403916 \\ const aligned = @alignCast(4, ptr);
3917 \\ _ = aligned;
37413918 \\}
37423919 , &[_][]const u8{
37433920 "tmp.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes",
37443921 });
37453922
3746 cases.add("@ptrToInt on *void",
3923 ctx.objErrStage1("@ptrToInt on *void",
37473924 \\export fn entry() bool {
37483925 \\ return @ptrToInt(&{}) == @ptrToInt(&{});
37493926 \\}
......@@ -3751,7 +3928,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37513928 "tmp.zig:2:23: error: pointer to size 0 type has no address",
37523929 });
37533930
3754 cases.add("@popCount - non-integer",
3931 ctx.objErrStage1("@popCount - non-integer",
37553932 \\export fn entry(x: f32) u32 {
37563933 \\ return @popCount(f32, x);
37573934 \\}
......@@ -3759,8 +3936,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37593936 "tmp.zig:2:22: error: expected integer type, found 'f32'",
37603937 });
37613938
3762 cases.addCase(x: {
3763 const tc = cases.create("wrong same named struct",
3939 {
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(
37643956 \\const a = @import("a.zig");
37653957 \\const b = @import("b.zig");
37663958 \\
......@@ -3769,30 +3961,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37693961 \\ bar(&a1);
37703962 \\}
37713963 \\
3772 \\fn bar(x: *b.Foo) void {}
3964 \\fn bar(x: *b.Foo) void {_ = x;}
37733965 , &[_][]const u8{
37743966 "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'",
37753967 "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
37763968 "a.zig:1:17: note: a.Foo declared here",
37773969 "b.zig:1:17: note: b.Foo declared here",
37783970 });
3971 }
37793972
3780 tc.addSourceFile("a.zig",
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",
3973 ctx.objErrStage1("@floatToInt comptime safety",
37963974 \\comptime {
37973975 \\ _ = @floatToInt(i8, @as(f32, -129.1));
37983976 \\}
......@@ -3808,35 +3986,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38083986 "tmp.zig:8:9: error: integer value '256' cannot be stored in type 'u8'",
38093987 });
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",
38123990 \\export fn entry() void {
38133991 \\ const a: fn () c_void = undefined;
3992 \\ _ = a;
38143993 \\}
38153994 , &[_][]const u8{
38163995 "tmp.zig:2:20: error: return type cannot be opaque",
38173996 });
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",
38203999 \\export fn entry() void {
38214000 \\ var x: i32 = 1234;
38224001 \\ var p: *i32 = &x;
38234002 \\ var pp: *?*i32 = &p;
38244003 \\ pp.* = null;
38254004 \\ var y = p.*;
4005 \\ _ = y;
38264006 \\}
38274007 , &[_][]const u8{
38284008 "tmp.zig:4:23: error: expected type '*?*i32', found '**i32'",
38294009 });
38304010
3831 cases.add("attempted implicit cast from T to [*]const T",
4011 ctx.objErrStage1("attempted implicit cast from T to [*]const T",
38324012 \\export fn entry() void {
38334013 \\ const x: [*]const bool = true;
4014 \\ _ = x;
38344015 \\}
38354016 , &[_][]const u8{
38364017 "tmp.zig:2:30: error: expected type '[*]const bool', found 'bool'",
38374018 });
38384019
3839 cases.add("dereference unknown length pointer",
4020 ctx.objErrStage1("dereference unknown length pointer",
38404021 \\export fn entry(x: [*]i32) i32 {
38414022 \\ return x.*;
38424023 \\}
......@@ -3844,7 +4025,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38444025 "tmp.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32'",
38454026 });
38464027
3847 cases.add("field access of unknown length pointer",
4028 ctx.objErrStage1("field access of unknown length pointer",
38484029 \\const Foo = extern struct {
38494030 \\ a: i32,
38504031 \\};
......@@ -3856,13 +4037,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38564037 "tmp.zig:6:8: error: type '[*]Foo' does not support field access",
38574038 });
38584039
3859 cases.add("unknown length pointer to opaque",
4040 ctx.objErrStage1("unknown length pointer to opaque",
38604041 \\export const T = [*]opaque {};
38614042 , &[_][]const u8{
38624043 "tmp.zig:1:21: error: unknown-length pointer to opaque",
38634044 });
38644045
3865 cases.add("error when evaluating return type",
4046 ctx.objErrStage1("error when evaluating return type",
38664047 \\const Foo = struct {
38674048 \\ map: @as(i32, i32),
38684049 \\
......@@ -3872,20 +4053,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38724053 \\};
38734054 \\export fn entry() void {
38744055 \\ var rule_set = try Foo.init();
4056 \\ _ = rule_set;
38754057 \\}
38764058 , &[_][]const u8{
38774059 "tmp.zig:2:19: error: expected type 'i32', found 'type'",
38784060 });
38794061
3880 cases.add("slicing single-item pointer",
4062 ctx.objErrStage1("slicing single-item pointer",
38814063 \\export fn entry(ptr: *i32) void {
38824064 \\ const slice = ptr[0..2];
4065 \\ _ = slice;
38834066 \\}
38844067 , &[_][]const u8{
38854068 "tmp.zig:2:22: error: slice of single-item pointer",
38864069 });
38874070
3888 cases.add("indexing single-item pointer",
4071 ctx.objErrStage1("indexing single-item pointer",
38894072 \\export fn entry(ptr: *i32) i32 {
38904073 \\ return ptr[1];
38914074 \\}
......@@ -3893,12 +4076,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38934076 "tmp.zig:2:15: error: index of single-item pointer",
38944077 });
38954078
3896 cases.add("nested error set mismatch",
4079 ctx.objErrStage1("nested error set mismatch",
38974080 \\const NextError = error{NextError};
38984081 \\const OtherError = error{OutOfMemory};
38994082 \\
39004083 \\export fn entry() void {
39014084 \\ const a: ?NextError!i32 = foo();
4085 \\ _ = a;
39024086 \\}
39034087 \\
39044088 \\fn foo() ?OtherError!i32 {
......@@ -3911,7 +4095,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39114095 "tmp.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set",
39124096 });
39134097
3914 cases.add("invalid deref on switch target",
4098 ctx.objErrStage1("invalid deref on switch target",
39154099 \\comptime {
39164100 \\ var tile = Tile.Empty;
39174101 \\ switch (tile.*) {
......@@ -3927,13 +4111,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39274111 "tmp.zig:3:17: error: attempt to dereference non-pointer type 'Tile'",
39284112 });
39294113
3930 cases.add("invalid field access in comptime",
3931 \\comptime { var x = doesnt_exist.whatever; }
4114 ctx.objErrStage1("invalid field access in comptime",
4115 \\comptime { var x = doesnt_exist.whatever; _ = x; }
39324116 , &[_][]const u8{
39334117 "tmp.zig:1:20: error: use of undeclared identifier 'doesnt_exist'",
39344118 });
39354119
3936 cases.add("suspend inside suspend block",
4120 ctx.objErrStage1("suspend inside suspend block",
39374121 \\export fn entry() void {
39384122 \\ _ = async foo();
39394123 \\}
......@@ -3948,17 +4132,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39484132 "tmp.zig:5:5: note: other suspend block here",
39494133 });
39504134
3951 cases.add("assign inline fn to non-comptime var",
4135 ctx.objErrStage1("assign inline fn to non-comptime var",
39524136 \\export fn entry() void {
39534137 \\ var a = b;
4138 \\ _ = a;
39544139 \\}
39554140 \\fn b() callconv(.Inline) void { }
39564141 , &[_][]const u8{
39574142 "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",
39594144 });
39604145
3961 cases.add("wrong type passed to @panic",
4146 ctx.objErrStage1("wrong type passed to @panic",
39624147 \\export fn entry() void {
39634148 \\ var e = error.Foo;
39644149 \\ @panic(e);
......@@ -3967,7 +4152,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39674152 "tmp.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'",
39684153 });
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",
39714156 \\const FloatInt = extern union {
39724157 \\ Float: f32,
39734158 \\ Int: i32,
......@@ -3975,13 +4160,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39754160 \\export fn entry() void {
39764161 \\ var fi = FloatInt{.Float = 123.45};
39774162 \\ var tagName = @tagName(fi);
4163 \\ _ = tagName;
39784164 \\}
39794165 , &[_][]const u8{
39804166 "tmp.zig:7:19: error: union has no associated enum",
39814167 "tmp.zig:1:18: note: declared here",
39824168 });
39834169
3984 cases.add("returning error from void async function",
4170 ctx.objErrStage1("returning error from void async function",
39854171 \\export fn entry() void {
39864172 \\ _ = async amain();
39874173 \\}
......@@ -3992,37 +4178,40 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39924178 "tmp.zig:5:17: error: expected type 'void', found 'error{ShouldBeCompileError}'",
39934179 });
39944180
3995 cases.add("var makes structs required to be comptime known",
4181 ctx.objErrStage1("var makes structs required to be comptime known",
39964182 \\export fn entry() void {
39974183 \\ const S = struct{v: anytype};
39984184 \\ var s = S{.v=@as(i32, 10)};
4185 \\ _ = s;
39994186 \\}
40004187 , &[_][]const u8{
40014188 "tmp.zig:3:4: error: variable of type 'S' must be const or comptime",
40024189 });
40034190
4004 cases.add("@ptrCast discards const qualifier",
4191 ctx.objErrStage1("@ptrCast discards const qualifier",
40054192 \\export fn entry() void {
40064193 \\ const x: i32 = 1234;
40074194 \\ const y = @ptrCast(*i32, &x);
4195 \\ _ = y;
40084196 \\}
40094197 , &[_][]const u8{
40104198 "tmp.zig:3:15: error: cast discards const qualifier",
40114199 });
40124200
4013 cases.add("comptime slice of undefined pointer non-zero len",
4201 ctx.objErrStage1("comptime slice of undefined pointer non-zero len",
40144202 \\export fn entry() void {
40154203 \\ const slice = @as([*]i32, undefined)[0..1];
4204 \\ _ = slice;
40164205 \\}
40174206 , &[_][]const u8{
40184207 "tmp.zig:2:41: error: non-zero length slice of undefined pointer",
40194208 });
40204209
4021 cases.add("type checking function pointers",
4210 ctx.objErrStage1("type checking function pointers",
40224211 \\fn a(b: fn (*const u8) void) void {
40234212 \\ b('a');
40244213 \\}
4025 \\fn c(d: u8) void {}
4214 \\fn c(d: u8) void {_ = d;}
40264215 \\export fn entry() void {
40274216 \\ a(c);
40284217 \\}
......@@ -4030,7 +4219,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40304219 "tmp.zig:6:7: error: expected type 'fn(*const u8) void', found 'fn(u8) void'",
40314220 });
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",
40344223 \\export fn entry() void {
40354224 \\ foo(error.A);
40364225 \\}
......@@ -4043,7 +4232,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40434232 "tmp.zig:5:5: error: else prong required when switching on type 'anyerror'",
40444233 });
40454234
4046 cases.add("error not handled in switch",
4235 ctx.objErrStage1("error not handled in switch",
40474236 \\export fn entry() void {
40484237 \\ foo(452) catch |err| switch (err) {
40494238 \\ error.Foo => {},
......@@ -4062,7 +4251,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40624251 "tmp.zig:2:26: error: error.Bar not handled in switch",
40634252 });
40644253
4065 cases.add("duplicate error in switch",
4254 ctx.objErrStage1("duplicate error in switch",
40664255 \\export fn entry() void {
40674256 \\ foo(452) catch |err| switch (err) {
40684257 \\ error.Foo => {},
......@@ -4080,10 +4269,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40804269 \\}
40814270 , &[_][]const u8{
40824271 "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",
40844273 });
40854274
4086 cases.add("invalid cast from integral type to enum",
4275 ctx.objErrStage1("invalid cast from integral type to enum",
40874276 \\const E = enum(usize) { One, Two };
40884277 \\
40894278 \\export fn entry() void {
......@@ -4099,7 +4288,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40994288 "tmp.zig:9:10: error: expected type 'usize', found 'E'",
41004289 });
41014290
4102 cases.add("range operator in switch used on error set",
4291 ctx.objErrStage1("range operator in switch used on error set",
41034292 \\export fn entry() void {
41044293 \\ try foo(452) catch |err| switch (err) {
41054294 \\ error.A ... error.B => {},
......@@ -4117,33 +4306,35 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
41174306 "tmp.zig:3:17: error: operator not allowed for errors",
41184307 });
41194308
4120 cases.add("inferring error set of function pointer",
4309 ctx.objErrStage1("inferring error set of function pointer",
41214310 \\comptime {
41224311 \\ const z: ?fn()!void = null;
41234312 \\}
41244313 , &[_][]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",
41264315 });
41274316
4128 cases.add("access non-existent member of error set",
4317 ctx.objErrStage1("access non-existent member of error set",
41294318 \\const Foo = error{A};
41304319 \\comptime {
41314320 \\ const z = Foo.Bar;
4321 \\ _ = z;
41324322 \\}
41334323 , &[_][]const u8{
41344324 "tmp.zig:3:18: error: no error named 'Bar' in 'Foo'",
41354325 });
41364326
4137 cases.add("error union operator with non error set LHS",
4327 ctx.objErrStage1("error union operator with non error set LHS",
41384328 \\comptime {
41394329 \\ const z = i32!i32;
41404330 \\ var x: z = undefined;
4331 \\ _ = x;
41414332 \\}
41424333 , &[_][]const u8{
41434334 "tmp.zig:2:15: error: expected error set type, found type 'i32'",
41444335 });
41454336
4146 cases.add("error equality but sets have no common members",
4337 ctx.objErrStage1("error equality but sets have no common members",
41474338 \\const Set1 = error{A, C};
41484339 \\const Set2 = error{B, D};
41494340 \\export fn entry() void {
......@@ -4158,29 +4349,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
41584349 "tmp.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors",
41594350 });
41604351
4161 cases.add("only equality binary operator allowed for error sets",
4352 ctx.objErrStage1("only equality binary operator allowed for error sets",
41624353 \\comptime {
41634354 \\ const z = error.A > error.B;
4355 \\ _ = z;
41644356 \\}
41654357 , &[_][]const u8{
41664358 "tmp.zig:2:23: error: operator not allowed for errors",
41674359 });
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",
41704362 \\const Set1 = error {A, B};
41714363 \\const Set2 = error {A, C};
41724364 \\comptime {
41734365 \\ var x = Set1.B;
41744366 \\ var y = @errSetCast(Set2, x);
4367 \\ _ = y;
41754368 \\}
41764369 , &[_][]const u8{
41774370 "tmp.zig:5:13: error: error.B not a member of error set 'Set2'",
41784371 });
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",
41814374 \\const SmallErrorSet = error{A};
41824375 \\export fn entry() void {
41834376 \\ var x: SmallErrorSet!i32 = foo();
4377 \\ _ = x;
41844378 \\}
41854379 \\fn foo() anyerror!i32 {
41864380 \\ return error.B;
......@@ -4191,10 +4385,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
41914385 "tmp.zig:3:35: note: cannot cast global error set into smaller set",
41924386 });
41934387
4194 cases.add("cast global error set to error set",
4388 ctx.objErrStage1("cast global error set to error set",
41954389 \\const SmallErrorSet = error{A};
41964390 \\export fn entry() void {
41974391 \\ var x: SmallErrorSet = foo();
4392 \\ _ = x;
41984393 \\}
41994394 \\fn foo() anyerror {
42004395 \\ return error.B;
......@@ -4203,7 +4398,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
42034398 "tmp.zig:3:31: error: expected type 'SmallErrorSet', found 'anyerror'",
42044399 "tmp.zig:3:31: note: cannot cast global error set into smaller set",
42054400 });
4206 cases.add("recursive inferred error set",
4401 ctx.objErrStage1("recursive inferred error set",
42074402 \\export fn entry() void {
42084403 \\ foo() catch unreachable;
42094404 \\}
......@@ -4214,7 +4409,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
42144409 "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",
42154410 });
42164411
4217 cases.add("implicit cast of error set not a subset",
4412 ctx.objErrStage1("implicit cast of error set not a subset",
42184413 \\const Set1 = error{A, B};
42194414 \\const Set2 = error{A, C};
42204415 \\export fn entry() void {
......@@ -4222,13 +4417,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
42224417 \\}
42234418 \\fn foo(set1: Set1) void {
42244419 \\ var x: Set2 = set1;
4420 \\ _ = x;
42254421 \\}
42264422 , &[_][]const u8{
42274423 "tmp.zig:7:19: error: expected type 'Set2', found 'Set1'",
42284424 "tmp.zig:1:23: note: 'error.B' not a member of destination error set",
42294425 });
42304426
4231 cases.add("int to err global invalid number",
4427 ctx.objErrStage1("int to err global invalid number",
42324428 \\const Set1 = error{
42334429 \\ A,
42344430 \\ B,
......@@ -4236,12 +4432,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
42364432 \\comptime {
42374433 \\ var x: u16 = 3;
42384434 \\ var y = @intToError(x);
4435 \\ _ = y;
42394436 \\}
42404437 , &[_][]const u8{
42414438 "tmp.zig:7:13: error: integer value 3 represents no error",
42424439 });
42434440
4244 cases.add("int to err non global invalid number",
4441 ctx.objErrStage1("int to err non global invalid number",
42454442 \\const Set1 = error{
42464443 \\ A,
42474444 \\ B,
......@@ -4253,68 +4450,74 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
42534450 \\comptime {
42544451 \\ var x = @errorToInt(Set1.B);
42554452 \\ var y = @errSetCast(Set2, @intToError(x));
4453 \\ _ = y;
42564454 \\}
42574455 , &[_][]const u8{
42584456 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'",
42594457 });
42604458
4261 cases.add("duplicate error value in error set",
4459 ctx.objErrStage1("duplicate error value in error set",
42624460 \\const Foo = error {
42634461 \\ Bar,
42644462 \\ Bar,
42654463 \\};
42664464 \\export fn entry() void {
42674465 \\ const a: Foo = undefined;
4466 \\ _ = a;
42684467 \\}
42694468 , &[_][]const u8{
42704469 "tmp.zig:3:5: error: duplicate error: 'Bar'",
42714470 "tmp.zig:2:5: note: other error here",
42724471 });
42734472
4274 cases.add("cast negative integer literal to usize",
4473 ctx.objErrStage1("cast negative integer literal to usize",
42754474 \\export fn entry() void {
42764475 \\ const x = @as(usize, -10);
4476 \\ _ = x;
42774477 \\}
42784478 , &[_][]const u8{
42794479 "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'",
42804480 });
42814481
4282 cases.add("use invalid number literal as array index",
4482 ctx.objErrStage1("use invalid number literal as array index",
42834483 \\var v = 25;
42844484 \\export fn entry() void {
42854485 \\ var arr: [v]u8 = undefined;
4486 \\ _ = arr;
42864487 \\}
42874488 , &[_][]const u8{
42884489 "tmp.zig:1:1: error: unable to infer variable type",
42894490 });
42904491
4291 cases.add("duplicate struct field",
4492 ctx.objErrStage1("duplicate struct field",
42924493 \\const Foo = struct {
42934494 \\ Bar: i32,
42944495 \\ Bar: usize,
42954496 \\};
42964497 \\export fn entry() void {
42974498 \\ const a: Foo = undefined;
4499 \\ _ = a;
42984500 \\}
42994501 , &[_][]const u8{
43004502 "tmp.zig:3:5: error: duplicate struct field: 'Bar'",
43014503 "tmp.zig:2:5: note: other field here",
43024504 });
43034505
4304 cases.add("duplicate union field",
4506 ctx.objErrStage1("duplicate union field",
43054507 \\const Foo = union {
43064508 \\ Bar: i32,
43074509 \\ Bar: usize,
43084510 \\};
43094511 \\export fn entry() void {
43104512 \\ const a: Foo = undefined;
4513 \\ _ = a;
43114514 \\}
43124515 , &[_][]const u8{
43134516 "tmp.zig:3:5: error: duplicate union field: 'Bar'",
43144517 "tmp.zig:2:5: note: other field here",
43154518 });
43164519
4317 cases.add("duplicate enum field",
4520 ctx.objErrStage1("duplicate enum field",
43184521 \\const Foo = enum {
43194522 \\ Bar,
43204523 \\ Bar,
......@@ -4322,13 +4525,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
43224525 \\
43234526 \\export fn entry() void {
43244527 \\ const a: Foo = undefined;
4528 \\ _ = a;
43254529 \\}
43264530 , &[_][]const u8{
43274531 "tmp.zig:3:5: error: duplicate enum field: 'Bar'",
43284532 "tmp.zig:2:5: note: other field here",
43294533 });
43304534
4331 cases.add("calling function with naked calling convention",
4535 ctx.objErrStage1("calling function with naked calling convention",
43324536 \\export fn entry() void {
43334537 \\ foo();
43344538 \\}
......@@ -4338,42 +4542,42 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
43384542 "tmp.zig:4:1: note: declared here",
43394543 });
43404544
4341 cases.add("function with invalid return type",
4545 ctx.objErrStage1("function with invalid return type",
43424546 \\export fn foo() boid {}
43434547 , &[_][]const u8{
43444548 "tmp.zig:1:17: error: use of undeclared identifier 'boid'",
43454549 });
43464550
4347 cases.add("function with non-extern non-packed enum parameter",
4551 ctx.objErrStage1("function with non-extern non-packed enum parameter",
43484552 \\const Foo = enum { A, B, C };
4349 \\export fn entry(foo: Foo) void { }
4553 \\export fn entry(foo: Foo) void { _ = foo; }
43504554 , &[_][]const u8{
43514555 "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
43524556 });
43534557
4354 cases.add("function with non-extern non-packed struct parameter",
4558 ctx.objErrStage1("function with non-extern non-packed struct parameter",
43554559 \\const Foo = struct {
43564560 \\ A: i32,
43574561 \\ B: f32,
43584562 \\ C: bool,
43594563 \\};
4360 \\export fn entry(foo: Foo) void { }
4564 \\export fn entry(foo: Foo) void { _ = foo; }
43614565 , &[_][]const u8{
43624566 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
43634567 });
43644568
4365 cases.add("function with non-extern non-packed union parameter",
4569 ctx.objErrStage1("function with non-extern non-packed union parameter",
43664570 \\const Foo = union {
43674571 \\ A: i32,
43684572 \\ B: f32,
43694573 \\ C: bool,
43704574 \\};
4371 \\export fn entry(foo: Foo) void { }
4575 \\export fn entry(foo: Foo) void { _ = foo; }
43724576 , &[_][]const u8{
43734577 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
43744578 });
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",
43774581 \\const Foo = enum { M };
43784582 \\
43794583 \\export fn entry() void {
......@@ -4384,15 +4588,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
43844588 "tmp.zig:5:5: error: enumeration value 'Foo.M' not handled in switch",
43854589 });
43864590
4387 cases.add("shift by negative comptime integer",
4591 ctx.objErrStage1("shift by negative comptime integer",
43884592 \\comptime {
43894593 \\ var a = 1 >> -1;
4594 \\ _ = a;
43904595 \\}
43914596 , &[_][]const u8{
43924597 "tmp.zig:2:18: error: shift by negative value -1",
43934598 });
43944599
4395 cases.add("@panic called at compile time",
4600 ctx.objErrStage1("@panic called at compile time",
43964601 \\export fn entry() void {
43974602 \\ comptime {
43984603 \\ @panic("aoeu",);
......@@ -4402,20 +4607,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44024607 "tmp.zig:3:9: error: encountered @panic at compile-time",
44034608 });
44044609
4405 cases.add("wrong return type for main",
4610 ctx.objErrStage1("wrong return type for main",
44064611 \\pub fn main() f32 { }
44074612 , &[_][]const u8{
44084613 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",
44094614 });
44104615
4411 cases.add("double ?? on main return value",
4616 ctx.objErrStage1("double ?? on main return value",
44124617 \\pub fn main() ??void {
44134618 \\}
44144619 , &[_][]const u8{
44154620 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",
44164621 });
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",
44194624 \\export fn entry() void {
44204625 \\ const BlockKind = u32;
44214626 \\
......@@ -4424,12 +4629,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44244629 \\ };
44254630 \\
44264631 \\ bogus;
4632 \\
4633 \\ _ = Block;
44274634 \\}
44284635 , &[_][]const u8{
44294636 "tmp.zig:8:5: error: use of undeclared identifier 'bogus'",
44304637 });
44314638
4432 cases.add("labeled break not found",
4639 ctx.objErrStage1("labeled break not found",
44334640 \\export fn entry() void {
44344641 \\ blah: while (true) {
44354642 \\ while (true) {
......@@ -4438,10 +4645,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44384645 \\ }
44394646 \\}
44404647 , &[_][]const u8{
4441 "tmp.zig:4:13: error: label not found: 'outer'",
4648 "tmp.zig:4:20: error: label not found: 'outer'",
44424649 });
44434650
4444 cases.add("labeled continue not found",
4651 ctx.objErrStage1("labeled continue not found",
44454652 \\export fn entry() void {
44464653 \\ var i: usize = 0;
44474654 \\ blah: while (i < 10) : (i += 1) {
......@@ -4451,17 +4658,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44514658 \\ }
44524659 \\}
44534660 , &[_][]const u8{
4454 "tmp.zig:5:13: error: labeled loop not found: 'outer'",
4661 "tmp.zig:5:23: error: label not found: 'outer'",
44554662 });
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",
44584665 \\extern fn foo(ptr: fn(*void) callconv(.C) void) void;
44594666 \\
44604667 \\export fn entry() void {
44614668 \\ foo(bar);
44624669 \\}
44634670 \\
4464 \\fn bar(x: *void) callconv(.C) void { }
4671 \\fn bar(x: *void) callconv(.C) void { _ = x; }
44654672 \\export fn entry2() void {
44664673 \\ bar(&{});
44674674 \\}
......@@ -4470,7 +4677,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44704677 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
44714678 });
44724679
4473 cases.add("implicit semicolon - block statement",
4680 ctx.objErrStage1("implicit semicolon - block statement",
44744681 \\export fn entry() void {
44754682 \\ {}
44764683 \\ var good = {};
......@@ -4478,10 +4685,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44784685 \\ var bad = {};
44794686 \\}
44804687 , &[_][]const u8{
4481 "tmp.zig:5:5: error: expected token ';', found 'var'",
4688 "tmp.zig:5:5: error: expected ';', found 'var'",
44824689 });
44834690
4484 cases.add("implicit semicolon - block expr",
4691 ctx.objErrStage1("implicit semicolon - block expr",
44854692 \\export fn entry() void {
44864693 \\ _ = {};
44874694 \\ var good = {};
......@@ -4489,10 +4696,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
44894696 \\ var bad = {};
44904697 \\}
44914698 , &[_][]const u8{
4492 "tmp.zig:5:5: error: expected token ';', found 'var'",
4699 "tmp.zig:5:5: error: expected ';', found 'var'",
44934700 });
44944701
4495 cases.add("implicit semicolon - comptime statement",
4702 ctx.objErrStage1("implicit semicolon - comptime statement",
44964703 \\export fn entry() void {
44974704 \\ comptime {}
44984705 \\ var good = {};
......@@ -4500,10 +4707,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45004707 \\ var bad = {};
45014708 \\}
45024709 , &[_][]const u8{
4503 "tmp.zig:5:5: error: expected token ';', found 'var'",
4710 "tmp.zig:5:5: error: expected ';', found 'var'",
45044711 });
45054712
4506 cases.add("implicit semicolon - comptime expression",
4713 ctx.objErrStage1("implicit semicolon - comptime expression",
45074714 \\export fn entry() void {
45084715 \\ _ = comptime {};
45094716 \\ var good = {};
......@@ -4511,10 +4718,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45114718 \\ var bad = {};
45124719 \\}
45134720 , &[_][]const u8{
4514 "tmp.zig:5:5: error: expected token ';', found 'var'",
4721 "tmp.zig:5:5: error: expected ';', found 'var'",
45154722 });
45164723
4517 cases.add("implicit semicolon - defer",
4724 ctx.objErrStage1("implicit semicolon - defer",
45184725 \\export fn entry() void {
45194726 \\ defer {}
45204727 \\ var good = {};
......@@ -4522,10 +4729,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45224729 \\ var bad = {};
45234730 \\}
45244731 , &[_][]const u8{
4525 "tmp.zig:5:5: error: expected token ';', found 'var'",
4732 "tmp.zig:5:5: error: expected ';', found 'var'",
45264733 });
45274734
4528 cases.add("implicit semicolon - if statement",
4735 ctx.objErrStage1("implicit semicolon - if statement",
45294736 \\export fn entry() void {
45304737 \\ if(true) {}
45314738 \\ var good = {};
......@@ -4533,10 +4740,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45334740 \\ var bad = {};
45344741 \\}
45354742 , &[_][]const u8{
4536 "tmp.zig:5:5: error: expected token ';', found 'var'",
4743 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
45374744 });
45384745
4539 cases.add("implicit semicolon - if expression",
4746 ctx.objErrStage1("implicit semicolon - if expression",
45404747 \\export fn entry() void {
45414748 \\ _ = if(true) {};
45424749 \\ var good = {};
......@@ -4544,10 +4751,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45444751 \\ var bad = {};
45454752 \\}
45464753 , &[_][]const u8{
4547 "tmp.zig:5:5: error: expected token ';', found 'var'",
4754 "tmp.zig:5:5: error: expected ';', found 'var'",
45484755 });
45494756
4550 cases.add("implicit semicolon - if-else statement",
4757 ctx.objErrStage1("implicit semicolon - if-else statement",
45514758 \\export fn entry() void {
45524759 \\ if(true) {} else {}
45534760 \\ var good = {};
......@@ -4555,10 +4762,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45554762 \\ var bad = {};
45564763 \\}
45574764 , &[_][]const u8{
4558 "tmp.zig:5:5: error: expected token ';', found 'var'",
4765 "tmp.zig:5:5: error: expected ';', found 'var'",
45594766 });
45604767
4561 cases.add("implicit semicolon - if-else expression",
4768 ctx.objErrStage1("implicit semicolon - if-else expression",
45624769 \\export fn entry() void {
45634770 \\ _ = if(true) {} else {};
45644771 \\ var good = {};
......@@ -4566,10 +4773,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45664773 \\ var bad = {};
45674774 \\}
45684775 , &[_][]const u8{
4569 "tmp.zig:5:5: error: expected token ';', found 'var'",
4776 "tmp.zig:5:5: error: expected ';', found 'var'",
45704777 });
45714778
4572 cases.add("implicit semicolon - if-else-if statement",
4779 ctx.objErrStage1("implicit semicolon - if-else-if statement",
45734780 \\export fn entry() void {
45744781 \\ if(true) {} else if(true) {}
45754782 \\ var good = {};
......@@ -4577,10 +4784,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45774784 \\ var bad = {};
45784785 \\}
45794786 , &[_][]const u8{
4580 "tmp.zig:5:5: error: expected token ';', found 'var'",
4787 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
45814788 });
45824789
4583 cases.add("implicit semicolon - if-else-if expression",
4790 ctx.objErrStage1("implicit semicolon - if-else-if expression",
45844791 \\export fn entry() void {
45854792 \\ _ = if(true) {} else if(true) {};
45864793 \\ var good = {};
......@@ -4588,10 +4795,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45884795 \\ var bad = {};
45894796 \\}
45904797 , &[_][]const u8{
4591 "tmp.zig:5:5: error: expected token ';', found 'var'",
4798 "tmp.zig:5:5: error: expected ';', found 'var'",
45924799 });
45934800
4594 cases.add("implicit semicolon - if-else-if-else statement",
4801 ctx.objErrStage1("implicit semicolon - if-else-if-else statement",
45954802 \\export fn entry() void {
45964803 \\ if(true) {} else if(true) {} else {}
45974804 \\ var good = {};
......@@ -4599,10 +4806,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45994806 \\ var bad = {};
46004807 \\}
46014808 , &[_][]const u8{
4602 "tmp.zig:5:5: error: expected token ';', found 'var'",
4809 "tmp.zig:5:5: error: expected ';', found 'var'",
46034810 });
46044811
4605 cases.add("implicit semicolon - if-else-if-else expression",
4812 ctx.objErrStage1("implicit semicolon - if-else-if-else expression",
46064813 \\export fn entry() void {
46074814 \\ _ = if(true) {} else if(true) {} else {};
46084815 \\ var good = {};
......@@ -4610,10 +4817,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46104817 \\ var bad = {};
46114818 \\}
46124819 , &[_][]const u8{
4613 "tmp.zig:5:5: error: expected token ';', found 'var'",
4820 "tmp.zig:5:5: error: expected ';', found 'var'",
46144821 });
46154822
4616 cases.add("implicit semicolon - test statement",
4823 ctx.objErrStage1("implicit semicolon - test statement",
46174824 \\export fn entry() void {
46184825 \\ if (foo()) |_| {}
46194826 \\ var good = {};
......@@ -4621,10 +4828,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46214828 \\ var bad = {};
46224829 \\}
46234830 , &[_][]const u8{
4624 "tmp.zig:5:5: error: expected token ';', found 'var'",
4831 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
46254832 });
46264833
4627 cases.add("implicit semicolon - test expression",
4834 ctx.objErrStage1("implicit semicolon - test expression",
46284835 \\export fn entry() void {
46294836 \\ _ = if (foo()) |_| {};
46304837 \\ var good = {};
......@@ -4632,10 +4839,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46324839 \\ var bad = {};
46334840 \\}
46344841 , &[_][]const u8{
4635 "tmp.zig:5:5: error: expected token ';', found 'var'",
4842 "tmp.zig:5:5: error: expected ';', found 'var'",
46364843 });
46374844
4638 cases.add("implicit semicolon - while statement",
4845 ctx.objErrStage1("implicit semicolon - while statement",
46394846 \\export fn entry() void {
46404847 \\ while(true) {}
46414848 \\ var good = {};
......@@ -4643,10 +4850,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46434850 \\ var bad = {};
46444851 \\}
46454852 , &[_][]const u8{
4646 "tmp.zig:5:5: error: expected token ';', found 'var'",
4853 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
46474854 });
46484855
4649 cases.add("implicit semicolon - while expression",
4856 ctx.objErrStage1("implicit semicolon - while expression",
46504857 \\export fn entry() void {
46514858 \\ _ = while(true) {};
46524859 \\ var good = {};
......@@ -4654,10 +4861,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46544861 \\ var bad = {};
46554862 \\}
46564863 , &[_][]const u8{
4657 "tmp.zig:5:5: error: expected token ';', found 'var'",
4864 "tmp.zig:5:5: error: expected ';', found 'var'",
46584865 });
46594866
4660 cases.add("implicit semicolon - while-continue statement",
4867 ctx.objErrStage1("implicit semicolon - while-continue statement",
46614868 \\export fn entry() void {
46624869 \\ while(true):({}) {}
46634870 \\ var good = {};
......@@ -4665,10 +4872,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46654872 \\ var bad = {};
46664873 \\}
46674874 , &[_][]const u8{
4668 "tmp.zig:5:5: error: expected token ';', found 'var'",
4875 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
46694876 });
46704877
4671 cases.add("implicit semicolon - while-continue expression",
4878 ctx.objErrStage1("implicit semicolon - while-continue expression",
46724879 \\export fn entry() void {
46734880 \\ _ = while(true):({}) {};
46744881 \\ var good = {};
......@@ -4676,10 +4883,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46764883 \\ var bad = {};
46774884 \\}
46784885 , &[_][]const u8{
4679 "tmp.zig:5:5: error: expected token ';', found 'var'",
4886 "tmp.zig:5:5: error: expected ';', found 'var'",
46804887 });
46814888
4682 cases.add("implicit semicolon - for statement",
4889 ctx.objErrStage1("implicit semicolon - for statement",
46834890 \\export fn entry() void {
46844891 \\ for(foo()) |_| {}
46854892 \\ var good = {};
......@@ -4687,10 +4894,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46874894 \\ var bad = {};
46884895 \\}
46894896 , &[_][]const u8{
4690 "tmp.zig:5:5: error: expected token ';', found 'var'",
4897 "tmp.zig:5:5: error: expected ';' or 'else', found 'var'",
46914898 });
46924899
4693 cases.add("implicit semicolon - for expression",
4900 ctx.objErrStage1("implicit semicolon - for expression",
46944901 \\export fn entry() void {
46954902 \\ _ = for(foo()) |_| {};
46964903 \\ var good = {};
......@@ -4698,32 +4905,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
46984905 \\ var bad = {};
46994906 \\}
47004907 , &[_][]const u8{
4701 "tmp.zig:5:5: error: expected token ';', found 'var'",
4908 "tmp.zig:5:5: error: expected ';', found 'var'",
47024909 });
47034910
4704 cases.add("multiple function definitions",
4911 ctx.objErrStage1("multiple function definitions",
47054912 \\fn a() void {}
47064913 \\fn a() void {}
47074914 \\export fn entry() void { a(); }
47084915 , &[_][]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",
47104918 });
47114919
4712 cases.add("unreachable with return",
4920 ctx.objErrStage1("unreachable with return",
47134921 \\fn a() noreturn {return;}
47144922 \\export fn entry() void { a(); }
47154923 , &[_][]const u8{
47164924 "tmp.zig:1:18: error: expected type 'noreturn', found 'void'",
47174925 });
47184926
4719 cases.add("control reaches end of non-void function",
4927 ctx.objErrStage1("control reaches end of non-void function",
47204928 \\fn a() i32 {}
47214929 \\export fn entry() void { _ = a(); }
47224930 , &[_][]const u8{
47234931 "tmp.zig:1:12: error: expected type 'i32', found 'void'",
47244932 });
47254933
4726 cases.add("undefined function call",
4934 ctx.objErrStage1("undefined function call",
47274935 \\export fn a() void {
47284936 \\ b();
47294937 \\}
......@@ -4731,30 +4939,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
47314939 "tmp.zig:2:5: error: use of undeclared identifier 'b'",
47324940 });
47334941
4734 cases.add("wrong number of arguments",
4942 ctx.objErrStage1("wrong number of arguments",
47354943 \\export fn a() void {
4736 \\ b(1);
4944 \\ c(1);
47374945 \\}
4738 \\fn b(a: i32, b: i32, c: i32) void { }
4946 \\fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
47394947 , &[_][]const u8{
47404948 "tmp.zig:2:6: error: expected 3 argument(s), found 1",
47414949 });
47424950
4743 cases.add("invalid type",
4951 ctx.objErrStage1("invalid type",
47444952 \\fn a() bogus {}
47454953 \\export fn entry() void { _ = a(); }
47464954 , &[_][]const u8{
47474955 "tmp.zig:1:8: error: use of undeclared identifier 'bogus'",
47484956 });
47494957
4750 cases.add("pointer to noreturn",
4958 ctx.objErrStage1("pointer to noreturn",
47514959 \\fn a() *noreturn {}
47524960 \\export fn entry() void { _ = a(); }
47534961 , &[_][]const u8{
47544962 "tmp.zig:1:9: error: pointer to noreturn not allowed",
47554963 });
47564964
4757 cases.add("unreachable code",
4965 ctx.objErrStage1("unreachable code",
47584966 \\export fn a() void {
47594967 \\ return;
47604968 \\ b();
......@@ -4762,17 +4970,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
47624970 \\
47634971 \\fn b() void {}
47644972 , &[_][]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",
47664975 });
47674976
4768 cases.add("bad import",
4977 ctx.objErrStage1("bad import",
47694978 \\const bogus = @import("bogus-does-not-exist.zig",);
4770 \\export fn entry() void { bogus.bogo(); }
47714979 , &[_][]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",
47734981 });
47744982
4775 cases.add("undeclared identifier",
4983 ctx.objErrStage1("undeclared identifier",
47764984 \\export fn a() void {
47774985 \\ return
47784986 \\ b +
......@@ -4782,33 +4990,36 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
47824990 "tmp.zig:3:5: error: use of undeclared identifier 'b'",
47834991 });
47844992
4785 cases.add("parameter redeclaration",
4993 ctx.objErrStage1("parameter redeclaration",
47864994 \\fn f(a : i32, a : i32) void {
47874995 \\}
47884996 \\export fn entry() void { f(1, 2); }
47894997 , &[_][]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",
47915000 });
47925001
4793 cases.add("local variable redeclaration",
5002 ctx.objErrStage1("local variable redeclaration",
47945003 \\export fn f() void {
47955004 \\ const a : i32 = 0;
4796 \\ const a = 0;
5005 \\ var a = 0;
47975006 \\}
47985007 , &[_][]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",
48005010 });
48015011
4802 cases.add("local variable redeclares parameter",
5012 ctx.objErrStage1("local variable redeclares parameter",
48035013 \\fn f(a : i32) void {
48045014 \\ const a = 0;
48055015 \\}
48065016 \\export fn entry() void { f(1); }
48075017 , &[_][]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",
48095020 });
48105021
4811 cases.add("variable has wrong type",
5022 ctx.objErrStage1("variable has wrong type",
48125023 \\export fn f() i32 {
48135024 \\ const a = "a";
48145025 \\ return a;
......@@ -4817,7 +5028,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
48175028 "tmp.zig:3:12: error: expected type 'i32', found '*const [1:0]u8'",
48185029 });
48195030
4820 cases.add("if condition is bool, not int",
5031 ctx.objErrStage1("if condition is bool, not int",
48215032 \\export fn f() void {
48225033 \\ if (0) {}
48235034 \\}
......@@ -4825,30 +5036,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
48255036 "tmp.zig:2:9: error: expected type 'bool', found 'comptime_int'",
48265037 });
48275038
4828 cases.add("assign unreachable",
5039 ctx.objErrStage1("assign unreachable",
48295040 \\export fn f() void {
48305041 \\ const a = return;
48315042 \\}
48325043 , &[_][]const u8{
48335044 "tmp.zig:2:5: error: unreachable code",
5045 "tmp.zig:2:15: note: control flow is diverted here",
48345046 });
48355047
4836 cases.add("unreachable variable",
5048 ctx.objErrStage1("unreachable variable",
48375049 \\export fn f() void {
48385050 \\ const a: noreturn = {};
5051 \\ _ = a;
48395052 \\}
48405053 , &[_][]const u8{
48415054 "tmp.zig:2:25: error: expected type 'noreturn', found 'void'",
48425055 });
48435056
4844 cases.add("unreachable parameter",
4845 \\fn f(a: noreturn) void {}
5057 ctx.objErrStage1("unreachable parameter",
5058 \\fn f(a: noreturn) void { _ = a; }
48465059 \\export fn entry() void { f(); }
48475060 , &[_][]const u8{
48485061 "tmp.zig:1:9: error: parameter of type 'noreturn' not allowed",
48495062 });
48505063
4851 cases.add("assign to constant variable",
5064 ctx.objErrStage1("assign to constant variable",
48525065 \\export fn f() void {
48535066 \\ const a = 3;
48545067 \\ a = 4;
......@@ -4857,7 +5070,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
48575070 "tmp.zig:3:9: error: cannot assign to constant",
48585071 });
48595072
4860 cases.add("use of undeclared identifier",
5073 ctx.objErrStage1("use of undeclared identifier",
48615074 \\export fn f() void {
48625075 \\ b = 3;
48635076 \\}
......@@ -4865,15 +5078,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
48655078 "tmp.zig:2:5: error: use of undeclared identifier 'b'",
48665079 });
48675080
4868 cases.add("const is a statement, not an expression",
5081 ctx.objErrStage1("const is a statement, not an expression",
48695082 \\export fn f() void {
48705083 \\ (const a = 0);
48715084 \\}
48725085 , &[_][]const u8{
4873 "tmp.zig:2:6: error: invalid token: 'const'",
5086 "tmp.zig:2:6: error: expected expression, found 'const'",
48745087 });
48755088
4876 cases.add("array access of undeclared identifier",
5089 ctx.objErrStage1("array access of undeclared identifier",
48775090 \\export fn f() void {
48785091 \\ i[i] = i[i];
48795092 \\}
......@@ -4881,7 +5094,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
48815094 "tmp.zig:2:5: error: use of undeclared identifier 'i'",
48825095 });
48835096
4884 cases.add("array access of non array",
5097 ctx.objErrStage1("array access of non array",
48855098 \\export fn f() void {
48865099 \\ var bad : bool = undefined;
48875100 \\ bad[0] = bad[0];
......@@ -4895,7 +5108,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
48955108 "tmp.zig:7:12: error: array access of non-array type 'bool'",
48965109 });
48975110
4898 cases.add("array access with non integer index",
5111 ctx.objErrStage1("array access with non integer index",
48995112 \\export fn f() void {
49005113 \\ var array = "aoeu";
49015114 \\ var bad = false;
......@@ -4911,7 +5124,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
49115124 "tmp.zig:9:15: error: expected type 'usize', found 'bool'",
49125125 });
49135126
4914 cases.add("write to const global variable",
5127 ctx.objErrStage1("write to const global variable",
49155128 \\const x : i32 = 99;
49165129 \\fn f() void {
49175130 \\ x = 1;
......@@ -4921,58 +5134,64 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
49215134 "tmp.zig:3:9: error: cannot assign to constant",
49225135 });
49235136
4924 cases.add("missing else clause",
5137 ctx.objErrStage1("missing else clause",
49255138 \\fn f(b: bool) void {
49265139 \\ const x : i32 = if (b) h: { break :h 1; };
5140 \\ _ = x;
49275141 \\}
49285142 \\fn g(b: bool) void {
49295143 \\ const y = if (b) h: { break :h @as(i32, 1); };
5144 \\ _ = y;
49305145 \\}
49315146 \\export fn entry() void { f(true); g(true); }
49325147 , &[_][]const u8{
49335148 "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'",
49355150 });
49365151
4937 cases.add("invalid struct field",
5152 ctx.objErrStage1("invalid struct field",
49385153 \\const A = struct { x : i32, };
49395154 \\export fn f() void {
49405155 \\ var a : A = undefined;
49415156 \\ a.foo = 1;
49425157 \\ const y = a.bar;
5158 \\ _ = y;
49435159 \\}
49445160 \\export fn g() void {
49455161 \\ var a : A = undefined;
49465162 \\ const y = a.bar;
5163 \\ _ = y;
49475164 \\}
49485165 , &[_][]const u8{
49495166 "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'",
49515168 });
49525169
4953 cases.add("redefinition of struct",
5170 ctx.objErrStage1("redefinition of struct",
49545171 \\const A = struct { x : i32, };
49555172 \\const A = struct { y : i32, };
49565173 , &[_][]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",
49585176 });
49595177
4960 cases.add("redefinition of enums",
4961 \\const A = enum {};
4962 \\const A = enum {};
5178 ctx.objErrStage1("redefinition of enums",
5179 \\const A = enum {x};
5180 \\const A = enum {x};
49635181 , &[_][]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",
49655184 });
49665185
4967 cases.add("redefinition of global variables",
5186 ctx.objErrStage1("redefinition of global variables",
49685187 \\var a : i32 = 1;
49695188 \\var a : i32 = 2;
49705189 , &[_][]const u8{
4971 "tmp.zig:2:1: error: redefinition of 'a'",
4972 "tmp.zig:1:1: note: previous definition is here",
5190 "tmp.zig:2:1: error: redeclaration of 'a'",
5191 "tmp.zig:1:1: note: other declaration here",
49735192 });
49745193
4975 cases.add("duplicate field in struct value expression",
5194 ctx.objErrStage1("duplicate field in struct value expression",
49765195 \\const A = struct {
49775196 \\ x : i32,
49785197 \\ y : i32,
......@@ -4985,12 +5204,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
49855204 \\ .x = 3,
49865205 \\ .z = 4,
49875206 \\ };
5207 \\ _ = a;
49885208 \\}
49895209 , &[_][]const u8{
49905210 "tmp.zig:11:9: error: duplicate field",
49915211 });
49925212
4993 cases.add("missing field in struct value expression",
5213 ctx.objErrStage1("missing field in struct value expression",
49945214 \\const A = struct {
49955215 \\ x : i32,
49965216 \\ y : i32,
......@@ -5003,12 +5223,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
50035223 \\ .z = 4,
50045224 \\ .y = 2,
50055225 \\ };
5226 \\ _ = a;
50065227 \\}
50075228 , &[_][]const u8{
50085229 "tmp.zig:9:17: error: missing field: 'x'",
50095230 });
50105231
5011 cases.add("invalid field in struct value expression",
5232 ctx.objErrStage1("invalid field in struct value expression",
50125233 \\const A = struct {
50135234 \\ x : i32,
50145235 \\ y : i32,
......@@ -5020,12 +5241,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
50205241 \\ .y = 2,
50215242 \\ .foo = 42,
50225243 \\ };
5244 \\ _ = a;
50235245 \\}
50245246 , &[_][]const u8{
50255247 "tmp.zig:10:9: error: no member named 'foo' in struct 'A'",
50265248 });
50275249
5028 cases.add("invalid break expression",
5250 ctx.objErrStage1("invalid break expression",
50295251 \\export fn f() void {
50305252 \\ break;
50315253 \\}
......@@ -5033,7 +5255,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
50335255 "tmp.zig:2:5: error: break expression outside loop",
50345256 });
50355257
5036 cases.add("invalid continue expression",
5258 ctx.objErrStage1("invalid continue expression",
50375259 \\export fn f() void {
50385260 \\ continue;
50395261 \\}
......@@ -5041,48 +5263,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
50415263 "tmp.zig:2:5: error: continue expression outside loop",
50425264 });
50435265
5044 cases.add("invalid maybe type",
5266 ctx.objErrStage1("invalid maybe type",
50455267 \\export fn f() void {
5046 \\ if (true) |x| { }
5268 \\ if (true) |x| { _ = x; }
50475269 \\}
50485270 , &[_][]const u8{
50495271 "tmp.zig:2:9: error: expected optional type, found 'bool'",
50505272 });
50515273
5052 cases.add("cast unreachable",
5274 ctx.objErrStage1("cast unreachable",
50535275 \\fn f() i32 {
50545276 \\ return @as(i32, return 1);
50555277 \\}
50565278 \\export fn entry() void { _ = f(); }
50575279 , &[_][]const u8{
50585280 "tmp.zig:2:12: error: unreachable code",
5281 "tmp.zig:2:21: note: control flow is diverted here",
50595282 });
50605283
5061 cases.add("invalid builtin fn",
5284 ctx.objErrStage1("invalid builtin fn",
50625285 \\fn f() @bogus(foo) {
50635286 \\}
50645287 \\export fn entry() void { _ = f(); }
50655288 , &[_][]const u8{
5066 "tmp.zig:1:8: error: invalid builtin function: 'bogus'",
5289 "tmp.zig:1:8: error: invalid builtin function: '@bogus'",
50675290 });
50685291
5069 cases.add("noalias on non pointer param",
5070 \\fn f(noalias x: i32) void {}
5292 ctx.objErrStage1("noalias on non pointer param",
5293 \\fn f(noalias x: i32) void { _ = x; }
50715294 \\export fn entry() void { f(1234); }
50725295 , &[_][]const u8{
50735296 "tmp.zig:1:6: error: noalias on non-pointer parameter",
50745297 });
50755298
5076 cases.add("struct init syntax for array",
5299 ctx.objErrStage1("struct init syntax for array",
50775300 \\const foo = [3]u16{ .x = 1024 };
50785301 \\comptime {
50795302 \\ _ = foo;
50805303 \\}
50815304 , &[_][]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",
50835306 });
50845307
5085 cases.add("type variables must be constant",
5308 ctx.objErrStage1("type variables must be constant",
50865309 \\var foo = u8;
50875310 \\export fn entry() foo {
50885311 \\ return 1;
......@@ -5091,25 +5314,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
50915314 "tmp.zig:1:1: error: variable of type 'type' must be constant",
50925315 });
50935316
5094 cases.add("variables shadowing types",
5317 ctx.objErrStage1("parameter shadowing global",
50955318 \\const Foo = struct {};
5096 \\const Bar = struct {};
5097 \\
5098 \\fn f(Foo: i32) void {
5099 \\ var Bar : i32 = undefined;
5319 \\fn f(Foo: i32) void {}
5320 \\export fn entry() void {
5321 \\ f(1234);
51005322 \\}
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 {};
51015331 \\
51025332 \\export fn entry() void {
5103 \\ f(1234);
5333 \\ var Bar : i32 = undefined;
5334 \\ _ = Bar;
51045335 \\}
51055336 , &[_][]const u8{
5106 "tmp.zig:4:6: error: redefinition of 'Foo'",
5107 "tmp.zig:1:1: note: previous definition is here",
5108 "tmp.zig:5:5: error: redefinition of 'Bar'",
5109 "tmp.zig:2:1: note: previous definition is here",
5337 "tmp.zig:5:9: error: local shadows declaration of 'Bar'",
5338 "tmp.zig:2:1: note: declared here",
51105339 });
51115340
5112 cases.add("switch expression - missing enumeration prong",
5341 ctx.objErrStage1("switch expression - missing enumeration prong",
51135342 \\const Number = enum {
51145343 \\ One,
51155344 \\ Two,
......@@ -5129,7 +5358,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51295358 "tmp.zig:8:5: error: enumeration value 'Number.Four' not handled in switch",
51305359 });
51315360
5132 cases.add("switch expression - duplicate enumeration prong",
5361 ctx.objErrStage1("switch expression - duplicate enumeration prong",
51335362 \\const Number = enum {
51345363 \\ One,
51355364 \\ Two,
......@@ -5149,10 +5378,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51495378 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
51505379 , &[_][]const u8{
51515380 "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",
51535382 });
51545383
5155 cases.add("switch expression - duplicate enumeration prong when else present",
5384 ctx.objErrStage1("switch expression - duplicate enumeration prong when else present",
51565385 \\const Number = enum {
51575386 \\ One,
51585387 \\ Two,
......@@ -5173,10 +5402,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51735402 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
51745403 , &[_][]const u8{
51755404 "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",
51775406 });
51785407
5179 cases.add("switch expression - multiple else prongs",
5408 ctx.objErrStage1("switch expression - multiple else prongs",
51805409 \\fn f(x: u32) void {
51815410 \\ const value: bool = switch (x) {
51825411 \\ 1234 => false,
......@@ -5191,7 +5420,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51915420 "tmp.zig:5:9: error: multiple else prongs in switch expression",
51925421 });
51935422
5194 cases.add("switch expression - non exhaustive integer prongs",
5423 ctx.objErrStage1("switch expression - non exhaustive integer prongs",
51955424 \\fn foo(x: u8) void {
51965425 \\ switch (x) {
51975426 \\ 0 => {},
......@@ -5202,7 +5431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52025431 "tmp.zig:2:5: error: switch must handle all possibilities",
52035432 });
52045433
5205 cases.add("switch expression - duplicate or overlapping integer value",
5434 ctx.objErrStage1("switch expression - duplicate or overlapping integer value",
52065435 \\fn foo(x: u8) u8 {
52075436 \\ return switch (x) {
52085437 \\ 0 ... 100 => @as(u8, 0),
......@@ -5214,11 +5443,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52145443 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
52155444 , &[_][]const u8{
52165445 "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",
52185447 });
52195448
5220 cases.add("switch expression - duplicate type",
5449 ctx.objErrStage1("switch expression - duplicate type",
52215450 \\fn foo(comptime T: type, x: T) u8 {
5451 \\ _ = x;
52225452 \\ return switch (T) {
52235453 \\ u32 => 0,
52245454 \\ u64 => 1,
......@@ -5228,16 +5458,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52285458 \\}
52295459 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); }
52305460 , &[_][]const u8{
5231 "tmp.zig:5:9: error: duplicate switch value",
5232 "tmp.zig:3:9: note: previous value is here",
5461 "tmp.zig:6:9: error: duplicate switch value",
5462 "tmp.zig:4:9: note: previous value here",
52335463 });
52345464
5235 cases.add("switch expression - duplicate type (struct alias)",
5465 ctx.objErrStage1("switch expression - duplicate type (struct alias)",
52365466 \\const Test = struct {
52375467 \\ bar: i32,
52385468 \\};
52395469 \\const Test2 = Test;
52405470 \\fn foo(comptime T: type, x: T) u8 {
5471 \\ _ = x;
52415472 \\ return switch (T) {
52425473 \\ Test => 0,
52435474 \\ u64 => 1,
......@@ -5247,11 +5478,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52475478 \\}
52485479 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); }
52495480 , &[_][]const u8{
5250 "tmp.zig:9:9: error: duplicate switch value",
5251 "tmp.zig:7:9: note: previous value is here",
5481 "tmp.zig:10:9: error: duplicate switch value",
5482 "tmp.zig:8:9: note: previous value here",
52525483 });
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",
52555486 \\fn foo(x: *u8) void {
52565487 \\ switch (x) {
52575488 \\ &y => {},
......@@ -5263,7 +5494,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52635494 "tmp.zig:2:5: error: else prong required when switching on type '*u8'",
52645495 });
52655496
5266 cases.add("global variable initializer must be constant expression",
5497 ctx.objErrStage1("global variable initializer must be constant expression",
52675498 \\extern fn foo() i32;
52685499 \\const x = foo();
52695500 \\export fn entry() i32 { return x; }
......@@ -5271,7 +5502,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52715502 "tmp.zig:2:11: error: unable to evaluate constant expression",
52725503 });
52735504
5274 cases.add("array concatenation with wrong type",
5505 ctx.objErrStage1("array concatenation with wrong type",
52755506 \\const src = "aoeu";
52765507 \\const derp: usize = 1234;
52775508 \\const a = derp ++ "foo";
......@@ -5281,7 +5512,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52815512 "tmp.zig:3:11: error: expected array, found 'usize'",
52825513 });
52835514
5284 cases.add("non compile time array concatenation",
5515 ctx.objErrStage1("non compile time array concatenation",
52855516 \\fn f() []u8 {
52865517 \\ return s ++ "foo";
52875518 \\}
......@@ -5291,7 +5522,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52915522 "tmp.zig:2:12: error: unable to evaluate constant expression",
52925523 });
52935524
5294 cases.add("@cImport with bogus include",
5525 ctx.objErrStage1("@cImport with bogus include",
52955526 \\const c = @cImport(@cInclude("bogus.h"));
52965527 \\export fn entry() usize { return @sizeOf(@TypeOf(c.bogo)); }
52975528 , &[_][]const u8{
......@@ -5299,7 +5530,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
52995530 ".h:1:10: note: 'bogus.h' file not found",
53005531 });
53015532
5302 cases.add("address of number literal",
5533 ctx.objErrStage1("address of number literal",
53035534 \\const x = 3;
53045535 \\const y = &x;
53055536 \\fn foo() *const i32 { return y; }
......@@ -5308,14 +5539,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53085539 "tmp.zig:3:30: error: expected type '*const i32', found '*const comptime_int'",
53095540 });
53105541
5311 cases.add("integer overflow error",
5542 ctx.objErrStage1("integer overflow error",
53125543 \\const x : u8 = 300;
53135544 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }
53145545 , &[_][]const u8{
53155546 "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'",
53165547 });
53175548
5318 cases.add("invalid shift amount error",
5549 ctx.objErrStage1("invalid shift amount error",
53195550 \\const x : u8 = 2;
53205551 \\fn f() u16 {
53215552 \\ return x << 8;
......@@ -5325,7 +5556,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53255556 "tmp.zig:3:17: error: integer value 8 cannot be coerced to type 'u3'",
53265557 });
53275558
5328 cases.add("missing function call param",
5559 ctx.objErrStage1("missing function call param",
53295560 \\const Foo = struct {
53305561 \\ a: i32,
53315562 \\ b: i32,
......@@ -5346,6 +5577,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53465577 \\
53475578 \\fn f(foo: *const Foo, index: usize) void {
53485579 \\ const result = members[index]();
5580 \\ _ = foo;
5581 \\ _ = result;
53495582 \\}
53505583 \\
53515584 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
......@@ -5353,21 +5586,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53535586 "tmp.zig:20:34: error: expected 1 argument(s), found 0",
53545587 });
53555588
5356 cases.add("missing function name",
5589 ctx.objErrStage1("missing function name",
53575590 \\fn () void {}
53585591 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
53595592 , &[_][]const u8{
53605593 "tmp.zig:1:1: error: missing function name",
53615594 });
53625595
5363 cases.add("missing param name",
5596 ctx.objErrStage1("missing param name",
53645597 \\fn f(i32) void {}
53655598 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
53665599 , &[_][]const u8{
53675600 "tmp.zig:1:6: error: missing parameter name",
53685601 });
53695602
5370 cases.add("wrong function type",
5603 ctx.objErrStage1("wrong function type",
53715604 \\const fns = [_]fn() void { a, b, c };
53725605 \\fn a() i32 {return 0;}
53735606 \\fn b() i32 {return 1;}
......@@ -5377,7 +5610,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53775610 "tmp.zig:1:28: error: expected type 'fn() void', found 'fn() i32'",
53785611 });
53795612
5380 cases.add("extern function pointer mismatch",
5613 ctx.objErrStage1("extern function pointer mismatch",
53815614 \\const fns = [_](fn(i32)i32) { a, b, c };
53825615 \\pub fn a(x: i32) i32 {return x + 0;}
53835616 \\pub fn b(x: i32) i32 {return x + 1;}
......@@ -5388,15 +5621,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53885621 "tmp.zig:1:37: error: expected type 'fn(i32) i32', found 'fn(i32) callconv(.C) i32'",
53895622 });
53905623
5391 cases.add("colliding invalid top level functions",
5624 ctx.objErrStage1("colliding invalid top level functions",
53925625 \\fn func() bogus {}
53935626 \\fn func() bogus {}
53945627 \\export fn entry() usize { return @sizeOf(@TypeOf(func)); }
53955628 , &[_][]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",
53975631 });
53985632
5399 cases.add("non constant expression in array size",
5633 ctx.objErrStage1("non constant expression in array size",
54005634 \\const Foo = struct {
54015635 \\ y: [get()]u8,
54025636 \\};
......@@ -5409,7 +5643,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54095643 "tmp.zig:2:12: note: called from here",
54105644 });
54115645
5412 cases.add("addition with non numbers",
5646 ctx.objErrStage1("addition with non numbers",
54135647 \\const Foo = struct {
54145648 \\ field: i32,
54155649 \\};
......@@ -5420,7 +5654,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54205654 "tmp.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'",
54215655 });
54225656
5423 cases.add("division by zero",
5657 ctx.objErrStage1("division by zero",
54245658 \\const lit_int_x = 1 / 0;
54255659 \\const lit_float_x = 1.0 / 0.0;
54265660 \\const int_x = @as(u32, 1) / @as(u32, 0);
......@@ -5437,16 +5671,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54375671 "tmp.zig:4:31: error: division by zero",
54385672 });
54395673
5440 cases.add("normal string with newline",
5674 ctx.objErrStage1("normal string with newline",
54415675 \\const foo = "a
54425676 \\b";
5443 \\
5444 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
54455677 , &[_][]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'",
54475680 });
54485681
5449 cases.add("invalid comparison for function pointers",
5682 ctx.objErrStage1("invalid comparison for function pointers",
54505683 \\fn foo() void {}
54515684 \\const invalid = foo > foo;
54525685 \\
......@@ -5455,7 +5688,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54555688 "tmp.zig:2:21: error: operator not allowed for type 'fn() void'",
54565689 });
54575690
5458 cases.add("generic function instance with non-constant expression",
5691 ctx.objErrStage1("generic function instance with non-constant expression",
54595692 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }
54605693 \\fn test1(a: i32, b: i32) i32 {
54615694 \\ return foo(a, b);
......@@ -5466,7 +5699,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54665699 "tmp.zig:3:16: error: runtime value cannot be passed to comptime arg",
54675700 });
54685701
5469 cases.add("assign null to non-optional pointer",
5702 ctx.objErrStage1("assign null to non-optional pointer",
54705703 \\const a: *u8 = null;
54715704 \\
54725705 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); }
......@@ -5474,26 +5707,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54745707 "tmp.zig:1:16: error: expected type '*u8', found '(null)'",
54755708 });
54765709
5477 cases.add("indexing an array of size zero",
5710 ctx.objErrStage1("indexing an array of size zero",
54785711 \\const array = [_]u8{};
54795712 \\export fn foo() void {
54805713 \\ const pointer = &array[0];
5714 \\ _ = pointer;
54815715 \\}
54825716 , &[_][]const u8{
54835717 "tmp.zig:3:27: error: accessing a zero length array is not allowed",
54845718 });
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",
54875721 \\const array = [_]u8{};
54885722 \\export fn foo() void {
54895723 \\ var index: usize = 0;
54905724 \\ const pointer = &array[index];
5725 \\ _ = pointer;
54915726 \\}
54925727 , &[_][]const u8{
54935728 "tmp.zig:4:27: error: accessing a zero length array is not allowed",
54945729 });
54955730
5496 cases.add("compile time division by zero",
5731 ctx.objErrStage1("compile time division by zero",
54975732 \\const y = foo(0);
54985733 \\fn foo(x: u32) u32 {
54995734 \\ return 1 / x;
......@@ -5505,7 +5740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55055740 "tmp.zig:1:14: note: referenced here",
55065741 });
55075742
5508 cases.add("branch on undefined value",
5743 ctx.objErrStage1("branch on undefined value",
55095744 \\const x = if (undefined) true else false;
55105745 \\
55115746 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); }
......@@ -5513,7 +5748,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55135748 "tmp.zig:1:15: error: use of undefined value here causes undefined behavior",
55145749 });
55155750
5516 cases.add("div on undefined value",
5751 ctx.objErrStage1("div on undefined value",
55175752 \\comptime {
55185753 \\ var a: i64 = undefined;
55195754 \\ _ = a / a;
......@@ -5522,7 +5757,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55225757 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
55235758 });
55245759
5525 cases.add("div assign on undefined value",
5760 ctx.objErrStage1("div assign on undefined value",
55265761 \\comptime {
55275762 \\ var a: i64 = undefined;
55285763 \\ a /= a;
......@@ -5531,7 +5766,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55315766 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
55325767 });
55335768
5534 cases.add("mod on undefined value",
5769 ctx.objErrStage1("mod on undefined value",
55355770 \\comptime {
55365771 \\ var a: i64 = undefined;
55375772 \\ _ = a % a;
......@@ -5540,7 +5775,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55405775 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
55415776 });
55425777
5543 cases.add("mod assign on undefined value",
5778 ctx.objErrStage1("mod assign on undefined value",
55445779 \\comptime {
55455780 \\ var a: i64 = undefined;
55465781 \\ a %= a;
......@@ -5549,7 +5784,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55495784 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
55505785 });
55515786
5552 cases.add("add on undefined value",
5787 ctx.objErrStage1("add on undefined value",
55535788 \\comptime {
55545789 \\ var a: i64 = undefined;
55555790 \\ _ = a + a;
......@@ -5558,7 +5793,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55585793 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
55595794 });
55605795
5561 cases.add("add assign on undefined value",
5796 ctx.objErrStage1("add assign on undefined value",
55625797 \\comptime {
55635798 \\ var a: i64 = undefined;
55645799 \\ a += a;
......@@ -5567,7 +5802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55675802 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
55685803 });
55695804
5570 cases.add("add wrap on undefined value",
5805 ctx.objErrStage1("add wrap on undefined value",
55715806 \\comptime {
55725807 \\ var a: i64 = undefined;
55735808 \\ _ = a +% a;
......@@ -5576,7 +5811,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55765811 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
55775812 });
55785813
5579 cases.add("add wrap assign on undefined value",
5814 ctx.objErrStage1("add wrap assign on undefined value",
55805815 \\comptime {
55815816 \\ var a: i64 = undefined;
55825817 \\ a +%= a;
......@@ -5585,7 +5820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55855820 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
55865821 });
55875822
5588 cases.add("sub on undefined value",
5823 ctx.objErrStage1("sub on undefined value",
55895824 \\comptime {
55905825 \\ var a: i64 = undefined;
55915826 \\ _ = a - a;
......@@ -5594,7 +5829,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
55945829 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
55955830 });
55965831
5597 cases.add("sub assign on undefined value",
5832 ctx.objErrStage1("sub assign on undefined value",
55985833 \\comptime {
55995834 \\ var a: i64 = undefined;
56005835 \\ a -= a;
......@@ -5603,7 +5838,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56035838 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
56045839 });
56055840
5606 cases.add("sub wrap on undefined value",
5841 ctx.objErrStage1("sub wrap on undefined value",
56075842 \\comptime {
56085843 \\ var a: i64 = undefined;
56095844 \\ _ = a -% a;
......@@ -5612,7 +5847,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56125847 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
56135848 });
56145849
5615 cases.add("sub wrap assign on undefined value",
5850 ctx.objErrStage1("sub wrap assign on undefined value",
56165851 \\comptime {
56175852 \\ var a: i64 = undefined;
56185853 \\ a -%= a;
......@@ -5621,7 +5856,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56215856 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
56225857 });
56235858
5624 cases.add("mult on undefined value",
5859 ctx.objErrStage1("mult on undefined value",
56255860 \\comptime {
56265861 \\ var a: i64 = undefined;
56275862 \\ _ = a * a;
......@@ -5630,7 +5865,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56305865 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
56315866 });
56325867
5633 cases.add("mult assign on undefined value",
5868 ctx.objErrStage1("mult assign on undefined value",
56345869 \\comptime {
56355870 \\ var a: i64 = undefined;
56365871 \\ a *= a;
......@@ -5639,7 +5874,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56395874 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
56405875 });
56415876
5642 cases.add("mult wrap on undefined value",
5877 ctx.objErrStage1("mult wrap on undefined value",
56435878 \\comptime {
56445879 \\ var a: i64 = undefined;
56455880 \\ _ = a *% a;
......@@ -5648,7 +5883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56485883 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
56495884 });
56505885
5651 cases.add("mult wrap assign on undefined value",
5886 ctx.objErrStage1("mult wrap assign on undefined value",
56525887 \\comptime {
56535888 \\ var a: i64 = undefined;
56545889 \\ a *%= a;
......@@ -5657,7 +5892,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56575892 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
56585893 });
56595894
5660 cases.add("shift left on undefined value",
5895 ctx.objErrStage1("shift left on undefined value",
56615896 \\comptime {
56625897 \\ var a: i64 = undefined;
56635898 \\ _ = a << 2;
......@@ -5666,7 +5901,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56665901 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
56675902 });
56685903
5669 cases.add("shift left assign on undefined value",
5904 ctx.objErrStage1("shift left assign on undefined value",
56705905 \\comptime {
56715906 \\ var a: i64 = undefined;
56725907 \\ a <<= 2;
......@@ -5675,7 +5910,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56755910 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
56765911 });
56775912
5678 cases.add("shift right on undefined value",
5913 ctx.objErrStage1("shift right on undefined value",
56795914 \\comptime {
56805915 \\ var a: i64 = undefined;
56815916 \\ _ = a >> 2;
......@@ -5684,7 +5919,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56845919 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
56855920 });
56865921
5687 cases.add("shift left assign on undefined value",
5922 ctx.objErrStage1("shift left assign on undefined value",
56885923 \\comptime {
56895924 \\ var a: i64 = undefined;
56905925 \\ a >>= 2;
......@@ -5693,7 +5928,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56935928 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
56945929 });
56955930
5696 cases.add("bin and on undefined value",
5931 ctx.objErrStage1("bin and on undefined value",
56975932 \\comptime {
56985933 \\ var a: i64 = undefined;
56995934 \\ _ = a & a;
......@@ -5702,7 +5937,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57025937 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
57035938 });
57045939
5705 cases.add("bin and assign on undefined value",
5940 ctx.objErrStage1("bin and assign on undefined value",
57065941 \\comptime {
57075942 \\ var a: i64 = undefined;
57085943 \\ a &= a;
......@@ -5711,7 +5946,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57115946 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
57125947 });
57135948
5714 cases.add("bin or on undefined value",
5949 ctx.objErrStage1("bin or on undefined value",
57155950 \\comptime {
57165951 \\ var a: i64 = undefined;
57175952 \\ _ = a | a;
......@@ -5720,7 +5955,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57205955 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
57215956 });
57225957
5723 cases.add("bin or assign on undefined value",
5958 ctx.objErrStage1("bin or assign on undefined value",
57245959 \\comptime {
57255960 \\ var a: i64 = undefined;
57265961 \\ a |= a;
......@@ -5729,7 +5964,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57295964 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
57305965 });
57315966
5732 cases.add("bin xor on undefined value",
5967 ctx.objErrStage1("bin xor on undefined value",
57335968 \\comptime {
57345969 \\ var a: i64 = undefined;
57355970 \\ _ = a ^ a;
......@@ -5738,7 +5973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57385973 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
57395974 });
57405975
5741 cases.add("bin xor assign on undefined value",
5976 ctx.objErrStage1("bin xor assign on undefined value",
57425977 \\comptime {
57435978 \\ var a: i64 = undefined;
57445979 \\ a ^= a;
......@@ -5747,7 +5982,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57475982 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior",
57485983 });
57495984
5750 cases.add("comparison operators with undefined value",
5985 ctx.objErrStage1("comparison operators with undefined value",
57515986 \\// operator ==
57525987 \\comptime {
57535988 \\ var a: i64 = undefined;
......@@ -5793,7 +6028,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57936028 "tmp.zig:35:11: error: use of undefined value here causes undefined behavior",
57946029 });
57956030
5796 cases.add("and on undefined value",
6031 ctx.objErrStage1("and on undefined value",
57976032 \\comptime {
57986033 \\ var a: bool = undefined;
57996034 \\ _ = a and a;
......@@ -5802,7 +6037,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58026037 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
58036038 });
58046039
5805 cases.add("or on undefined value",
6040 ctx.objErrStage1("or on undefined value",
58066041 \\comptime {
58076042 \\ var a: bool = undefined;
58086043 \\ _ = a or a;
......@@ -5811,7 +6046,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58116046 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior",
58126047 });
58136048
5814 cases.add("negate on undefined value",
6049 ctx.objErrStage1("negate on undefined value",
58156050 \\comptime {
58166051 \\ var a: i64 = undefined;
58176052 \\ _ = -a;
......@@ -5820,7 +6055,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58206055 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",
58216056 });
58226057
5823 cases.add("negate wrap on undefined value",
6058 ctx.objErrStage1("negate wrap on undefined value",
58246059 \\comptime {
58256060 \\ var a: i64 = undefined;
58266061 \\ _ = -%a;
......@@ -5829,7 +6064,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58296064 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",
58306065 });
58316066
5832 cases.add("bin not on undefined value",
6067 ctx.objErrStage1("bin not on undefined value",
58336068 \\comptime {
58346069 \\ var a: i64 = undefined;
58356070 \\ _ = ~a;
......@@ -5838,7 +6073,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58386073 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",
58396074 });
58406075
5841 cases.add("bool not on undefined value",
6076 ctx.objErrStage1("bool not on undefined value",
58426077 \\comptime {
58436078 \\ var a: bool = undefined;
58446079 \\ _ = !a;
......@@ -5847,7 +6082,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58476082 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior",
58486083 });
58496084
5850 cases.add("orelse on undefined value",
6085 ctx.objErrStage1("orelse on undefined value",
58516086 \\comptime {
58526087 \\ var a: ?bool = undefined;
58536088 \\ _ = a orelse false;
......@@ -5856,16 +6091,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58566091 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",
58576092 });
58586093
5859 cases.add("catch on undefined value",
6094 ctx.objErrStage1("catch on undefined value",
58606095 \\comptime {
58616096 \\ var a: anyerror!bool = undefined;
5862 \\ _ = a catch |err| false;
6097 \\ _ = a catch false;
58636098 \\}
58646099 , &[_][]const u8{
58656100 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior",
58666101 });
58676102
5868 cases.add("deref on undefined value",
6103 ctx.objErrStage1("deref on undefined value",
58696104 \\comptime {
58706105 \\ var a: *u8 = undefined;
58716106 \\ _ = a.*;
......@@ -5874,7 +6109,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58746109 "tmp.zig:3:9: error: attempt to dereference undefined value",
58756110 });
58766111
5877 cases.add("endless loop in function evaluation",
6112 ctx.objErrStage1("endless loop in function evaluation",
58786113 \\const seventh_fib_number = fibbonaci(7);
58796114 \\fn fibbonaci(x: i32) i32 {
58806115 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
......@@ -5887,16 +6122,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58876122 "tmp.zig:6:50: note: referenced here",
58886123 });
58896124
5890 cases.add("@embedFile with bogus file",
6125 ctx.objErrStage1("@embedFile with bogus file",
58916126 \\const resource = @embedFile("bogus.txt",);
58926127 \\
58936128 \\export fn entry() usize { return @sizeOf(@TypeOf(resource)); }
58946129 , &[_][]const u8{
58956130 "tmp.zig:1:29: error: unable to find '",
5896 "bogus.txt'",
58976131 });
58986132
5899 cases.add("non-const expression in struct literal outside function",
6133 ctx.objErrStage1("non-const expression in struct literal outside function",
59006134 \\const Foo = struct {
59016135 \\ x: i32,
59026136 \\};
......@@ -5908,7 +6142,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59086142 "tmp.zig:4:21: error: unable to evaluate constant expression",
59096143 });
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",
59126146 \\const Foo = struct {
59136147 \\ x: i32,
59146148 \\};
......@@ -5925,7 +6159,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59256159 "tmp.zig:4:17: note: referenced here",
59266160 });
59276161
5928 cases.add("undeclared identifier error should mark fn as impure",
6162 ctx.objErrStage1("undeclared identifier error should mark fn as impure",
59296163 \\export fn foo() void {
59306164 \\ test_a_thing();
59316165 \\}
......@@ -5936,7 +6170,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59366170 "tmp.zig:5:5: error: use of undeclared identifier 'bad_fn_call'",
59376171 });
59386172
5939 cases.add("illegal comparison of types",
6173 ctx.objErrStage1("illegal comparison of types",
59406174 \\fn bad_eql_1(a: []u8, b: []u8) bool {
59416175 \\ return a == b;
59426176 \\}
......@@ -5955,13 +6189,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59556189 "tmp.zig:9:16: error: operator not allowed for type 'EnumWithData'",
59566190 });
59576191
5958 cases.add("non-const switch number literal",
6192 ctx.objErrStage1("non-const switch number literal",
59596193 \\export fn foo() void {
59606194 \\ const x = switch (bar()) {
59616195 \\ 1, 2 => 1,
59626196 \\ 3, 4 => 2,
59636197 \\ else => 3,
59646198 \\ };
6199 \\ _ = x;
59656200 \\}
59666201 \\fn bar() i32 {
59676202 \\ return 2;
......@@ -5970,7 +6205,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59706205 "tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'",
59716206 });
59726207
5973 cases.add("atomic orderings of cmpxchg - failure stricter than success",
6208 ctx.objErrStage1("atomic orderings of cmpxchg - failure stricter than success",
59746209 \\const AtomicOrder = @import("std").builtin.AtomicOrder;
59756210 \\export fn f() void {
59766211 \\ var x: i32 = 1234;
......@@ -5980,7 +6215,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59806215 "tmp.zig:4:81: error: failure atomic ordering must be no stricter than success",
59816216 });
59826217
5983 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
6218 ctx.objErrStage1("atomic orderings of cmpxchg - success Monotonic or stricter",
59846219 \\const AtomicOrder = @import("std").builtin.AtomicOrder;
59856220 \\export fn f() void {
59866221 \\ var x: i32 = 1234;
......@@ -5990,7 +6225,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59906225 "tmp.zig:4:58: error: success atomic ordering must be Monotonic or stricter",
59916226 });
59926227
5993 cases.add("negation overflow in function evaluation",
6228 ctx.objErrStage1("negation overflow in function evaluation",
59946229 \\const y = neg(-128);
59956230 \\fn neg(x: i8) i8 {
59966231 \\ return -x;
......@@ -6002,7 +6237,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60026237 "tmp.zig:1:14: note: referenced here",
60036238 });
60046239
6005 cases.add("add overflow in function evaluation",
6240 ctx.objErrStage1("add overflow in function evaluation",
60066241 \\const y = add(65530, 10);
60076242 \\fn add(a: u16, b: u16) u16 {
60086243 \\ return a + b;
......@@ -6014,7 +6249,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60146249 "tmp.zig:1:14: note: referenced here",
60156250 });
60166251
6017 cases.add("sub overflow in function evaluation",
6252 ctx.objErrStage1("sub overflow in function evaluation",
60186253 \\const y = sub(10, 20);
60196254 \\fn sub(a: u16, b: u16) u16 {
60206255 \\ return a - b;
......@@ -6026,7 +6261,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60266261 "tmp.zig:1:14: note: referenced here",
60276262 });
60286263
6029 cases.add("mul overflow in function evaluation",
6264 ctx.objErrStage1("mul overflow in function evaluation",
60306265 \\const y = mul(300, 6000);
60316266 \\fn mul(a: u16, b: u16) u16 {
60326267 \\ return a * b;
......@@ -6038,7 +6273,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60386273 "tmp.zig:1:14: note: referenced here",
60396274 });
60406275
6041 cases.add("truncate sign mismatch",
6276 ctx.objErrStage1("truncate sign mismatch",
60426277 \\export fn entry1() i8 {
60436278 \\ var x: u32 = 10;
60446279 \\ return @truncate(i8, x);
......@@ -6062,7 +6297,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60626297 "tmp.zig:15:26: error: expected unsigned integer type, found 'i32'",
60636298 });
60646299
6065 cases.add("try in function with non error return type",
6300 ctx.objErrStage1("try in function with non error return type",
60666301 \\export fn f() void {
60676302 \\ try something();
60686303 \\}
......@@ -6071,7 +6306,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60716306 "tmp.zig:2:5: error: expected type 'void', found 'anyerror'",
60726307 });
60736308
6074 cases.add("invalid pointer for var type",
6309 ctx.objErrStage1("invalid pointer for var type",
60756310 \\extern fn ext() usize;
60766311 \\var bytes: [ext()]u8 = undefined;
60776312 \\export fn f() void {
......@@ -6083,7 +6318,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60836318 "tmp.zig:2:13: error: unable to evaluate constant expression",
60846319 });
60856320
6086 cases.add("export function with comptime parameter",
6321 ctx.objErrStage1("export function with comptime parameter",
60876322 \\export fn foo(comptime x: i32, y: i32) i32{
60886323 \\ return x + y;
60896324 \\}
......@@ -6091,7 +6326,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60916326 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
60926327 });
60936328
6094 cases.add("extern function with comptime parameter",
6329 ctx.objErrStage1("extern function with comptime parameter",
60956330 \\extern fn foo(comptime x: i32, y: i32) i32;
60966331 \\fn f() i32 {
60976332 \\ return foo(1, 2);
......@@ -6101,7 +6336,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61016336 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
61026337 });
61036338
6104 cases.add("non-pure function returns type",
6339 ctx.objErrStage1("non-pure function returns type",
61056340 \\var a: u32 = 0;
61066341 \\pub fn List(comptime T: type) type {
61076342 \\ a += 1;
......@@ -6125,7 +6360,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61256360 "tmp.zig:16:19: note: referenced here",
61266361 });
61276362
6128 cases.add("bogus method call on slice",
6363 ctx.objErrStage1("bogus method call on slice",
61296364 \\var self = "aoeu";
61306365 \\fn f(m: []const u8) void {
61316366 \\ m.copy(u8, self[0..], m);
......@@ -6135,9 +6370,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61356370 "tmp.zig:3:6: error: no member named 'copy' in '[]const u8'",
61366371 });
61376372
6138 cases.add("wrong number of arguments for method fn call",
6373 ctx.objErrStage1("wrong number of arguments for method fn call",
61396374 \\const Foo = struct {
6140 \\ fn method(self: *const Foo, a: i32) void {}
6375 \\ fn method(self: *const Foo, a: i32) void {_ = self; _ = a;}
61416376 \\};
61426377 \\fn f(foo: *const Foo) void {
61436378 \\
......@@ -6148,7 +6383,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61486383 "tmp.zig:6:15: error: expected 2 argument(s), found 3",
61496384 });
61506385
6151 cases.add("assign through constant pointer",
6386 ctx.objErrStage1("assign through constant pointer",
61526387 \\export fn f() void {
61536388 \\ var cstr = "Hat";
61546389 \\ cstr[0] = 'W';
......@@ -6157,7 +6392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61576392 "tmp.zig:3:13: error: cannot assign to constant",
61586393 });
61596394
6160 cases.add("assign through constant slice",
6395 ctx.objErrStage1("assign through constant slice",
61616396 \\export fn f() void {
61626397 \\ var cstr: []const u8 = "Hat";
61636398 \\ cstr[0] = 'W';
......@@ -6166,13 +6401,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61666401 "tmp.zig:3:13: error: cannot assign to constant",
61676402 });
61686403
6169 cases.add("main function with bogus args type",
6170 \\pub fn main(args: [][]bogus) !void {}
6404 ctx.objErrStage1("main function with bogus args type",
6405 \\pub fn main(args: [][]bogus) !void {_ = args;}
61716406 , &[_][]const u8{
61726407 "tmp.zig:1:23: error: use of undeclared identifier 'bogus'",
61736408 });
61746409
6175 cases.add("misspelled type with pointer only reference",
6410 ctx.objErrStage1("misspelled type with pointer only reference",
61766411 \\const JasonHM = u8;
61776412 \\const JasonList = *JsonNode;
61786413 \\
......@@ -6200,6 +6435,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62006435 \\ var jll: JasonList = undefined;
62016436 \\ jll.init(1234);
62026437 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
6438 \\ _ = jd;
62036439 \\}
62046440 \\
62056441 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
......@@ -6207,7 +6443,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62076443 "tmp.zig:5:16: error: use of undeclared identifier 'JsonList'",
62086444 });
62096445
6210 cases.add("method call with first arg type primitive",
6446 ctx.objErrStage1("method call with first arg type primitive",
62116447 \\const Foo = struct {
62126448 \\ x: i32,
62136449 \\
......@@ -6227,7 +6463,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62276463 "tmp.zig:14:5: error: expected type 'i32', found 'Foo'",
62286464 });
62296465
6230 cases.add("method call with first arg type wrong container",
6466 ctx.objErrStage1("method call with first arg type wrong container",
62316467 \\pub const List = struct {
62326468 \\ len: usize,
62336469 \\ allocator: *Allocator,
......@@ -6256,7 +6492,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62566492 "tmp.zig:23:5: error: expected type '*Allocator', found '*List'",
62576493 });
62586494
6259 cases.add("binary not on number literal",
6495 ctx.objErrStage1("binary not on number literal",
62606496 \\const TINY_QUANTUM_SHIFT = 4;
62616497 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
62626498 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
......@@ -6266,8 +6502,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62666502 "tmp.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'",
62676503 });
62686504
6269 cases.addCase(x: {
6270 const tc = cases.create("multiple files with private function error",
6505 {
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(
62716514 \\const foo = @import("foo.zig",);
62726515 \\
62736516 \\export fn callPrivFunction() void {
......@@ -6277,16 +6520,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62776520 "tmp.zig:4:8: error: 'privateFunction' is private",
62786521 "foo.zig:1:1: note: declared here",
62796522 });
6523 }
62806524
6281 tc.addSourceFile("foo.zig",
6282 \\fn privateFunction() void { }
6283 );
6525 {
6526 const case = ctx.obj("multiple files with private member instance function (canonical invocation) error", .{});
6527 case.backend = .stage1;
62846528
6285 break :x tc;
6286 });
6529 case.addSourceFile("foo.zig",
6530 \\pub const Foo = struct {
6531 \\ fn privateFunction(self: *Foo) void { _ = self; }
6532 \\};
6533 );
62876534
6288 cases.addCase(x: {
6289 const tc = cases.create("multiple files with private member instance function (canonical invocation) error",
6535 case.addError(
62906536 \\const Foo = @import("foo.zig",).Foo;
62916537 \\
62926538 \\export fn callPrivFunction() void {
......@@ -6297,18 +6543,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
62976543 "tmp.zig:5:8: error: 'privateFunction' is private",
62986544 "foo.zig:2:5: note: declared here",
62996545 });
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",
63026553 \\pub const Foo = struct {
6303 \\ fn privateFunction(self: *Foo) void { }
6554 \\ fn privateFunction(self: *Foo) void { _ = self; }
63046555 \\};
63056556 );
63066557
6307 break :x tc;
6308 });
6309
6310 cases.addCase(x: {
6311 const tc = cases.create("multiple files with private member instance function error",
6558 case.addError(
63126559 \\const Foo = @import("foo.zig",).Foo;
63136560 \\
63146561 \\export fn callPrivFunction() void {
......@@ -6319,17 +6566,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63196566 "tmp.zig:5:8: error: 'privateFunction' is private",
63206567 "foo.zig:2:5: note: declared here",
63216568 });
6569 }
63226570
6323 tc.addSourceFile("foo.zig",
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",
6571 ctx.objErrStage1("container init with non-type",
63336572 \\const zero: i32 = 0;
63346573 \\const a = zero{1};
63356574 \\
......@@ -6338,7 +6577,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63386577 "tmp.zig:2:11: error: expected type 'type', found 'i32'",
63396578 });
63406579
6341 cases.add("assign to constant field",
6580 ctx.objErrStage1("assign to constant field",
63426581 \\const Foo = struct {
63436582 \\ field: i32,
63446583 \\};
......@@ -6350,7 +6589,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63506589 "tmp.zig:6:15: error: cannot assign to constant",
63516590 });
63526591
6353 cases.add("return from defer expression",
6592 ctx.objErrStage1("return from defer expression",
63546593 \\pub fn testTrickyDefer() !void {
63556594 \\ defer canFail() catch {};
63566595 \\
......@@ -6367,32 +6606,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63676606 \\
63686607 \\export fn entry() usize { return @sizeOf(@TypeOf(testTrickyDefer)); }
63696608 , &[_][]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",
63716610 });
63726611
6373 cases.add("assign too big number to u16",
6612 ctx.objErrStage1("assign too big number to u16",
63746613 \\export fn foo() void {
63756614 \\ var vga_mem: u16 = 0xB8000;
6615 \\ _ = vga_mem;
63766616 \\}
63776617 , &[_][]const u8{
63786618 "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'",
63796619 });
63806620
6381 cases.add("global variable alignment non power of 2",
6621 ctx.objErrStage1("global variable alignment non power of 2",
63826622 \\const some_data: [100]u8 align(3) = undefined;
63836623 \\export fn entry() usize { return @sizeOf(@TypeOf(some_data)); }
63846624 , &[_][]const u8{
63856625 "tmp.zig:1:32: error: alignment value 3 is not a power of 2",
63866626 });
63876627
6388 cases.add("function alignment non power of 2",
6628 ctx.objErrStage1("function alignment non power of 2",
63896629 \\extern fn foo() align(3) void;
63906630 \\export fn entry() void { return foo(); }
63916631 , &[_][]const u8{
63926632 "tmp.zig:1:23: error: alignment value 3 is not a power of 2",
63936633 });
63946634
6395 cases.add("compile log",
6635 ctx.objErrStage1("compile log",
63966636 \\export fn foo() void {
63976637 \\ comptime bar(12, "hi",);
63986638 \\}
......@@ -6407,7 +6647,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64076647 "tmp.zig:7:5: error: found compile log statement",
64086648 });
64096649
6410 cases.add("casting bit offset pointer to regular pointer",
6650 ctx.objErrStage1("casting bit offset pointer to regular pointer",
64116651 \\const BitField = packed struct {
64126652 \\ a: u3,
64136653 \\ b: u3,
......@@ -6427,7 +6667,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64276667 "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",
64286668 });
64296669
6430 cases.add("referring to a struct that is invalid",
6670 ctx.objErrStage1("referring to a struct that is invalid",
64316671 \\const UsbDeviceRequest = struct {
64326672 \\ Type: u8,
64336673 \\};
......@@ -6444,7 +6684,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64446684 "tmp.zig:6:20: note: referenced here",
64456685 });
64466686
6447 cases.add("control flow uses comptime var at runtime",
6687 ctx.objErrStage1("control flow uses comptime var at runtime",
64486688 \\export fn foo() void {
64496689 \\ comptime var i = 0;
64506690 \\ while (i < 5) : (i += 1) {
......@@ -6458,7 +6698,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64586698 "tmp.zig:3:24: note: compile-time variable assigned here",
64596699 });
64606700
6461 cases.add("ignored return value",
6701 ctx.objErrStage1("ignored return value",
64626702 \\export fn foo() void {
64636703 \\ bar();
64646704 \\}
......@@ -6467,7 +6707,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64676707 "tmp.zig:2:8: error: expression value is ignored",
64686708 });
64696709
6470 cases.add("ignored assert-err-ok return value",
6710 ctx.objErrStage1("ignored assert-err-ok return value",
64716711 \\export fn foo() void {
64726712 \\ bar() catch unreachable;
64736713 \\}
......@@ -6476,7 +6716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64766716 "tmp.zig:2:11: error: expression value is ignored",
64776717 });
64786718
6479 cases.add("ignored statement value",
6719 ctx.objErrStage1("ignored statement value",
64806720 \\export fn foo() void {
64816721 \\ 1;
64826722 \\}
......@@ -6484,7 +6724,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64846724 "tmp.zig:2:5: error: expression value is ignored",
64856725 });
64866726
6487 cases.add("ignored comptime statement value",
6727 ctx.objErrStage1("ignored comptime statement value",
64886728 \\export fn foo() void {
64896729 \\ comptime {1;}
64906730 \\}
......@@ -6492,7 +6732,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64926732 "tmp.zig:2:15: error: expression value is ignored",
64936733 });
64946734
6495 cases.add("ignored comptime value",
6735 ctx.objErrStage1("ignored comptime value",
64966736 \\export fn foo() void {
64976737 \\ comptime 1;
64986738 \\}
......@@ -6500,7 +6740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65006740 "tmp.zig:2:5: error: expression value is ignored",
65016741 });
65026742
6503 cases.add("ignored defered statement value",
6743 ctx.objErrStage1("ignored defered statement value",
65046744 \\export fn foo() void {
65056745 \\ defer {1;}
65066746 \\}
......@@ -6508,7 +6748,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65086748 "tmp.zig:2:12: error: expression value is ignored",
65096749 });
65106750
6511 cases.add("ignored defered function call",
6751 ctx.objErrStage1("ignored defered function call",
65126752 \\export fn foo() void {
65136753 \\ defer bar();
65146754 \\}
......@@ -6517,7 +6757,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65176757 "tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if`",
65186758 });
65196759
6520 cases.add("dereference an array",
6760 ctx.objErrStage1("dereference an array",
65216761 \\var s_buffer: [10]u8 = undefined;
65226762 \\pub fn pass(in: []u8) []u8 {
65236763 \\ var out = &s_buffer;
......@@ -6530,13 +6770,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65306770 "tmp.zig:4:10: error: attempt to dereference non-pointer type '[10]u8'",
65316771 });
65326772
6533 cases.add("pass const ptr to mutable ptr fn",
6773 ctx.objErrStage1("pass const ptr to mutable ptr fn",
65346774 \\fn foo() bool {
65356775 \\ const a = @as([]const u8, "a",);
65366776 \\ const b = &a;
65376777 \\ return ptrEql(b, b);
65386778 \\}
65396779 \\fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
6780 \\ _ = a; _ = b;
65406781 \\ return true;
65416782 \\}
65426783 \\
......@@ -6545,8 +6786,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65456786 "tmp.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'",
65466787 });
65476788
6548 cases.addCase(x: {
6549 const tc = cases.create("export collision",
6789 {
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(
65506799 \\const foo = @import("foo.zig",);
65516800 \\
65526801 \\export fn bar() usize {
......@@ -6556,18 +6805,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65566805 "foo.zig:1:1: error: exported symbol collision: 'bar'",
65576806 "tmp.zig:3:1: note: other symbol here",
65586807 });
6808 }
65596809
6560 tc.addSourceFile("foo.zig",
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",
6810 ctx.objErrStage1("implicit cast from array to mutable slice",
65696811 \\var global_array: [10]i32 = undefined;
6570 \\fn foo(param: []i32) void {}
6812 \\fn foo(param: []i32) void {_ = param;}
65716813 \\export fn entry() void {
65726814 \\ foo(global_array);
65736815 \\}
......@@ -6575,7 +6817,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65756817 "tmp.zig:4:9: error: expected type '[]i32', found '[10]i32'",
65766818 });
65776819
6578 cases.add("ptrcast to non-pointer",
6820 ctx.objErrStage1("ptrcast to non-pointer",
65796821 \\export fn entry(a: *i32) usize {
65806822 \\ return @ptrCast(usize, a);
65816823 \\}
......@@ -6583,7 +6825,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65836825 "tmp.zig:2:21: error: expected pointer, found 'usize'",
65846826 });
65856827
6586 cases.add("asm at compile time",
6828 ctx.objErrStage1("asm at compile time",
65876829 \\comptime {
65886830 \\ doSomeAsm();
65896831 \\}
......@@ -6599,25 +6841,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
65996841 "tmp.zig:6:5: error: unable to evaluate constant expression",
66006842 });
66016843
6602 cases.add("invalid member of builtin enum",
6844 ctx.objErrStage1("invalid member of builtin enum",
66036845 \\const builtin = @import("std").builtin;
66046846 \\export fn entry() void {
66056847 \\ const foo = builtin.Mode.x86;
6848 \\ _ = foo;
66066849 \\}
66076850 , &[_][]const u8{
66086851 "tmp.zig:3:29: error: container 'std.builtin.Mode' has no member called 'x86'",
66096852 });
66106853
6611 cases.add("int to ptr of 0 bits",
6854 ctx.objErrStage1("int to ptr of 0 bits",
66126855 \\export fn foo() void {
66136856 \\ var x: usize = 0x1000;
66146857 \\ var y: *void = @intToPtr(*void, x);
6858 \\ _ = y;
66156859 \\}
66166860 , &[_][]const u8{
66176861 "tmp.zig:3:30: error: type '*void' has 0 bits and cannot store information",
66186862 });
66196863
6620 cases.add("@fieldParentPtr - non struct",
6864 ctx.objErrStage1("@fieldParentPtr - non struct",
66216865 \\const Foo = i32;
66226866 \\export fn foo(a: *i32) *Foo {
66236867 \\ return @fieldParentPtr(Foo, "a", a);
......@@ -6626,7 +6870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66266870 "tmp.zig:3:28: error: expected struct type, found 'i32'",
66276871 });
66286872
6629 cases.add("@fieldParentPtr - bad field name",
6873 ctx.objErrStage1("@fieldParentPtr - bad field name",
66306874 \\const Foo = extern struct {
66316875 \\ derp: i32,
66326876 \\};
......@@ -6637,7 +6881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66376881 "tmp.zig:5:33: error: struct 'Foo' has no field 'a'",
66386882 });
66396883
6640 cases.add("@fieldParentPtr - field pointer is not pointer",
6884 ctx.objErrStage1("@fieldParentPtr - field pointer is not pointer",
66416885 \\const Foo = extern struct {
66426886 \\ a: i32,
66436887 \\};
......@@ -6648,7 +6892,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66486892 "tmp.zig:5:38: error: expected pointer, found 'i32'",
66496893 });
66506894
6651 cases.add("@fieldParentPtr - comptime field ptr not based on struct",
6895 ctx.objErrStage1("@fieldParentPtr - comptime field ptr not based on struct",
66526896 \\const Foo = struct {
66536897 \\ a: i32,
66546898 \\ b: i32,
......@@ -6658,12 +6902,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66586902 \\comptime {
66596903 \\ const field_ptr = @intToPtr(*i32, 0x1234);
66606904 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);
6905 \\ _ = another_foo_ptr;
66616906 \\}
66626907 , &[_][]const u8{
66636908 "tmp.zig:9:55: error: pointer value not based on parent struct",
66646909 });
66656910
6666 cases.add("@fieldParentPtr - comptime wrong field index",
6911 ctx.objErrStage1("@fieldParentPtr - comptime wrong field index",
66676912 \\const Foo = struct {
66686913 \\ a: i32,
66696914 \\ b: i32,
......@@ -6672,12 +6917,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66726917 \\
66736918 \\comptime {
66746919 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
6920 \\ _ = another_foo_ptr;
66756921 \\}
66766922 , &[_][]const u8{
66776923 "tmp.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'",
66786924 });
66796925
6680 cases.add("@offsetOf - non struct",
6926 ctx.objErrStage1("@offsetOf - non struct",
66816927 \\const Foo = i32;
66826928 \\export fn foo() usize {
66836929 \\ return @offsetOf(Foo, "a",);
......@@ -6686,7 +6932,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66866932 "tmp.zig:3:22: error: expected struct type, found 'i32'",
66876933 });
66886934
6689 cases.add("@offsetOf - bad field name",
6935 ctx.objErrStage1("@offsetOf - bad field name",
66906936 \\const Foo = struct {
66916937 \\ derp: i32,
66926938 \\};
......@@ -6697,20 +6943,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
66976943 "tmp.zig:5:27: error: struct 'Foo' has no field 'a'",
66986944 });
66996945
6700 cases.addExe("missing main fn in executable",
6946 ctx.exeErrStage1("missing main fn in executable",
67016947 \\
67026948 , &[_][]const u8{
67036949 "error: root source file has no member called 'main'",
67046950 });
67056951
6706 cases.addExe("private main fn",
6952 ctx.exeErrStage1("private main fn",
67076953 \\fn main() void {}
67086954 , &[_][]const u8{
67096955 "error: 'main' is private",
67106956 "tmp.zig:1:1: note: declared here",
67116957 });
67126958
6713 cases.add("setting a section on a local variable",
6959 ctx.objErrStage1("setting a section on a local variable",
67146960 \\export fn entry() i32 {
67156961 \\ var foo: i32 linksection(".text2") = 1234;
67166962 \\ return foo;
......@@ -6719,7 +6965,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
67196965 "tmp.zig:2:30: error: cannot set section of local variable 'foo'",
67206966 });
67216967
6722 cases.add("inner struct member shadowing outer struct member",
6968 ctx.objErrStage1("inner struct member shadowing outer struct member",
67236969 \\fn A() type {
67246970 \\ return struct {
67256971 \\ b: B(),
......@@ -6741,10 +6987,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
67416987 \\}
67426988 , &[_][]const u8{
67436989 "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",
67456991 });
67466992
6747 cases.add("while expected bool, got optional",
6993 ctx.objErrStage1("while expected bool, got optional",
67486994 \\export fn foo() void {
67496995 \\ while (bar()) {}
67506996 \\}
......@@ -6753,7 +6999,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
67536999 "tmp.zig:2:15: error: expected type 'bool', found '?i32'",
67547000 });
67557001
6756 cases.add("while expected bool, got error union",
7002 ctx.objErrStage1("while expected bool, got error union",
67577003 \\export fn foo() void {
67587004 \\ while (bar()) {}
67597005 \\}
......@@ -6762,36 +7008,36 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
67627008 "tmp.zig:2:15: error: expected type 'bool', found 'anyerror!i32'",
67637009 });
67647010
6765 cases.add("while expected optional, got bool",
7011 ctx.objErrStage1("while expected optional, got bool",
67667012 \\export fn foo() void {
6767 \\ while (bar()) |x| {}
7013 \\ while (bar()) |x| {_ = x;}
67687014 \\}
67697015 \\fn bar() bool { return true; }
67707016 , &[_][]const u8{
67717017 "tmp.zig:2:15: error: expected optional type, found 'bool'",
67727018 });
67737019
6774 cases.add("while expected optional, got error union",
7020 ctx.objErrStage1("while expected optional, got error union",
67757021 \\export fn foo() void {
6776 \\ while (bar()) |x| {}
7022 \\ while (bar()) |x| {_ = x;}
67777023 \\}
67787024 \\fn bar() anyerror!i32 { return 1; }
67797025 , &[_][]const u8{
67807026 "tmp.zig:2:15: error: expected optional type, found 'anyerror!i32'",
67817027 });
67827028
6783 cases.add("while expected error union, got bool",
7029 ctx.objErrStage1("while expected error union, got bool",
67847030 \\export fn foo() void {
6785 \\ while (bar()) |x| {} else |err| {}
7031 \\ while (bar()) |x| {_ = x;} else |err| {_ = err;}
67867032 \\}
67877033 \\fn bar() bool { return true; }
67887034 , &[_][]const u8{
67897035 "tmp.zig:2:15: error: expected error union type, found 'bool'",
67907036 });
67917037
6792 cases.add("while expected error union, got optional",
7038 ctx.objErrStage1("while expected error union, got optional",
67937039 \\export fn foo() void {
6794 \\ while (bar()) |x| {} else |err| {}
7040 \\ while (bar()) |x| {_ = x;} else |err| {_ = err;}
67957041 \\}
67967042 \\fn bar() ?i32 { return 1; }
67977043 , &[_][]const u8{
......@@ -6799,7 +7045,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
67997045 });
68007046
68017047 // 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",
68037049 // \\export fn foo() void {
68047050 // \\ bar();
68057051 // \\}
......@@ -6816,7 +7062,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
68167062 // "tmp.zig:4:1: error: unable to inline function",
68177063 //});
68187064
6819 //cases.add("save reference to inline function",
7065 //ctx.objErrStage1("save reference to inline function",
68207066 // \\export fn foo() void {
68217067 // \\ quux(@ptrToInt(bar));
68227068 // \\}
......@@ -6826,7 +7072,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
68267072 // "tmp.zig:4:1: error: unable to inline function",
68277073 //});
68287074
6829 cases.add("signed integer division",
7075 ctx.objErrStage1("signed integer division",
68307076 \\export fn foo(a: i32, b: i32) i32 {
68317077 \\ return a / b;
68327078 \\}
......@@ -6834,7 +7080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
68347080 "tmp.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact",
68357081 });
68367082
6837 cases.add("signed integer remainder division",
7083 ctx.objErrStage1("signed integer remainder division",
68387084 \\export fn foo(a: i32, b: i32) i32 {
68397085 \\ return a % b;
68407086 \\}
......@@ -6842,27 +7088,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
68427088 "tmp.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod",
68437089 });
68447090
6845 cases.add("compile-time division by zero",
7091 ctx.objErrStage1("compile-time division by zero",
68467092 \\comptime {
68477093 \\ const a: i32 = 1;
68487094 \\ const b: i32 = 0;
68497095 \\ const c = a / b;
7096 \\ _ = c;
68507097 \\}
68517098 , &[_][]const u8{
68527099 "tmp.zig:4:17: error: division by zero",
68537100 });
68547101
6855 cases.add("compile-time remainder division by zero",
7102 ctx.objErrStage1("compile-time remainder division by zero",
68567103 \\comptime {
68577104 \\ const a: i32 = 1;
68587105 \\ const b: i32 = 0;
68597106 \\ const c = a % b;
7107 \\ _ = c;
68607108 \\}
68617109 , &[_][]const u8{
68627110 "tmp.zig:4:17: error: division by zero",
68637111 });
68647112
6865 cases.add("@setRuntimeSafety twice for same scope",
7113 ctx.objErrStage1("@setRuntimeSafety twice for same scope",
68667114 \\export fn foo() void {
68677115 \\ @setRuntimeSafety(false);
68687116 \\ @setRuntimeSafety(false);
......@@ -6872,7 +7120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
68727120 "tmp.zig:2:5: note: first set here",
68737121 });
68747122
6875 cases.add("@setFloatMode twice for same scope",
7123 ctx.objErrStage1("@setFloatMode twice for same scope",
68767124 \\export fn foo() void {
68777125 \\ @setFloatMode(@import("std").builtin.FloatMode.Optimized);
68787126 \\ @setFloatMode(@import("std").builtin.FloatMode.Optimized);
......@@ -6882,15 +7130,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
68827130 "tmp.zig:2:5: note: first set here",
68837131 });
68847132
6885 cases.add("array access of type",
7133 ctx.objErrStage1("array access of type",
68867134 \\export fn foo() void {
68877135 \\ var b: u8[40] = undefined;
7136 \\ _ = b;
68887137 \\}
68897138 , &[_][]const u8{
68907139 "tmp.zig:2:14: error: array access of non-array type 'type'",
68917140 });
68927141
6893 cases.add("cannot break out of defer expression",
7142 ctx.objErrStage1("cannot break out of defer expression",
68947143 \\export fn foo() void {
68957144 \\ while (true) {
68967145 \\ defer {
......@@ -6902,7 +7151,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69027151 "tmp.zig:4:13: error: cannot break out of defer expression",
69037152 });
69047153
6905 cases.add("cannot continue out of defer expression",
7154 ctx.objErrStage1("cannot continue out of defer expression",
69067155 \\export fn foo() void {
69077156 \\ while (true) {
69087157 \\ defer {
......@@ -6914,11 +7163,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69147163 "tmp.zig:4:13: error: cannot continue out of defer expression",
69157164 });
69167165
6917 cases.add("calling a generic function only known at runtime",
7166 ctx.objErrStage1("calling a generic function only known at runtime",
69187167 \\var foos = [_]fn(anytype) void { foo1, foo2 };
69197168 \\
6920 \\fn foo1(arg: anytype) void {}
6921 \\fn foo2(arg: anytype) void {}
7169 \\fn foo1(arg: anytype) void {_ = arg;}
7170 \\fn foo2(arg: anytype) void {_ = arg;}
69227171 \\
69237172 \\pub fn main() !void {
69247173 \\ foos[0](true);
......@@ -6927,7 +7176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69277176 "tmp.zig:7:9: error: calling a generic function requires compile-time known function value",
69287177 });
69297178
6930 cases.add("@compileError shows traceback of references that caused it",
7179 ctx.objErrStage1("@compileError shows traceback of references that caused it",
69317180 \\const foo = @compileError("aoeu",);
69327181 \\
69337182 \\const bar = baz + foo;
......@@ -6942,23 +7191,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69427191 "tmp.zig:7:12: note: referenced here",
69437192 });
69447193
6945 cases.add("float literal too large error",
7194 ctx.objErrStage1("float literal too large error",
69467195 \\comptime {
69477196 \\ const a = 0x1.0p18495;
7197 \\ _ = a;
69487198 \\}
69497199 , &[_][]const u8{
69507200 "tmp.zig:2:15: error: float literal out of range of any type",
69517201 });
69527202
6953 cases.add("float literal too small error (denormal)",
7203 ctx.objErrStage1("float literal too small error (denormal)",
69547204 \\comptime {
69557205 \\ const a = 0x1.0p-19000;
7206 \\ _ = a;
69567207 \\}
69577208 , &[_][]const u8{
69587209 "tmp.zig:2:15: error: float literal out of range of any type",
69597210 });
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",
69627213 \\export fn entry() i32 {
69637214 \\ return @as(i32, 12.34);
69647215 \\}
......@@ -6966,7 +7217,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69667217 "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
69677218 });
69687219
6969 cases.add("non pointer given to @ptrToInt",
7220 ctx.objErrStage1("non pointer given to @ptrToInt",
69707221 \\export fn entry(x: i32) usize {
69717222 \\ return @ptrToInt(x);
69727223 \\}
......@@ -6974,23 +7225,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69747225 "tmp.zig:2:22: error: expected pointer, found 'i32'",
69757226 });
69767227
6977 cases.add("@shlExact shifts out 1 bits",
7228 ctx.objErrStage1("@shlExact shifts out 1 bits",
69787229 \\comptime {
69797230 \\ const x = @shlExact(@as(u8, 0b01010101), 2);
7231 \\ _ = x;
69807232 \\}
69817233 , &[_][]const u8{
69827234 "tmp.zig:2:15: error: operation caused overflow",
69837235 });
69847236
6985 cases.add("@shrExact shifts out 1 bits",
7237 ctx.objErrStage1("@shrExact shifts out 1 bits",
69867238 \\comptime {
69877239 \\ const x = @shrExact(@as(u8, 0b10101010), 2);
7240 \\ _ = x;
69887241 \\}
69897242 , &[_][]const u8{
69907243 "tmp.zig:2:15: error: exact shift shifted out 1 bits",
69917244 });
69927245
6993 cases.add("shifting without int type or comptime known",
7246 ctx.objErrStage1("shifting without int type or comptime known",
69947247 \\export fn entry(x: u8) u8 {
69957248 \\ return 0x11 << x;
69967249 \\}
......@@ -6998,7 +7251,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
69987251 "tmp.zig:2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be compile-time known",
69997252 });
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",
70027255 \\export fn entry(x: u8, y: u8) u8 {
70037256 \\ return x << y;
70047257 \\}
......@@ -7006,16 +7259,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70067259 "tmp.zig:2:17: error: expected type 'u3', found 'u8'",
70077260 });
70087261
7009 cases.add("globally shadowing a primitive type",
7262 ctx.objErrStage1("globally shadowing a primitive type",
70107263 \\const u16 = u8;
70117264 \\export fn entry() void {
70127265 \\ const a: u16 = 300;
7266 \\ _ = a;
70137267 \\}
70147268 , &[_][]const u8{
70157269 "tmp.zig:1:1: error: declaration shadows primitive type 'u16'",
70167270 });
70177271
7018 cases.add("implicitly increasing pointer alignment",
7272 ctx.objErrStage1("implicitly increasing pointer alignment",
70197273 \\const Foo = packed struct {
70207274 \\ a: u8,
70217275 \\ b: u32,
......@@ -7033,7 +7287,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70337287 "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'",
70347288 });
70357289
7036 cases.add("implicitly increasing slice alignment",
7290 ctx.objErrStage1("implicitly increasing slice alignment",
70377291 \\const Foo = packed struct {
70387292 \\ a: u8,
70397293 \\ b: u32,
......@@ -7054,7 +7308,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70547308 "tmp.zig:9:26: note: '*[1]u32' has alignment 4",
70557309 });
70567310
7057 cases.add("increase pointer alignment in @ptrCast",
7311 ctx.objErrStage1("increase pointer alignment in @ptrCast",
70587312 \\export fn entry() u32 {
70597313 \\ var bytes: [4]u8 = [_]u8{0x01, 0x02, 0x03, 0x04};
70607314 \\ const ptr = @ptrCast(*u32, &bytes[0]);
......@@ -7066,7 +7320,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70667320 "tmp.zig:3:26: note: '*u32' has alignment 4",
70677321 });
70687322
7069 cases.add("@alignCast expects pointer or slice",
7323 ctx.objErrStage1("@alignCast expects pointer or slice",
70707324 \\export fn entry() void {
70717325 \\ @alignCast(4, @as(u32, 3));
70727326 \\}
......@@ -7074,7 +7328,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70747328 "tmp.zig:2:19: error: expected pointer or slice, found 'u32'",
70757329 });
70767330
7077 cases.add("passing an under-aligned function pointer",
7331 ctx.objErrStage1("passing an under-aligned function pointer",
70787332 \\export fn entry() void {
70797333 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
70807334 \\}
......@@ -7086,7 +7340,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70867340 "tmp.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'",
70877341 });
70887342
7089 cases.add("passing a not-aligned-enough pointer to cmpxchg",
7343 ctx.objErrStage1("passing a not-aligned-enough pointer to cmpxchg",
70907344 \\const AtomicOrder = @import("std").builtin.AtomicOrder;
70917345 \\export fn entry() bool {
70927346 \\ var x: i32 align(1) = 1234;
......@@ -7097,15 +7351,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
70977351 "tmp.zig:4:32: error: expected type '*i32', found '*align(1) i32'",
70987352 });
70997353
7100 cases.add("wrong size to an array literal",
7354 ctx.objErrStage1("wrong size to an array literal",
71017355 \\comptime {
71027356 \\ const array = [2]u8{1, 2, 3};
7357 \\ _ = array;
71037358 \\}
71047359 , &[_][]const u8{
71057360 "tmp.zig:2:31: error: index 2 outside array of size 2",
71067361 });
71077362
7108 cases.add("wrong pointer coerced to pointer to opaque {}",
7363 ctx.objErrStage1("wrong pointer coerced to pointer to opaque {}",
71097364 \\const Derp = opaque {};
71107365 \\extern fn bar(d: *Derp) void;
71117366 \\export fn foo() void {
......@@ -7116,53 +7371,66 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
71167371 "tmp.zig:5:9: error: expected type '*Derp', found '*c_void'",
71177372 });
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",
71207375 \\export fn entry1() void {
71217376 \\ var m2 = &2;
7377 \\ _ = m2;
71227378 \\}
71237379 \\export fn entry2() void {
71247380 \\ var a = undefined;
7381 \\ _ = a;
71257382 \\}
71267383 \\export fn entry3() void {
71277384 \\ var b = 1;
7385 \\ _ = b;
71287386 \\}
71297387 \\export fn entry4() void {
71307388 \\ var c = 1.0;
7389 \\ _ = c;
71317390 \\}
71327391 \\export fn entry5() void {
71337392 \\ var d = null;
7393 \\ _ = d;
71347394 \\}
71357395 \\export fn entry6(opaque_: *Opaque) void {
71367396 \\ var e = opaque_.*;
7397 \\ _ = e;
71377398 \\}
71387399 \\export fn entry7() void {
71397400 \\ var f = i32;
7401 \\ _ = f;
71407402 \\}
71417403 \\export fn entry8() void {
71427404 \\ var h = (Foo {}).bar;
7143 \\}
7144 \\export fn entry9() void {
7145 \\ var z: noreturn = return;
7405 \\ _ = h;
71467406 \\}
71477407 \\const Opaque = opaque {};
71487408 \\const Foo = struct {
7149 \\ fn bar(self: *const Foo) void {}
7409 \\ fn bar(self: *const Foo) void {_ = self;}
71507410 \\};
71517411 , &[_][]const u8{
71527412 "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",
7154 "tmp.zig:8: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",
7156 "tmp.zig:11: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",
7158 "tmp.zig:14:4: error: variable of type '(null)' must be const or comptime",
7159 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
7160 "tmp.zig:20: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",
7162 "tmp.zig:26:22: error: unreachable code",
7413 "tmp.zig:6:4: error: variable of type '(undefined)' must be const or comptime",
7414 "tmp.zig:10:4: error: variable of type 'comptime_int' must be const or comptime",
7415 "tmp.zig:10:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type",
7416 "tmp.zig:14:4: error: variable of type 'comptime_float' must be const or comptime",
7417 "tmp.zig:14:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type",
7418 "tmp.zig:18:4: error: variable of type '(null)' must be const or comptime",
7419 "tmp.zig:22:4: error: variable of type 'Opaque' not allowed",
7420 "tmp.zig:26:4: error: variable of type 'type' must be const or comptime",
7421 "tmp.zig:30:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
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",
71637431 });
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",
71667434 \\export fn entry() void {
71677435 \\ var x: i32 = 1234;
71687436 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}
......@@ -7171,7 +7439,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
71717439 "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
71727440 });
71737441
7174 cases.add("wrong types given to @export",
7442 ctx.objErrStage1("wrong types given to @export",
71757443 \\fn entry() callconv(.C) void { }
71767444 \\comptime {
71777445 \\ @export(entry, .{.name = "entry", .linkage = @as(u32, 1234) });
......@@ -7180,7 +7448,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
71807448 "tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'",
71817449 });
71827450
7183 cases.add("struct with invalid field",
7451 ctx.objErrStage1("struct with invalid field",
71847452 \\const std = @import("std",);
71857453 \\const Allocator = std.mem.Allocator;
71867454 \\const ArrayList = std.ArrayList;
......@@ -7203,12 +7471,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72037471 \\ .text = MdText.init(&std.testing.allocator),
72047472 \\ .weight = HeaderWeight.H1,
72057473 \\ };
7474 \\ _ = a;
72067475 \\}
72077476 , &[_][]const u8{
72087477 "tmp.zig:14:17: error: use of undeclared identifier 'HeaderValue'",
72097478 });
72107479
7211 cases.add("@setAlignStack outside function",
7480 ctx.objErrStage1("@setAlignStack outside function",
72127481 \\comptime {
72137482 \\ @setAlignStack(16);
72147483 \\}
......@@ -7216,7 +7485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72167485 "tmp.zig:2:5: error: @setAlignStack outside function",
72177486 });
72187487
7219 cases.add("@setAlignStack in naked function",
7488 ctx.objErrStage1("@setAlignStack in naked function",
72207489 \\export fn entry() callconv(.Naked) void {
72217490 \\ @setAlignStack(16);
72227491 \\}
......@@ -7224,7 +7493,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72247493 "tmp.zig:2:5: error: @setAlignStack in naked function",
72257494 });
72267495
7227 cases.add("@setAlignStack in inline function",
7496 ctx.objErrStage1("@setAlignStack in inline function",
72287497 \\export fn entry() void {
72297498 \\ foo();
72307499 \\}
......@@ -7235,7 +7504,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72357504 "tmp.zig:5:5: error: @setAlignStack in inline function",
72367505 });
72377506
7238 cases.add("@setAlignStack set twice",
7507 ctx.objErrStage1("@setAlignStack set twice",
72397508 \\export fn entry() void {
72407509 \\ @setAlignStack(16);
72417510 \\ @setAlignStack(16);
......@@ -7245,7 +7514,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72457514 "tmp.zig:2:5: note: first set here",
72467515 });
72477516
7248 cases.add("@setAlignStack too big",
7517 ctx.objErrStage1("@setAlignStack too big",
72497518 \\export fn entry() void {
72507519 \\ @setAlignStack(511 + 1);
72517520 \\}
......@@ -7253,7 +7522,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72537522 "tmp.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256",
72547523 });
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",
72577526 \\const Mode = @import("std").builtin.Mode;
72587527 \\
72597528 \\fn Free(comptime filename: []const u8) TestCase {
......@@ -7290,24 +7559,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
72907559 \\ };
72917560 \\
72927561 \\ for ([_]Mode { Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast }) |mode| {
7562 \\ _ = mode;
72937563 \\ inline for (tests) |test_case| {
72947564 \\ const foo = test_case.filename ++ ".zig";
7565 \\ _ = foo;
72957566 \\ }
72967567 \\ }
72977568 \\}
72987569 , &[_][]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",
73007571 });
73017572
7302 cases.add("invalid legacy unicode escape",
7573 ctx.objErrStage1("invalid legacy unicode escape",
73037574 \\export fn entry() void {
73047575 \\ const a = '\U1234';
73057576 \\}
73067577 , &[_][]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'",
73087580 });
73097581
7310 cases.add("invalid empty unicode escape",
7582 ctx.objErrStage1("invalid empty unicode escape",
73117583 \\export fn entry() void {
73127584 \\ const a = '\u{}';
73137585 \\}
......@@ -7315,21 +7587,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73157587 "tmp.zig:2:19: error: empty unicode escape sequence",
73167588 });
73177589
7318 cases.add("non-printable invalid character", "\xff\xfe" ++
7319 \\fn test() bool {\r
7320 \\ true\r
7321 \\}
7322 , &[_][]const u8{
7323 "tmp.zig:1:1: error: invalid character: '\\xff'",
7590 ctx.objErrStage1("non-printable invalid character", "\xff\xfe" ++
7591 "fn foo() bool {\r\n" ++
7592 " return true;\r\n" ++
7593 "}\r\n", &[_][]const u8{
7594 "tmp.zig:1:1: error: expected test, comptime, var decl, or container field, found 'invalid'",
7595 "tmp.zig:1:1: note: invalid byte: '\\xff'",
73247596 });
73257597
7326 cases.add("non-printable invalid character with escape alternative", "fn test() bool {\n" ++
7327 "\ttrue\n" ++
7598 ctx.objErrStage1("non-printable invalid character with escape alternative", "fn foo() bool {\n" ++
7599 "\treturn true;\n" ++
73287600 "}\n", &[_][]const u8{
73297601 "tmp.zig:2:1: error: invalid character: '\\t'",
73307602 });
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",
73337605 \\export fn entry() void {
73347606 \\ foo("hello".*,);
73357607 \\}
......@@ -7338,7 +7610,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73387610 "tmp.zig:2:16: error: expected type '*const u8', found '[5:0]u8'",
73397611 });
73407612
7341 cases.add("constant inside comptime function has compile error",
7613 ctx.objErrStage1("constant inside comptime function has compile error",
73427614 \\const ContextAllocator = MemoryPool(usize);
73437615 \\
73447616 \\pub fn MemoryPool(comptime T: type) type {
......@@ -7353,12 +7625,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73537625 \\ var allocator: ContextAllocator = undefined;
73547626 \\}
73557627 , &[_][]const u8{
7356 "tmp.zig:4:25: error: aoeu",
7357 "tmp.zig:1:36: note: referenced here",
7358 "tmp.zig:12:20: note: referenced here",
7628 "tmp.zig:4:5: error: unreachable code",
7629 "tmp.zig:4:25: note: control flow is diverted here",
7630 "tmp.zig:12:9: error: unused local variable",
73597631 });
73607632
7361 cases.add("specify enum tag type that is too small",
7633 ctx.objErrStage1("specify enum tag type that is too small",
73627634 \\const Small = enum (u2) {
73637635 \\ One,
73647636 \\ Two,
......@@ -7369,12 +7641,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73697641 \\
73707642 \\export fn entry() void {
73717643 \\ var x = Small.One;
7644 \\ _ = x;
73727645 \\}
73737646 , &[_][]const u8{
73747647 "tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'",
73757648 });
73767649
7377 cases.add("specify non-integer enum tag type",
7650 ctx.objErrStage1("specify non-integer enum tag type",
73787651 \\const Small = enum (f32) {
73797652 \\ One,
73807653 \\ Two,
......@@ -7383,12 +7656,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73837656 \\
73847657 \\export fn entry() void {
73857658 \\ var x = Small.One;
7659 \\ _ = x;
73867660 \\}
73877661 , &[_][]const u8{
73887662 "tmp.zig:1:21: error: expected integer, found 'f32'",
73897663 });
73907664
7391 cases.add("implicitly casting enum to tag type",
7665 ctx.objErrStage1("implicitly casting enum to tag type",
73927666 \\const Small = enum(u2) {
73937667 \\ One,
73947668 \\ Two,
......@@ -7398,12 +7672,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73987672 \\
73997673 \\export fn entry() void {
74007674 \\ var x: u2 = Small.Two;
7675 \\ _ = x;
74017676 \\}
74027677 , &[_][]const u8{
74037678 "tmp.zig:9:22: error: expected type 'u2', found 'Small'",
74047679 });
74057680
7406 cases.add("explicitly casting non tag type to enum",
7681 ctx.objErrStage1("explicitly casting non tag type to enum",
74077682 \\const Small = enum(u2) {
74087683 \\ One,
74097684 \\ Two,
......@@ -7414,42 +7689,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
74147689 \\export fn entry() void {
74157690 \\ var y = @as(u3, 3);
74167691 \\ var x = @intToEnum(Small, y);
7692 \\ _ = x;
74177693 \\}
74187694 , &[_][]const u8{
74197695 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",
74207696 });
74217697
7422 cases.add("union fields with value assignments",
7698 ctx.objErrStage1("union fields with value assignments",
74237699 \\const MultipleChoice = union {
74247700 \\ A: i32 = 20,
74257701 \\};
74267702 \\export fn entry() void {
74277703 \\ var x: MultipleChoice = undefined;
7704 \\ _ = x;
74287705 \\}
74297706 , &[_][]const u8{
7430 "tmp.zig:2:14: error: untagged union field assignment",
7431 "tmp.zig:1:24: note: consider 'union(enum)' here",
7707 "tmp.zig:1:24: error: explicitly valued tagged union missing integer tag type",
7708 "tmp.zig:2:14: note: tag value specified here",
74327709 });
74337710
7434 cases.add("enum with 0 fields",
7711 ctx.objErrStage1("enum with 0 fields",
74357712 \\const Foo = enum {};
7436 \\export fn entry() usize {
7437 \\ return @sizeOf(Foo);
7438 \\}
74397713 , &[_][]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",
74417715 });
74427716
7443 cases.add("union with 0 fields",
7717 ctx.objErrStage1("union with 0 fields",
74447718 \\const Foo = union {};
7445 \\export fn entry() usize {
7446 \\ return @sizeOf(Foo);
7447 \\}
74487719 , &[_][]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",
74507721 });
74517722
7452 cases.add("enum value already taken",
7723 ctx.objErrStage1("enum value already taken",
74537724 \\const MultipleChoice = enum(u32) {
74547725 \\ A = 20,
74557726 \\ B = 40,
......@@ -7459,13 +7730,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
74597730 \\};
74607731 \\export fn entry() void {
74617732 \\ var x = MultipleChoice.C;
7733 \\ _ = x;
74627734 \\}
74637735 , &[_][]const u8{
74647736 "tmp.zig:6:5: error: enum tag value 60 already taken",
74657737 "tmp.zig:4:5: note: other occurrence here",
74667738 });
74677739
7468 cases.add("union with specified enum omits field",
7740 ctx.objErrStage1("union with specified enum omits field",
74697741 \\const Letter = enum {
74707742 \\ A,
74717743 \\ B,
......@@ -7483,29 +7755,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
74837755 "tmp.zig:4:5: note: declared here",
74847756 });
74857757
7486 cases.add("non-integer tag type to automatic union enum",
7758 ctx.objErrStage1("non-integer tag type to automatic union enum",
74877759 \\const Foo = union(enum(f32)) {
74887760 \\ A: i32,
74897761 \\};
74907762 \\export fn entry() void {
74917763 \\ const x = @typeInfo(Foo).Union.tag_type.?;
7764 \\ _ = x;
74927765 \\}
74937766 , &[_][]const u8{
74947767 "tmp.zig:1:24: error: expected integer tag type, found 'f32'",
74957768 });
74967769
7497 cases.add("non-enum tag type passed to union",
7770 ctx.objErrStage1("non-enum tag type passed to union",
74987771 \\const Foo = union(u32) {
74997772 \\ A: i32,
75007773 \\};
75017774 \\export fn entry() void {
75027775 \\ const x = @typeInfo(Foo).Union.tag_type.?;
7776 \\ _ = x;
75037777 \\}
75047778 , &[_][]const u8{
75057779 "tmp.zig:1:19: error: expected enum tag type, found 'u32'",
75067780 });
75077781
7508 cases.add("union auto-enum value already taken",
7782 ctx.objErrStage1("union auto-enum value already taken",
75097783 \\const MultipleChoice = union(enum(u32)) {
75107784 \\ A = 20,
75117785 \\ B = 40,
......@@ -7515,13 +7789,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
75157789 \\};
75167790 \\export fn entry() void {
75177791 \\ var x = MultipleChoice { .C = {} };
7792 \\ _ = x;
75187793 \\}
75197794 , &[_][]const u8{
75207795 "tmp.zig:6:9: error: enum tag value 60 already taken",
75217796 "tmp.zig:4:9: note: other occurrence here",
75227797 });
75237798
7524 cases.add("union enum field does not match enum",
7799 ctx.objErrStage1("union enum field does not match enum",
75257800 \\const Letter = enum {
75267801 \\ A,
75277802 \\ B,
......@@ -7535,49 +7810,49 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
75357810 \\};
75367811 \\export fn entry() void {
75377812 \\ var a = Payload {.A = 1234};
7813 \\ _ = a;
75387814 \\}
75397815 , &[_][]const u8{
75407816 "tmp.zig:10:5: error: enum field not found: 'D'",
75417817 "tmp.zig:1:16: note: enum declared here",
75427818 });
75437819
7544 cases.add("field type supplied in an enum",
7820 ctx.objErrStage1("field type supplied in an enum",
75457821 \\const Letter = enum {
75467822 \\ A: void,
75477823 \\ B,
75487824 \\ C,
75497825 \\};
7550 \\export fn entry() void {
7551 \\ var b = Letter.B;
7552 \\}
75537826 , &[_][]const u8{
7554 "tmp.zig:2:8: error: structs and unions, not enums, support field types",
7555 "tmp.zig:1:16: note: consider 'union(enum)' here",
7827 "tmp.zig:2:8: error: enum fields do not have types",
7828 "tmp.zig:1:16: note: consider 'union(enum)' here to make it a tagged union",
75567829 });
75577830
7558 cases.add("struct field missing type",
7831 ctx.objErrStage1("struct field missing type",
75597832 \\const Letter = struct {
75607833 \\ A,
75617834 \\};
75627835 \\export fn entry() void {
75637836 \\ var a = Letter { .A = {} };
7837 \\ _ = a;
75647838 \\}
75657839 , &[_][]const u8{
75667840 "tmp.zig:2:5: error: struct field missing type",
75677841 });
75687842
7569 cases.add("extern union field missing type",
7843 ctx.objErrStage1("extern union field missing type",
75707844 \\const Letter = extern union {
75717845 \\ A,
75727846 \\};
75737847 \\export fn entry() void {
75747848 \\ var a = Letter { .A = {} };
7849 \\ _ = a;
75757850 \\}
75767851 , &[_][]const u8{
75777852 "tmp.zig:2:5: error: union field missing type",
75787853 });
75797854
7580 cases.add("extern union given enum tag type",
7855 ctx.objErrStage1("extern union given enum tag type",
75817856 \\const Letter = enum {
75827857 \\ A,
75837858 \\ B,
......@@ -7590,12 +7865,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
75907865 \\};
75917866 \\export fn entry() void {
75927867 \\ var a = Payload { .A = 1234 };
7868 \\ _ = a;
75937869 \\}
75947870 , &[_][]const u8{
75957871 "tmp.zig:6:30: error: extern union does not support enum tag type",
75967872 });
75977873
7598 cases.add("packed union given enum tag type",
7874 ctx.objErrStage1("packed union given enum tag type",
75997875 \\const Letter = enum {
76007876 \\ A,
76017877 \\ B,
......@@ -7608,12 +7884,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
76087884 \\};
76097885 \\export fn entry() void {
76107886 \\ var a = Payload { .A = 1234 };
7887 \\ _ = a;
76117888 \\}
76127889 , &[_][]const u8{
76137890 "tmp.zig:6:30: error: packed union does not support enum tag type",
76147891 });
76157892
7616 cases.add("packed union with automatic layout field",
7893 ctx.objErrStage1("packed union with automatic layout field",
76177894 \\const Foo = struct {
76187895 \\ a: u32,
76197896 \\ b: f32,
......@@ -7624,12 +7901,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
76247901 \\};
76257902 \\export fn entry() void {
76267903 \\ var a = Payload { .B = true };
7904 \\ _ = a;
76277905 \\}
76287906 , &[_][]const u8{
76297907 "tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation",
76307908 });
76317909
7632 cases.add("switch on union with no attached enum",
7910 ctx.objErrStage1("switch on union with no attached enum",
76337911 \\const Payload = union {
76347912 \\ A: i32,
76357913 \\ B: f64,
......@@ -7650,20 +7928,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
76507928 "tmp.zig:1:17: note: consider 'union(enum)' here",
76517929 });
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",
76547932 \\const Foo = enum(u32) {
76557933 \\ A = 10,
76567934 \\ B = 11,
76577935 \\};
76587936 \\export fn entry() void {
76597937 \\ var x = @intToEnum(Foo, 0);
7938 \\ _ = x;
76607939 \\}
76617940 , &[_][]const u8{
76627941 "tmp.zig:6:13: error: enum 'Foo' has no tag matching integer value 0",
76637942 "tmp.zig:1:13: note: 'Foo' declared here",
76647943 });
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",
76677946 \\const Letter = enum { A, B, C };
76687947 \\const Value = union(Letter) {
76697948 \\ A: i32,
......@@ -7672,13 +7951,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
76727951 \\};
76737952 \\export fn entry() void {
76747953 \\ var x: Value = Letter.A;
7954 \\ _ = x;
76757955 \\}
76767956 , &[_][]const u8{
76777957 "tmp.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",
76787958 "tmp.zig:3:5: note: field 'A' declared here",
76797959 });
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",
76827962 \\const Letter = enum { A, B, C };
76837963 \\const Value = union(Letter) {
76847964 \\ A: i32,
......@@ -7690,35 +7970,38 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
76907970 \\}
76917971 \\fn foo(l: Letter) void {
76927972 \\ var x: Value = l;
7973 \\ _ = x;
76937974 \\}
76947975 , &[_][]const u8{
76957976 "tmp.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
76967977 "tmp.zig:3:5: note: field 'A' has type 'i32'",
76977978 });
76987979
7699 cases.add("taking byte offset of void field in struct",
7980 ctx.objErrStage1("taking byte offset of void field in struct",
77007981 \\const Empty = struct {
77017982 \\ val: void,
77027983 \\};
77037984 \\export fn foo() void {
77047985 \\ const fieldOffset = @offsetOf(Empty, "val",);
7986 \\ _ = fieldOffset;
77057987 \\}
77067988 , &[_][]const u8{
77077989 "tmp.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset",
77087990 });
77097991
7710 cases.add("taking bit offset of void field in struct",
7992 ctx.objErrStage1("taking bit offset of void field in struct",
77117993 \\const Empty = struct {
77127994 \\ val: void,
77137995 \\};
77147996 \\export fn foo() void {
77157997 \\ const fieldOffset = @bitOffsetOf(Empty, "val",);
7998 \\ _ = fieldOffset;
77167999 \\}
77178000 , &[_][]const u8{
77188001 "tmp.zig:5:45: error: zero-bit field 'val' in struct 'Empty' has no offset",
77198002 });
77208003
7721 cases.add("invalid union field access in comptime",
8004 ctx.objErrStage1("invalid union field access in comptime",
77228005 \\const Foo = union {
77238006 \\ Bar: u8,
77248007 \\ Baz: void,
......@@ -7726,12 +8009,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77268009 \\comptime {
77278010 \\ var foo = Foo {.Baz = {}};
77288011 \\ const bar_val = foo.Bar;
8012 \\ _ = bar_val;
77298013 \\}
77308014 , &[_][]const u8{
77318015 "tmp.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set",
77328016 });
77338017
7734 cases.add("unsupported modifier at start of asm output constraint",
8018 ctx.objErrStage1("unsupported modifier at start of asm output constraint",
77358019 \\export fn foo() void {
77368020 \\ var bar: u32 = 3;
77378021 \\ asm volatile ("" : [baz]"+r"(bar) : : "");
......@@ -7740,7 +8024,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77408024 "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",
77418025 });
77428026
7743 cases.add("comptime_int in asm input",
8027 ctx.objErrStage1("comptime_int in asm input",
77448028 \\export fn foo() void {
77458029 \\ asm volatile ("" : : [bar]"r"(3) : "");
77468030 \\}
......@@ -7748,7 +8032,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77488032 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_int",
77498033 });
77508034
7751 cases.add("comptime_float in asm input",
8035 ctx.objErrStage1("comptime_float in asm input",
77528036 \\export fn foo() void {
77538037 \\ asm volatile ("" : : [bar]"r"(3.17) : "");
77548038 \\}
......@@ -7756,7 +8040,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77568040 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_float",
77578041 });
77588042
7759 cases.add("runtime assignment to comptime struct type",
8043 ctx.objErrStage1("runtime assignment to comptime struct type",
77608044 \\const Foo = struct {
77618045 \\ Bar: u8,
77628046 \\ Baz: type,
......@@ -7764,12 +8048,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77648048 \\export fn f() void {
77658049 \\ var x: u8 = 0;
77668050 \\ const foo = Foo { .Bar = x, .Baz = u8 };
8051 \\ _ = foo;
77678052 \\}
77688053 , &[_][]const u8{
77698054 "tmp.zig:7:23: error: unable to evaluate constant expression",
77708055 });
77718056
7772 cases.add("runtime assignment to comptime union type",
8057 ctx.objErrStage1("runtime assignment to comptime union type",
77738058 \\const Foo = union {
77748059 \\ Bar: u8,
77758060 \\ Baz: type,
......@@ -7777,16 +8062,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77778062 \\export fn f() void {
77788063 \\ var x: u8 = 0;
77798064 \\ const foo = Foo { .Bar = x };
8065 \\ _ = foo;
77808066 \\}
77818067 , &[_][]const u8{
77828068 "tmp.zig:7:23: error: unable to evaluate constant expression",
77838069 });
77848070
7785 cases.addTest("@shuffle with selected index past first vector length",
8071 ctx.testErrStage1("@shuffle with selected index past first vector length",
77868072 \\export fn entry() void {
77878073 \\ const v: @import("std").meta.Vector(4, u32) = [4]u32{ 10, 11, 12, 13 };
77888074 \\ const x: @import("std").meta.Vector(4, u32) = [4]u32{ 14, 15, 16, 17 };
77898075 \\ var z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });
8076 \\ _ = z;
77908077 \\}
77918078 , &[_][]const u8{
77928079 "tmp.zig:4:39: error: mask index '4' has out-of-bounds selection",
......@@ -7794,27 +8081,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
77948081 "tmp.zig:4:30: note: selections from the second vector are specified with negative numbers",
77958082 });
77968083
7797 cases.addTest("nested vectors",
8084 ctx.testErrStage1("nested vectors",
77988085 \\export fn entry() void {
77998086 \\ const V1 = @import("std").meta.Vector(4, u8);
78008087 \\ const V2 = @Type(@import("std").builtin.TypeInfo{ .Vector = .{ .len = 4, .child = V1 } });
78018088 \\ var v: V2 = undefined;
8089 \\ _ = v;
78028090 \\}
78038091 , &[_][]const u8{
78048092 "tmp.zig:3:53: error: vector element type must be integer, float, bool, or pointer; '@Vector(4, u8)' is invalid",
78058093 "tmp.zig:3:16: note: referenced here",
78068094 });
78078095
7808 cases.addTest("bad @splat type",
8096 ctx.testErrStage1("bad @splat type",
78098097 \\export fn entry() void {
78108098 \\ const c = 4;
78118099 \\ var v = @splat(4, c);
8100 \\ _ = v;
78128101 \\}
78138102 , &[_][]const u8{
78148103 "tmp.zig:3:23: error: vector element type must be integer, float, bool, or pointer; 'comptime_int' is invalid",
78158104 });
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",
78188107 \\const Bar = union(enum(u32)) {
78198108 \\ X: i32 = 1
78208109 \\};
......@@ -7830,28 +8119,30 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
78308119 "tmp.zig:6:5: error: found compile log statement",
78318120 });
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",
78348123 \\export fn entry(byte: u8) void {
78358124 \\ const w: i32 = 1234;
78368125 \\ var x: *const i32 = &w;
78378126 \\ var y: *[1]i32 = x;
78388127 \\ y[0] += 1;
8128 \\ _ = byte;
78398129 \\}
78408130 , &[_][]const u8{
78418131 "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'",
78428132 "tmp.zig:4:22: note: cast discards const qualifier",
78438133 });
78448134
7845 cases.add("attempted implicit cast from *const T to []T",
8135 ctx.objErrStage1("attempted implicit cast from *const T to []T",
78468136 \\export fn entry() void {
78478137 \\ const u: u32 = 42;
78488138 \\ const x: []u32 = &u;
8139 \\ _ = x;
78498140 \\}
78508141 , &[_][]const u8{
78518142 "tmp.zig:3:23: error: expected type '[]u32', found '*const u32'",
78528143 });
78538144
7854 cases.add("for loop body expression ignored",
8145 ctx.objErrStage1("for loop body expression ignored",
78558146 \\fn returns() usize {
78568147 \\ return 2;
78578148 \\}
......@@ -7861,21 +8152,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
78618152 \\export fn f2() void {
78628153 \\ var x: anyerror!i32 = error.Bad;
78638154 \\ for ("hello") |_| returns() else unreachable;
8155 \\ _ = x;
78648156 \\}
78658157 , &[_][]const u8{
78668158 "tmp.zig:5:30: error: expression value is ignored",
78678159 "tmp.zig:9:30: error: expression value is ignored",
78688160 });
78698161
7870 cases.add("aligned variable of zero-bit type",
8162 ctx.objErrStage1("aligned variable of zero-bit type",
78718163 \\export fn f() void {
78728164 \\ var s: struct {} align(4) = undefined;
8165 \\ _ = s;
78738166 \\}
78748167 , &[_][]const u8{
78758168 "tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned",
78768169 });
78778170
7878 cases.add("function returning opaque type",
8171 ctx.objErrStage1("function returning opaque type",
78798172 \\const FooType = opaque {};
78808173 \\export fn bar() !FooType {
78818174 \\ return error.InvalidValue;
......@@ -7893,7 +8186,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
78938186 "tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed",
78948187 });
78958188
7896 cases.add("generic function returning opaque type",
8189 ctx.objErrStage1("generic function returning opaque type",
78978190 \\const FooType = opaque {};
78988191 \\fn generic(comptime T: type) !T {
78998192 \\ return undefined;
......@@ -7917,81 +8210,89 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
79178210 "tmp.zig:2:1: note: function declared here",
79188211 });
79198212
7920 cases.add("function parameter is opaque",
8213 ctx.objErrStage1("function parameter is opaque",
79218214 \\const FooType = opaque {};
79228215 \\export fn entry1() void {
79238216 \\ const someFuncPtr: fn (FooType) void = undefined;
8217 \\ _ = someFuncPtr;
79248218 \\}
79258219 \\
79268220 \\export fn entry2() void {
79278221 \\ const someFuncPtr: fn (@TypeOf(null)) void = undefined;
8222 \\ _ = someFuncPtr;
79288223 \\}
79298224 \\
7930 \\fn foo(p: FooType) void {}
8225 \\fn foo(p: FooType) void {_ = p;}
79318226 \\export fn entry3() void {
79328227 \\ _ = foo;
79338228 \\}
79348229 \\
7935 \\fn bar(p: @TypeOf(null)) void {}
8230 \\fn bar(p: @TypeOf(null)) void {_ = p;}
79368231 \\export fn entry4() void {
79378232 \\ _ = bar;
79388233 \\}
79398234 , &[_][]const u8{
79408235 "tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed",
7941 "tmp.zig:7:28: error: parameter of type '(null)' not allowed",
7942 "tmp.zig:10:11: error: parameter of opaque type 'FooType' not allowed",
7943 "tmp.zig:15:11: error: parameter of type '(null)' not allowed",
8236 "tmp.zig:8:28: error: parameter of type '(null)' not allowed",
8237 "tmp.zig:12:11: error: parameter of opaque type 'FooType' not allowed",
8238 "tmp.zig:17:11: error: parameter of type '(null)' not allowed",
79448239 });
79458240
7946 cases.add( // fixed bug #2032
8241 ctx.objErrStage1( // fixed bug #2032
79478242 "compile diagnostic string for top level decl type",
79488243 \\export fn entry() void {
79498244 \\ var foo: u32 = @This(){};
8245 \\ _ = foo;
79508246 \\}
79518247 , &[_][]const u8{
79528248 "tmp.zig:2:27: error: type 'u32' does not support array initialization",
79538249 });
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",
79568252 \\export fn foo1() void {
79578253 \\ const a: *[1]u8 = undefined;
79588254 \\ var b: []u8 = a;
8255 \\ _ = b;
79598256 \\}
79608257 \\export fn foo2() void {
79618258 \\ comptime {
79628259 \\ var a: *[1]u8 = undefined;
79638260 \\ var b: []u8 = a;
8261 \\ _ = b;
79648262 \\ }
79658263 \\}
79668264 \\export fn foo3() void {
79678265 \\ comptime {
79688266 \\ const a: *[1]u8 = undefined;
79698267 \\ var b: []u8 = a;
8268 \\ _ = b;
79708269 \\ }
79718270 \\}
79728271 , &[_][]const u8{
79738272 "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",
7975 "tmp.zig:14:23: error: use of undefined value here causes undefined behavior",
8273 "tmp.zig:9:23: error: use of undefined value here causes undefined behavior",
8274 "tmp.zig:16:23: error: use of undefined value here causes undefined behavior",
79768275 });
79778276
7978 cases.add("issue #3818: bitcast from parray/slice to u16",
8277 ctx.objErrStage1("issue #3818: bitcast from parray/slice to u16",
79798278 \\export fn foo1() void {
79808279 \\ var bytes = [_]u8{1, 2};
79818280 \\ const word: u16 = @bitCast(u16, bytes[0..]);
8281 \\ _ = word;
79828282 \\}
79838283 \\export fn foo2() void {
79848284 \\ var bytes: []const u8 = &[_]u8{1, 2};
79858285 \\ const word: u16 = @bitCast(u16, bytes);
8286 \\ _ = word;
79868287 \\}
79878288 , &[_][]const u8{
79888289 "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",
7990 "tmp.zig:7:37: note: referenced here",
8290 "tmp.zig:8:32: error: destination type 'u16' has size 2 but source type '[]const u8' has size 16",
8291 "tmp.zig:8:37: note: referenced here",
79918292 });
79928293
79938294 // issue #7810
7994 cases.add("comptime slice-len increment beyond bounds",
8295 ctx.objErrStage1("comptime slice-len increment beyond bounds",
79958296 \\export fn foo_slice_len_increment_beyond_bounds() void {
79968297 \\ comptime {
79978298 \\ var buf_storage: [8]u8 = undefined;
......@@ -8004,11 +8305,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80048305 ":6:12: error: out of bounds slice",
80058306 });
80068307
8007 cases.add("comptime slice-sentinel is out of bounds (unterminated)",
8308 ctx.objErrStage1("comptime slice-sentinel is out of bounds (unterminated)",
80088309 \\export fn foo_array() void {
80098310 \\ comptime {
80108311 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80118312 \\ const slice = target[0..14 :0];
8313 \\ _ = slice;
80128314 \\ }
80138315 \\}
80148316 \\export fn foo_ptr_array() void {
......@@ -8016,6 +8318,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80168318 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80178319 \\ var target = &buf;
80188320 \\ const slice = target[0..14 :0];
8321 \\ _ = slice;
80198322 \\ }
80208323 \\}
80218324 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
......@@ -8023,6 +8326,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80238326 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80248327 \\ var target: [*]u8 = &buf;
80258328 \\ const slice = target[0..14 :0];
8329 \\ _ = slice;
80268330 \\ }
80278331 \\}
80288332 \\export fn foo_vector_ConstPtrSpecialRef() void {
......@@ -8030,6 +8334,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80308334 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80318335 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
80328336 \\ const slice = target[0..14 :0];
8337 \\ _ = slice;
80338338 \\ }
80348339 \\}
80358340 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
......@@ -8037,6 +8342,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80378342 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80388343 \\ var target: [*c]u8 = &buf;
80398344 \\ const slice = target[0..14 :0];
8345 \\ _ = slice;
80408346 \\ }
80418347 \\}
80428348 \\export fn foo_cvector_ConstPtrSpecialRef() void {
......@@ -8044,6 +8350,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80448350 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80458351 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
80468352 \\ const slice = target[0..14 :0];
8353 \\ _ = slice;
80478354 \\ }
80488355 \\}
80498356 \\export fn foo_slice() void {
......@@ -8051,23 +8358,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80518358 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80528359 \\ var target: []u8 = &buf;
80538360 \\ const slice = target[0..14 :0];
8361 \\ _ = slice;
80548362 \\ }
80558363 \\}
80568364 , &[_][]const u8{
80578365 ":4:29: error: slice-sentinel is out of bounds",
8058 ":11:29: error: slice-sentinel is out of bounds",
8059 ":18:29: error: slice-sentinel is out of bounds",
8060 ":25:29: error: slice-sentinel is out of bounds",
8061 ":32:29: error: slice-sentinel is out of bounds",
8062 ":39:29: error: slice-sentinel is out of bounds",
8063 ":46:29: error: slice-sentinel is out of bounds",
8366 ":12:29: error: slice-sentinel is out of bounds",
8367 ":20:29: error: slice-sentinel is out of bounds",
8368 ":28:29: error: slice-sentinel is out of bounds",
8369 ":36:29: error: slice-sentinel is out of bounds",
8370 ":44:29: error: slice-sentinel is out of bounds",
8371 ":52:29: error: slice-sentinel is out of bounds",
80648372 });
80658373
8066 cases.add("comptime slice-sentinel is out of bounds (terminated)",
8374 ctx.objErrStage1("comptime slice-sentinel is out of bounds (terminated)",
80678375 \\export fn foo_array() void {
80688376 \\ comptime {
80698377 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80708378 \\ const slice = target[0..15 :1];
8379 \\ _ = slice;
80718380 \\ }
80728381 \\}
80738382 \\export fn foo_ptr_array() void {
......@@ -8075,6 +8384,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80758384 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80768385 \\ var target = &buf;
80778386 \\ const slice = target[0..15 :0];
8387 \\ _ = slice;
80788388 \\ }
80798389 \\}
80808390 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
......@@ -8082,6 +8392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80828392 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80838393 \\ var target: [*]u8 = &buf;
80848394 \\ const slice = target[0..15 :0];
8395 \\ _ = slice;
80858396 \\ }
80868397 \\}
80878398 \\export fn foo_vector_ConstPtrSpecialRef() void {
......@@ -8089,6 +8400,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80898400 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80908401 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
80918402 \\ const slice = target[0..15 :0];
8403 \\ _ = slice;
80928404 \\ }
80938405 \\}
80948406 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
......@@ -8096,6 +8408,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
80968408 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
80978409 \\ var target: [*c]u8 = &buf;
80988410 \\ const slice = target[0..15 :0];
8411 \\ _ = slice;
80998412 \\ }
81008413 \\}
81018414 \\export fn foo_cvector_ConstPtrSpecialRef() void {
......@@ -8103,6 +8416,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81038416 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81048417 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
81058418 \\ const slice = target[0..15 :0];
8419 \\ _ = slice;
81068420 \\ }
81078421 \\}
81088422 \\export fn foo_slice() void {
......@@ -8110,23 +8424,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81108424 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81118425 \\ var target: []u8 = &buf;
81128426 \\ const slice = target[0..15 :0];
8427 \\ _ = slice;
81138428 \\ }
81148429 \\}
81158430 , &[_][]const u8{
81168431 ":4:29: error: out of bounds slice",
8117 ":11:29: error: out of bounds slice",
8118 ":18:29: error: out of bounds slice",
8119 ":25:29: error: out of bounds slice",
8120 ":32:29: error: out of bounds slice",
8121 ":39:29: error: out of bounds slice",
8122 ":46:29: error: out of bounds slice",
8432 ":12:29: error: out of bounds slice",
8433 ":20:29: error: out of bounds slice",
8434 ":28:29: error: out of bounds slice",
8435 ":36:29: error: out of bounds slice",
8436 ":44:29: error: out of bounds slice",
8437 ":52:29: error: out of bounds slice",
81238438 });
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)",
81268441 \\export fn foo_array() void {
81278442 \\ comptime {
81288443 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81298444 \\ const slice = target[0..3 :0];
8445 \\ _ = slice;
81308446 \\ }
81318447 \\}
81328448 \\export fn foo_ptr_array() void {
......@@ -8134,6 +8450,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81348450 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81358451 \\ var target = &buf;
81368452 \\ const slice = target[0..3 :0];
8453 \\ _ = slice;
81378454 \\ }
81388455 \\}
81398456 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
......@@ -8141,6 +8458,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81418458 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81428459 \\ var target: [*]u8 = &buf;
81438460 \\ const slice = target[0..3 :0];
8461 \\ _ = slice;
81448462 \\ }
81458463 \\}
81468464 \\export fn foo_vector_ConstPtrSpecialRef() void {
......@@ -8148,6 +8466,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81488466 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81498467 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
81508468 \\ const slice = target[0..3 :0];
8469 \\ _ = slice;
81518470 \\ }
81528471 \\}
81538472 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
......@@ -8155,6 +8474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81558474 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81568475 \\ var target: [*c]u8 = &buf;
81578476 \\ const slice = target[0..3 :0];
8477 \\ _ = slice;
81588478 \\ }
81598479 \\}
81608480 \\export fn foo_cvector_ConstPtrSpecialRef() void {
......@@ -8162,6 +8482,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81628482 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81638483 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
81648484 \\ const slice = target[0..3 :0];
8485 \\ _ = slice;
81658486 \\ }
81668487 \\}
81678488 \\export fn foo_slice() void {
......@@ -8169,23 +8490,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81698490 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81708491 \\ var target: []u8 = &buf;
81718492 \\ const slice = target[0..3 :0];
8493 \\ _ = slice;
81728494 \\ }
81738495 \\}
81748496 , &[_][]const u8{
81758497 ":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",
8177 ":18:29: error: slice-sentinel does not match memory at target index",
8178 ":25:29: error: slice-sentinel does not match memory at target index",
8179 ":32:29: error: slice-sentinel does not match memory at target index",
8180 ":39:29: error: slice-sentinel does not match memory at target index",
8181 ":46:29: error: slice-sentinel does not match memory at target index",
8498 ":12:29: error: slice-sentinel does not match memory at target index",
8499 ":20:29: error: slice-sentinel does not match memory at target index",
8500 ":28:29: error: slice-sentinel does not match memory at target index",
8501 ":36:29: error: slice-sentinel does not match memory at target index",
8502 ":44:29: error: slice-sentinel does not match memory at target index",
8503 ":52:29: error: slice-sentinel does not match memory at target index",
81828504 });
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)",
81858507 \\export fn foo_array() void {
81868508 \\ comptime {
81878509 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81888510 \\ const slice = target[0..3 :0];
8511 \\ _ = slice;
81898512 \\ }
81908513 \\}
81918514 \\export fn foo_ptr_array() void {
......@@ -8193,6 +8516,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81938516 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
81948517 \\ var target = &buf;
81958518 \\ const slice = target[0..3 :0];
8519 \\ _ = slice;
81968520 \\ }
81978521 \\}
81988522 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
......@@ -8200,6 +8524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82008524 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82018525 \\ var target: [*]u8 = &buf;
82028526 \\ const slice = target[0..3 :0];
8527 \\ _ = slice;
82038528 \\ }
82048529 \\}
82058530 \\export fn foo_vector_ConstPtrSpecialRef() void {
......@@ -8207,6 +8532,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82078532 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82088533 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
82098534 \\ const slice = target[0..3 :0];
8535 \\ _ = slice;
82108536 \\ }
82118537 \\}
82128538 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
......@@ -8214,6 +8540,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82148540 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82158541 \\ var target: [*c]u8 = &buf;
82168542 \\ const slice = target[0..3 :0];
8543 \\ _ = slice;
82178544 \\ }
82188545 \\}
82198546 \\export fn foo_cvector_ConstPtrSpecialRef() void {
......@@ -8221,6 +8548,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82218548 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82228549 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
82238550 \\ const slice = target[0..3 :0];
8551 \\ _ = slice;
82248552 \\ }
82258553 \\}
82268554 \\export fn foo_slice() void {
......@@ -8228,23 +8556,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82288556 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82298557 \\ var target: []u8 = &buf;
82308558 \\ const slice = target[0..3 :0];
8559 \\ _ = slice;
82318560 \\ }
82328561 \\}
82338562 , &[_][]const u8{
82348563 ":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",
8236 ":18:29: error: slice-sentinel does not match memory at target index",
8237 ":25:29: error: slice-sentinel does not match memory at target index",
8238 ":32:29: error: slice-sentinel does not match memory at target index",
8239 ":39:29: error: slice-sentinel does not match memory at target index",
8240 ":46:29: error: slice-sentinel does not match memory at target index",
8564 ":12:29: error: slice-sentinel does not match memory at target index",
8565 ":20:29: error: slice-sentinel does not match memory at target index",
8566 ":28:29: error: slice-sentinel does not match memory at target index",
8567 ":36:29: error: slice-sentinel does not match memory at target index",
8568 ":44:29: error: slice-sentinel does not match memory at target index",
8569 ":52:29: error: slice-sentinel does not match memory at target index",
82418570 });
82428571
8243 cases.add("comptime slice-sentinel does not match target-sentinel",
8572 ctx.objErrStage1("comptime slice-sentinel does not match target-sentinel",
82448573 \\export fn foo_array() void {
82458574 \\ comptime {
82468575 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82478576 \\ const slice = target[0..14 :255];
8577 \\ _ = slice;
82488578 \\ }
82498579 \\}
82508580 \\export fn foo_ptr_array() void {
......@@ -8252,6 +8582,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82528582 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82538583 \\ var target = &buf;
82548584 \\ const slice = target[0..14 :255];
8585 \\ _ = slice;
82558586 \\ }
82568587 \\}
82578588 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
......@@ -8259,6 +8590,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82598590 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82608591 \\ var target: [*]u8 = &buf;
82618592 \\ const slice = target[0..14 :255];
8593 \\ _ = slice;
82628594 \\ }
82638595 \\}
82648596 \\export fn foo_vector_ConstPtrSpecialRef() void {
......@@ -8266,6 +8598,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82668598 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82678599 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
82688600 \\ const slice = target[0..14 :255];
8601 \\ _ = slice;
82698602 \\ }
82708603 \\}
82718604 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
......@@ -8273,6 +8606,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82738606 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82748607 \\ var target: [*c]u8 = &buf;
82758608 \\ const slice = target[0..14 :255];
8609 \\ _ = slice;
82768610 \\ }
82778611 \\}
82788612 \\export fn foo_cvector_ConstPtrSpecialRef() void {
......@@ -8280,6 +8614,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82808614 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82818615 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
82828616 \\ const slice = target[0..14 :255];
8617 \\ _ = slice;
82838618 \\ }
82848619 \\}
82858620 \\export fn foo_slice() void {
......@@ -8287,19 +8622,20 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
82878622 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
82888623 \\ var target: []u8 = &buf;
82898624 \\ const slice = target[0..14 :255];
8625 \\ _ = slice;
82908626 \\ }
82918627 \\}
82928628 , &[_][]const u8{
82938629 ":4:29: error: slice-sentinel does not match target-sentinel",
8294 ":11:29: error: slice-sentinel does not match target-sentinel",
8295 ":18:29: error: slice-sentinel does not match target-sentinel",
8296 ":25:29: error: slice-sentinel does not match target-sentinel",
8297 ":32:29: error: slice-sentinel does not match target-sentinel",
8298 ":39:29: error: slice-sentinel does not match target-sentinel",
8299 ":46:29: error: slice-sentinel does not match target-sentinel",
8630 ":12:29: error: slice-sentinel does not match target-sentinel",
8631 ":20:29: error: slice-sentinel does not match target-sentinel",
8632 ":28:29: error: slice-sentinel does not match target-sentinel",
8633 ":36:29: error: slice-sentinel does not match target-sentinel",
8634 ":44:29: error: slice-sentinel does not match target-sentinel",
8635 ":52:29: error: slice-sentinel does not match target-sentinel",
83008636 });
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",
83038639 \\export fn foo() [*:0]const u8 {
83048640 \\ var buffer: [64]u8 = undefined;
83058641 \\ return buffer[0..];
......@@ -8309,8 +8645,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
83098645 ":3:18: note: destination pointer requires a terminating '0' sentinel",
83108646 });
83118647
8312 cases.add("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",
8313 \\fn ignore(comptime param: anytype) void {}
8648 ctx.objErrStage1("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",
8649 \\fn ignore(comptime param: anytype) void {_ = param;}
83148650 \\
83158651 \\export fn foo() void {
83168652 \\ const MyStruct = struct {
......@@ -8323,7 +8659,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
83238659 ":5:28: error: expected type '[]u8', found '*const [3:0]u8'",
83248660 });
83258661
8326 cases.add("integer underflow error",
8662 ctx.objErrStage1("integer underflow error",
83278663 \\export fn entry() void {
83288664 \\ _ = @intToPtr(*c_void, ~@as(usize, @import("std").math.maxInt(usize)) - 1);
83298665 \\}
......@@ -8331,23 +8667,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
83318667 ":2:75: error: operation caused overflow",
83328668 });
83338669
8334 cases.addCase(x: {
8335 var tc = cases.create("align(N) expr function pointers is a compile error",
8670 {
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(
83368679 \\export fn foo() align(1) void {
83378680 \\ return;
83388681 \\}
83398682 , &[_][]const u8{
83408683 "tmp.zig:1:23: error: align(N) expr is not allowed on function prototypes in wasm32/wasm64",
83418684 });
8342 tc.target = std.zig.CrossTarget{
8343 .cpu_arch = .wasm32,
8344 .os_tag = .freestanding,
8345 .abi = .none,
8346 };
8347 break :x tc;
8348 });
8685 }
83498686
8350 cases.add("compare optional to non-optional with invalid types",
8687 ctx.objErrStage1("compare optional to non-optional with invalid types",
83518688 \\export fn inconsistentChildType() void {
83528689 \\ var x: ?i32 = undefined;
83538690 \\ const y: comptime_int = 10;
......@@ -8381,16 +8718,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
83818718 ":22:12: note: operator not supported for type '[3]i32'",
83828719 });
83838720
8384 cases.add("slice cannot have its bytes reinterpreted",
8721 ctx.objErrStage1("slice cannot have its bytes reinterpreted",
83858722 \\export fn foo() void {
83868723 \\ const bytes = [1]u8{ 0xfa } ** 16;
83878724 \\ var value = @ptrCast(*const []const u8, &bytes).*;
8725 \\ _ = value;
83888726 \\}
83898727 , &[_][]const u8{
83908728 ":3:52: error: slice '[]const u8' cannot have its bytes reinterpreted",
83918729 });
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",
83948732 \\export fn foo() void {
83958733 \\ _ = @wasmMemorySize(0);
83968734 \\ return;
......@@ -8399,7 +8737,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
83998737 "tmp.zig:2:9: error: @wasmMemorySize is a wasm32 feature only",
84008738 });
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",
84038741 \\export fn foo() void {
84048742 \\ _ = @wasmMemoryGrow(0, 1);
84058743 \\ return;
......@@ -8407,7 +8745,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
84078745 , &[_][]const u8{
84088746 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
84098747 });
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",
84118749 \\export fn f1(x: u32) u32 {
84128750 \\ const y = -%x;
84138751 \\ return -y;
......@@ -8422,7 +8760,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
84228760 "tmp.zig:8:12: error: negation of type 'u32'",
84238761 });
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.",
84268764 \\export fn foo() void {
84278765 \\ var u: ?*c_void = null;
84288766 \\ var v: *c_void = undefined;
......@@ -8432,15 +8770,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
84328770 "tmp.zig:4:9: error: expected type '*c_void', found '?*c_void'",
84338771 });
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 **",
84368774 \\fn foo() void {
84378775 \\ var sequence = "repeat".*** 10;
8776 \\ _ = sequence;
84388777 \\}
84398778 , &[_][]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?",
84418781 });
84428782
8443 cases.add("Issue #9165: windows tcp server compilation error",
8783 ctx.objErrStage1("Issue #9165: windows tcp server compilation error",
84448784 \\const std = @import("std");
84458785 \\pub const io_mode = .evented;
84468786 \\pub fn main() !void {
test/stage2/cbe.zig+7-6
......@@ -525,7 +525,7 @@ pub fn addCases(ctx: *TestContext) !void {
525525 \\}
526526 , &.{
527527 ":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",
529529 });
530530 case.addError(
531531 \\const Point = struct { x: i32, y: i32 };
......@@ -538,7 +538,7 @@ pub fn addCases(ctx: *TestContext) !void {
538538 \\ return p.y - p.x - p.x;
539539 \\}
540540 , &.{
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'",
542542 ":1:15: note: struct declared here",
543543 });
544544 case.addCompareOutput(
......@@ -591,6 +591,7 @@ pub fn addCases(ctx: *TestContext) !void {
591591 , &.{
592592 ":3:5: error: enum fields cannot be marked comptime",
593593 ":8:8: error: enum fields do not have types",
594 ":6:12: note: consider 'union(enum)' here to make it a tagged union",
594595 });
595596
596597 // @enumToInt, @intToEnum, enum literal coercion, field access syntax, comparison, switch
......@@ -716,7 +717,7 @@ pub fn addCases(ctx: *TestContext) !void {
716717 \\ _ = @intToEnum(E, 3);
717718 \\}
718719 , &.{
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",
720721 ":1:11: note: enum declared here",
721722 });
722723
......@@ -732,7 +733,7 @@ pub fn addCases(ctx: *TestContext) !void {
732733 , &.{
733734 ":4:5: error: switch must handle all possibilities",
734735 ":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",
736737 });
737738
738739 case.addError(
......@@ -787,7 +788,7 @@ pub fn addCases(ctx: *TestContext) !void {
787788 \\ _ = E.d;
788789 \\}
789790 , &.{
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'",
791792 ":1:11: note: enum declared here",
792793 });
793794
......@@ -798,7 +799,7 @@ pub fn addCases(ctx: *TestContext) !void {
798799 \\ _ = x;
799800 \\}
800801 , &.{
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'",
802803 ":1:11: note: enum declared here",
803804 });
804805 }
test/stage2/darwin.zig+1-1
......@@ -14,7 +14,7 @@ pub fn addCases(ctx: *TestContext) !void {
1414 {
1515 var case = ctx.exe("hello world with updates", target);
1616 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'",
1818 });
1919
2020 // 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;
1616const compare_output = @import("compare_output.zig");
1717const standalone = @import("standalone.zig");
1818const stack_traces = @import("stack_traces.zig");
19const compile_errors = @import("compile_errors.zig");
2019const assemble_and_link = @import("assemble_and_link.zig");
2120const runtime_safety = @import("runtime_safety.zig");
2221const translate_c = @import("translate_c.zig");
......@@ -384,21 +383,6 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
384383 return cases.step;
385384}
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
402386pub fn addStandaloneTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode, skip_non_native: bool, target: std.zig.CrossTarget) *build.Step {
403387 const cases = b.allocator.create(StandaloneContext) catch unreachable;
404388 cases.* = StandaloneContext{
......@@ -840,304 +824,6 @@ pub const StackTracesContext = struct {
840824 };
841825};
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
1141827pub const StandaloneContext = struct {
1142828 b: *build.Builder,
1143829 step: *build.Step,
......@@ -1312,13 +998,6 @@ pub const GenHContext = struct {
1312998 }
1313999 };
13141000
1315 fn printInvocation(args: []const []const u8) void {
1316 for (args) |arg| {
1317 warn("{s} ", .{arg});
1318 }
1319 warn("\n", .{});
1320 }
1321
13221001 pub fn create(
13231002 self: *GenHContext,
13241003 filename: []const u8,