authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-12 17:45:57-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-12 17:45:57-04:00
logffa700ee58cd29dafe2bbdfe78a4bd4f7bab0674
treeaffe8b6dc716051f32259ad171f93d7009855c0f
parent6e42d45dccf4ba6fa07082db1cb820897d36924f
parent0a9d6956e7cac96c870ad062b4125b0a0a3b0143
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11837 from Vexu/stage2

Fix (nearly) all stage2 crashes when testing stdlib

43 files changed, 501 insertions(+), 626 deletions(-)

ci/zinc/linux_test.sh+1
...@@ -59,6 +59,7 @@ stage2/bin/zig build -Dtarget=arm-linux-musleabihf # test building self-hosted f...@@ -59,6 +59,7 @@ stage2/bin/zig build -Dtarget=arm-linux-musleabihf # test building self-hosted f
59# * https://github.com/ziglang/zig/issues/11367 (and corresponding workaround in compiler source)59# * https://github.com/ziglang/zig/issues/11367 (and corresponding workaround in compiler source)
60# * https://github.com/ziglang/zig/pull/11492#issuecomment-111287132160# * https://github.com/ziglang/zig/pull/11492#issuecomment-1112871321
61stage2/bin/zig build test-behavior -fqemu -fwasmtime61stage2/bin/zig build test-behavior -fqemu -fwasmtime
62stage2/bin/zig test lib/std/std.zig --zig-lib-dir lib
6263
63$ZIG build test-behavior -fqemu -fwasmtime -Domit-stage264$ZIG build test-behavior -fqemu -fwasmtime -Domit-stage2
64$ZIG build test-compiler-rt -fqemu -fwasmtime65$ZIG build test-compiler-rt -fqemu -fwasmtime
lib/std/bit_set.zig+4
...@@ -1330,6 +1330,7 @@ fn testStaticBitSet(comptime Set: type) !void {...@@ -1330,6 +1330,7 @@ fn testStaticBitSet(comptime Set: type) !void {
1330}1330}
13311331
1332test "IntegerBitSet" {1332test "IntegerBitSet" {
1333 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
1333 try testStaticBitSet(IntegerBitSet(0));1334 try testStaticBitSet(IntegerBitSet(0));
1334 try testStaticBitSet(IntegerBitSet(1));1335 try testStaticBitSet(IntegerBitSet(1));
1335 try testStaticBitSet(IntegerBitSet(2));1336 try testStaticBitSet(IntegerBitSet(2));
...@@ -1341,6 +1342,7 @@ test "IntegerBitSet" {...@@ -1341,6 +1342,7 @@ test "IntegerBitSet" {
1341}1342}
13421343
1343test "ArrayBitSet" {1344test "ArrayBitSet" {
1345 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
1344 if (@import("builtin").cpu.arch == .aarch64) {1346 if (@import("builtin").cpu.arch == .aarch64) {
1345 // https://github.com/ziglang/zig/issues/98791347 // https://github.com/ziglang/zig/issues/9879
1346 return error.SkipZigTest;1348 return error.SkipZigTest;
...@@ -1355,6 +1357,7 @@ test "ArrayBitSet" {...@@ -1355,6 +1357,7 @@ test "ArrayBitSet" {
1355}1357}
13561358
1357test "DynamicBitSetUnmanaged" {1359test "DynamicBitSetUnmanaged" {
1360 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
1358 const allocator = std.testing.allocator;1361 const allocator = std.testing.allocator;
1359 var a = try DynamicBitSetUnmanaged.initEmpty(allocator, 300);1362 var a = try DynamicBitSetUnmanaged.initEmpty(allocator, 300);
1360 try testing.expectEqual(@as(usize, 0), a.count());1363 try testing.expectEqual(@as(usize, 0), a.count());
...@@ -1395,6 +1398,7 @@ test "DynamicBitSetUnmanaged" {...@@ -1395,6 +1398,7 @@ test "DynamicBitSetUnmanaged" {
1395}1398}
13961399
1397test "DynamicBitSet" {1400test "DynamicBitSet" {
1401 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
1398 const allocator = std.testing.allocator;1402 const allocator = std.testing.allocator;
1399 var a = try DynamicBitSet.initEmpty(allocator, 300);1403 var a = try DynamicBitSet.initEmpty(allocator, 300);
1400 try testing.expectEqual(@as(usize, 0), a.count());1404 try testing.expectEqual(@as(usize, 0), a.count());
lib/std/compress.zig-1
...@@ -5,7 +5,6 @@ pub const gzip = @import("compress/gzip.zig");...@@ -5,7 +5,6 @@ pub const gzip = @import("compress/gzip.zig");
5pub const zlib = @import("compress/zlib.zig");5pub const zlib = @import("compress/zlib.zig");
66
7test {7test {
8 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
9 _ = deflate;8 _ = deflate;
10 _ = gzip;9 _ = gzip;
11 _ = zlib;10 _ = zlib;
lib/std/compress/deflate/compressor.zig+4-1
...@@ -254,7 +254,10 @@ pub fn Compressor(comptime WriterType: anytype) type {...@@ -254,7 +254,10 @@ pub fn Compressor(comptime WriterType: anytype) type {
254254
255 // Inner writer wrapped in a HuffmanBitWriter255 // Inner writer wrapped in a HuffmanBitWriter
256 hm_bw: hm_bw.HuffmanBitWriter(WriterType) = undefined,256 hm_bw: hm_bw.HuffmanBitWriter(WriterType) = undefined,
257 bulk_hasher: fn ([]u8, []u32) u32,257 bulk_hasher: if (@import("builtin").zig_backend == .stage1)
258 fn ([]u8, []u32) u32
259 else
260 *const fn ([]u8, []u32) u32,
258261
259 sync: bool, // requesting flush262 sync: bool, // requesting flush
260 best_speed_enc: *fast.DeflateFast, // Encoder for best_speed263 best_speed_enc: *fast.DeflateFast, // Encoder for best_speed
lib/std/compress/deflate/compressor_test.zig+13-24
...@@ -122,11 +122,8 @@ fn testToFromWithLevelAndLimit(level: deflate.Compression, input: []const u8, li...@@ -122,11 +122,8 @@ fn testToFromWithLevelAndLimit(level: deflate.Compression, input: []const u8, li
122 try expect(compressed.items.len <= limit);122 try expect(compressed.items.len <= limit);
123 }123 }
124124
125 var decomp = try decompressor(125 var fib = io.fixedBufferStream(compressed.items);
126 testing.allocator,126 var decomp = try decompressor(testing.allocator, fib.reader(), null);
127 io.fixedBufferStream(compressed.items).reader(),
128 null,
129 );
130 defer decomp.deinit();127 defer decomp.deinit();
131128
132 var decompressed = try testing.allocator.alloc(u8, input.len);129 var decompressed = try testing.allocator.alloc(u8, input.len);
...@@ -136,7 +133,9 @@ fn testToFromWithLevelAndLimit(level: deflate.Compression, input: []const u8, li...@@ -136,7 +133,9 @@ fn testToFromWithLevelAndLimit(level: deflate.Compression, input: []const u8, li
136 try expect(read == input.len);133 try expect(read == input.len);
137 try expect(mem.eql(u8, input, decompressed));134 try expect(mem.eql(u8, input, decompressed));
138135
139 try testSync(level, input);136 if (builtin.zig_backend == .stage1) {
137 try testSync(level, input);
138 }
140}139}
141140
142fn testToFromWithLimit(input: []const u8, limit: [11]u32) !void {141fn testToFromWithLimit(input: []const u8, limit: [11]u32) !void {
...@@ -475,21 +474,16 @@ test "inflate reset" {...@@ -475,21 +474,16 @@ test "inflate reset" {
475 try comp.close();474 try comp.close();
476 }475 }
477476
478 var decomp = try decompressor(477 var fib = io.fixedBufferStream(compressed_strings[0].items);
479 testing.allocator,478 var decomp = try decompressor(testing.allocator, fib.reader(), null);
480 io.fixedBufferStream(compressed_strings[0].items).reader(),
481 null,
482 );
483 defer decomp.deinit();479 defer decomp.deinit();
484480
485 var decompressed_0: []u8 = try decomp.reader()481 var decompressed_0: []u8 = try decomp.reader()
486 .readAllAlloc(testing.allocator, math.maxInt(usize));482 .readAllAlloc(testing.allocator, math.maxInt(usize));
487 defer testing.allocator.free(decompressed_0);483 defer testing.allocator.free(decompressed_0);
488484
489 try decomp.reset(485 fib = io.fixedBufferStream(compressed_strings[1].items);
490 io.fixedBufferStream(compressed_strings[1].items).reader(),486 try decomp.reset(fib.reader(), null);
491 null,
492 );
493487
494 var decompressed_1: []u8 = try decomp.reader()488 var decompressed_1: []u8 = try decomp.reader()
495 .readAllAlloc(testing.allocator, math.maxInt(usize));489 .readAllAlloc(testing.allocator, math.maxInt(usize));
...@@ -530,21 +524,16 @@ test "inflate reset dictionary" {...@@ -530,21 +524,16 @@ test "inflate reset dictionary" {
530 try comp.close();524 try comp.close();
531 }525 }
532526
533 var decomp = try decompressor(527 var fib = io.fixedBufferStream(compressed_strings[0].items);
534 testing.allocator,528 var decomp = try decompressor(testing.allocator, fib.reader(), dict);
535 io.fixedBufferStream(compressed_strings[0].items).reader(),
536 dict,
537 );
538 defer decomp.deinit();529 defer decomp.deinit();
539530
540 var decompressed_0: []u8 = try decomp.reader()531 var decompressed_0: []u8 = try decomp.reader()
541 .readAllAlloc(testing.allocator, math.maxInt(usize));532 .readAllAlloc(testing.allocator, math.maxInt(usize));
542 defer testing.allocator.free(decompressed_0);533 defer testing.allocator.free(decompressed_0);
543534
544 try decomp.reset(535 fib = io.fixedBufferStream(compressed_strings[1].items);
545 io.fixedBufferStream(compressed_strings[1].items).reader(),536 try decomp.reset(fib.reader(), dict);
546 dict,
547 );
548537
549 var decompressed_1: []u8 = try decomp.reader()538 var decompressed_1: []u8 = try decomp.reader()
550 .readAllAlloc(testing.allocator, math.maxInt(usize));539 .readAllAlloc(testing.allocator, math.maxInt(usize));
lib/std/compress/deflate/decompressor.zig+19-6
...@@ -334,7 +334,10 @@ pub fn Decompressor(comptime ReaderType: type) type {...@@ -334,7 +334,10 @@ pub fn Decompressor(comptime ReaderType: type) type {
334334
335 // Next step in the decompression,335 // Next step in the decompression,
336 // and decompression state.336 // and decompression state.
337 step: fn (*Self) Error!void,337 step: if (@import("builtin").zig_backend == .stage1)
338 fn (*Self) Error!void
339 else
340 *const fn (*Self) Error!void,
338 step_state: DecompressorState,341 step_state: DecompressorState,
339 final: bool,342 final: bool,
340 err: ?Error,343 err: ?Error,
...@@ -479,7 +482,13 @@ pub fn Decompressor(comptime ReaderType: type) type {...@@ -479,7 +482,13 @@ pub fn Decompressor(comptime ReaderType: type) type {
479 }482 }
480483
481 pub fn close(self: *Self) ?Error {484 pub fn close(self: *Self) ?Error {
482 if (self.err == Error.EndOfStreamWithNoError) {485 if (@import("builtin").zig_backend == .stage1) {
486 if (self.err == Error.EndOfStreamWithNoError) {
487 return null;
488 }
489 return self.err;
490 }
491 if (self.err == @as(?Error, error.EndOfStreamWithNoError)) {
483 return null;492 return null;
484 }493 }
485 return self.err;494 return self.err;
...@@ -920,7 +929,8 @@ test "truncated input" {...@@ -920,7 +929,8 @@ test "truncated input" {
920 };929 };
921930
922 for (tests) |t| {931 for (tests) |t| {
923 var r = io.fixedBufferStream(t.input).reader();932 var fib = io.fixedBufferStream(t.input);
933 const r = fib.reader();
924 var z = try decompressor(testing.allocator, r, null);934 var z = try decompressor(testing.allocator, r, null);
925 defer z.deinit();935 defer z.deinit();
926 var zr = z.reader();936 var zr = z.reader();
...@@ -959,7 +969,8 @@ test "Go non-regression test for 9842" {...@@ -959,7 +969,8 @@ test "Go non-regression test for 9842" {
959 };969 };
960970
961 for (tests) |t| {971 for (tests) |t| {
962 const reader = std.io.fixedBufferStream(t.input).reader();972 var fib = std.io.fixedBufferStream(t.input);
973 const reader = fib.reader();
963 var decomp = try decompressor(testing.allocator, reader, null);974 var decomp = try decompressor(testing.allocator, reader, null);
964 defer decomp.deinit();975 defer decomp.deinit();
965976
...@@ -1017,7 +1028,8 @@ test "inflate A Tale of Two Cities (1859) intro" {...@@ -1017,7 +1028,8 @@ test "inflate A Tale of Two Cities (1859) intro" {
1017 \\1028 \\
1018 ;1029 ;
10191030
1020 const reader = std.io.fixedBufferStream(&compressed).reader();1031 var fib = std.io.fixedBufferStream(&compressed);
1032 const reader = fib.reader();
1021 var decomp = try decompressor(testing.allocator, reader, null);1033 var decomp = try decompressor(testing.allocator, reader, null);
1022 defer decomp.deinit();1034 defer decomp.deinit();
10231035
...@@ -1082,7 +1094,8 @@ test "fuzzing" {...@@ -1082,7 +1094,8 @@ test "fuzzing" {
10821094
1083fn decompress(input: []const u8) !void {1095fn decompress(input: []const u8) !void {
1084 const allocator = testing.allocator;1096 const allocator = testing.allocator;
1085 const reader = std.io.fixedBufferStream(input).reader();1097 var fib = std.io.fixedBufferStream(input);
1098 const reader = fib.reader();
1086 var decomp = try decompressor(allocator, reader, null);1099 var decomp = try decompressor(allocator, reader, null);
1087 defer decomp.deinit();1100 defer decomp.deinit();
1088 var output = try decomp.reader().readAllAlloc(allocator, math.maxInt(usize));1101 var output = try decomp.reader().readAllAlloc(allocator, math.maxInt(usize));
lib/std/compress/deflate/deflate_fast_test.zig+6-12
...@@ -78,11 +78,8 @@ test "best speed" {...@@ -78,11 +78,8 @@ test "best speed" {
78 var decompressed = try testing.allocator.alloc(u8, want.items.len);78 var decompressed = try testing.allocator.alloc(u8, want.items.len);
79 defer testing.allocator.free(decompressed);79 defer testing.allocator.free(decompressed);
8080
81 var decomp = try inflate.decompressor(81 var fib = io.fixedBufferStream(compressed.items);
82 testing.allocator,82 var decomp = try inflate.decompressor(testing.allocator, fib.reader(), null);
83 io.fixedBufferStream(compressed.items).reader(),
84 null,
85 );
86 defer decomp.deinit();83 defer decomp.deinit();
8784
88 var read = try decomp.reader().readAll(decompressed);85 var read = try decomp.reader().readAll(decompressed);
...@@ -122,13 +119,13 @@ test "best speed max match offset" {...@@ -122,13 +119,13 @@ test "best speed max match offset" {
122 // zeros1 is between 0 and 30 zeros.119 // zeros1 is between 0 and 30 zeros.
123 // The difference between the two abc's will be offset, which120 // The difference between the two abc's will be offset, which
124 // is max_match_offset plus or minus a small adjustment.121 // is max_match_offset plus or minus a small adjustment.
125 var src_len: usize = @intCast(usize, offset + abc.len + @intCast(i32, extra));122 var src_len: usize = @intCast(usize, offset + @as(i32, abc.len) + @intCast(i32, extra));
126 var src = try testing.allocator.alloc(u8, src_len);123 var src = try testing.allocator.alloc(u8, src_len);
127 defer testing.allocator.free(src);124 defer testing.allocator.free(src);
128125
129 mem.copy(u8, src, abc);126 mem.copy(u8, src, abc);
130 if (!do_match_before) {127 if (!do_match_before) {
131 var src_offset: usize = @intCast(usize, offset - xyz.len);128 var src_offset: usize = @intCast(usize, offset - @as(i32, xyz.len));
132 mem.copy(u8, src[src_offset..], xyz);129 mem.copy(u8, src[src_offset..], xyz);
133 }130 }
134 var src_offset: usize = @intCast(usize, offset);131 var src_offset: usize = @intCast(usize, offset);
...@@ -149,11 +146,8 @@ test "best speed max match offset" {...@@ -149,11 +146,8 @@ test "best speed max match offset" {
149 var decompressed = try testing.allocator.alloc(u8, src.len);146 var decompressed = try testing.allocator.alloc(u8, src.len);
150 defer testing.allocator.free(decompressed);147 defer testing.allocator.free(decompressed);
151148
152 var decomp = try inflate.decompressor(149 var fib = io.fixedBufferStream(compressed.items);
153 testing.allocator,150 var decomp = try inflate.decompressor(testing.allocator, fib.reader(), null);
154 io.fixedBufferStream(compressed.items).reader(),
155 null,
156 );
157 defer decomp.deinit();151 defer decomp.deinit();
158 var read = try decomp.reader().readAll(decompressed);152 var read = try decomp.reader().readAll(decompressed);
159 _ = decomp.close();153 _ = decomp.close();
lib/std/crypto/argon2.zig+2
...@@ -897,6 +897,7 @@ test "kdf" {...@@ -897,6 +897,7 @@ test "kdf" {
897}897}
898898
899test "phc format hasher" {899test "phc format hasher" {
900 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
900 const allocator = std.testing.allocator;901 const allocator = std.testing.allocator;
901 const password = "testpass";902 const password = "testpass";
902903
...@@ -912,6 +913,7 @@ test "phc format hasher" {...@@ -912,6 +913,7 @@ test "phc format hasher" {
912}913}
913914
914test "password hash and password verify" {915test "password hash and password verify" {
916 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
915 const allocator = std.testing.allocator;917 const allocator = std.testing.allocator;
916 const password = "testpass";918 const password = "testpass";
917919
lib/std/crypto/bcrypt.zig+1
...@@ -802,6 +802,7 @@ test "bcrypt crypt format" {...@@ -802,6 +802,7 @@ test "bcrypt crypt format" {
802}802}
803803
804test "bcrypt phc format" {804test "bcrypt phc format" {
805 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
805 const hash_options = HashOptions{806 const hash_options = HashOptions{
806 .params = .{ .rounds_log = 5 },807 .params = .{ .rounds_log = 5 },
807 .encoding = .phc,808 .encoding = .phc,
lib/std/crypto/phc_encoding.zig+1
...@@ -260,6 +260,7 @@ fn kvSplit(str: []const u8) !struct { key: []const u8, value: []const u8 } {...@@ -260,6 +260,7 @@ fn kvSplit(str: []const u8) !struct { key: []const u8, value: []const u8 } {
260}260}
261261
262test "phc format - encoding/decoding" {262test "phc format - encoding/decoding" {
263 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
263 const Input = struct {264 const Input = struct {
264 str: []const u8,265 str: []const u8,
265 HashResult: type,266 HashResult: type,
lib/std/crypto/scrypt.zig+1
...@@ -683,6 +683,7 @@ test "unix-scrypt" {...@@ -683,6 +683,7 @@ test "unix-scrypt" {
683}683}
684684
685test "crypt format" {685test "crypt format" {
686 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
686 const str = "$7$C6..../....SodiumChloride$kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D";687 const str = "$7$C6..../....SodiumChloride$kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D";
687 const params = try crypt_format.deserialize(crypt_format.HashResult(32), str);688 const params = try crypt_format.deserialize(crypt_format.HashResult(32), str);
688 var buf: [str.len]u8 = undefined;689 var buf: [str.len]u8 = undefined;
lib/std/fmt.zig+48-22
...@@ -2111,7 +2111,6 @@ test "slice" {...@@ -2111,7 +2111,6 @@ test "slice" {
2111}2111}
21122112
2113test "escape non-printable" {2113test "escape non-printable" {
2114 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2115 try expectFmt("abc", "{s}", .{fmtSliceEscapeLower("abc")});2114 try expectFmt("abc", "{s}", .{fmtSliceEscapeLower("abc")});
2116 try expectFmt("ab\\xffc", "{s}", .{fmtSliceEscapeLower("ab\xffc")});2115 try expectFmt("ab\\xffc", "{s}", .{fmtSliceEscapeLower("ab\xffc")});
2117 try expectFmt("ab\\xFFc", "{s}", .{fmtSliceEscapeUpper("ab\xffc")});2116 try expectFmt("ab\\xFFc", "{s}", .{fmtSliceEscapeUpper("ab\xffc")});
...@@ -2148,7 +2147,6 @@ test "cstr" {...@@ -2148,7 +2147,6 @@ test "cstr" {
2148}2147}
21492148
2150test "filesize" {2149test "filesize" {
2151 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2152 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeDec(42)});2150 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeDec(42)});
2153 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeBin(42)});2151 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeBin(42)});
2154 try expectFmt("file size: 63MB\n", "file size: {}\n", .{fmtIntSizeDec(63 * 1000 * 1000)});2152 try expectFmt("file size: 63MB\n", "file size: {}\n", .{fmtIntSizeDec(63 * 1000 * 1000)});
...@@ -2192,18 +2190,22 @@ test "enum" {...@@ -2192,18 +2190,22 @@ test "enum" {
2192}2190}
21932191
2194test "non-exhaustive enum" {2192test "non-exhaustive enum" {
2193 if (builtin.zig_backend == .stage1) {
2194 // stage1 fails to return fully qualified namespaces.
2195 return error.SkipZigTest;
2196 }
2195 const Enum = enum(u16) {2197 const Enum = enum(u16) {
2196 One = 0x000f,2198 One = 0x000f,
2197 Two = 0xbeef,2199 Two = 0xbeef,
2198 _,2200 _,
2199 };2201 };
2200 try expectFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});2202 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.One\n", "enum: {}\n", .{Enum.One});
2201 try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});2203 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
2202 try expectFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});2204 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});
2203 try expectFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});2205 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.One\n", "enum: {x}\n", .{Enum.One});
2204 try expectFmt("enum: Enum.Two\n", "enum: {x}\n", .{Enum.Two});2206 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.Two\n", "enum: {x}\n", .{Enum.Two});
2205 try expectFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});2207 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.Two\n", "enum: {X}\n", .{Enum.Two});
2206 try expectFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});2208 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
2207}2209}
22082210
2209test "float.scientific" {2211test "float.scientific" {
...@@ -2223,6 +2225,7 @@ test "float.scientific.precision" {...@@ -2223,6 +2225,7 @@ test "float.scientific.precision" {
2223}2225}
22242226
2225test "float.special" {2227test "float.special" {
2228 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
2226 try expectFmt("f64: nan", "f64: {}", .{math.nan_f64});2229 try expectFmt("f64: nan", "f64: {}", .{math.nan_f64});
2227 // negative nan is not defined by IEE 754,2230 // negative nan is not defined by IEE 754,
2228 // and ARM thus normalizes it to positive nan2231 // and ARM thus normalizes it to positive nan
...@@ -2234,6 +2237,7 @@ test "float.special" {...@@ -2234,6 +2237,7 @@ test "float.special" {
2234}2237}
22352238
2236test "float.hexadecimal.special" {2239test "float.hexadecimal.special" {
2240 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
2237 try expectFmt("f64: nan", "f64: {x}", .{math.nan_f64});2241 try expectFmt("f64: nan", "f64: {x}", .{math.nan_f64});
2238 // negative nan is not defined by IEE 754,2242 // negative nan is not defined by IEE 754,
2239 // and ARM thus normalizes it to positive nan2243 // and ARM thus normalizes it to positive nan
...@@ -2359,6 +2363,10 @@ test "custom" {...@@ -2359,6 +2363,10 @@ test "custom" {
2359}2363}
23602364
2361test "struct" {2365test "struct" {
2366 if (builtin.zig_backend == .stage1) {
2367 // stage1 fails to return fully qualified namespaces.
2368 return error.SkipZigTest;
2369 }
2362 const S = struct {2370 const S = struct {
2363 a: u32,2371 a: u32,
2364 b: anyerror,2372 b: anyerror,
...@@ -2369,7 +2377,7 @@ test "struct" {...@@ -2369,7 +2377,7 @@ test "struct" {
2369 .b = error.Unused,2377 .b = error.Unused,
2370 };2378 };
23712379
2372 try expectFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst});2380 try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
2373 // Tuples2381 // Tuples
2374 try expectFmt("{ }", "{}", .{.{}});2382 try expectFmt("{ }", "{}", .{.{}});
2375 try expectFmt("{ -1 }", "{}", .{.{-1}});2383 try expectFmt("{ -1 }", "{}", .{.{-1}});
...@@ -2377,6 +2385,10 @@ test "struct" {...@@ -2377,6 +2385,10 @@ test "struct" {
2377}2385}
23782386
2379test "union" {2387test "union" {
2388 if (builtin.zig_backend == .stage1) {
2389 // stage1 fails to return fully qualified namespaces.
2390 return error.SkipZigTest;
2391 }
2380 const TU = union(enum) {2392 const TU = union(enum) {
2381 float: f32,2393 float: f32,
2382 int: u32,2394 int: u32,
...@@ -2396,17 +2408,21 @@ test "union" {...@@ -2396,17 +2408,21 @@ test "union" {
2396 const uu_inst = UU{ .int = 456 };2408 const uu_inst = UU{ .int = 456 };
2397 const eu_inst = EU{ .float = 321.123 };2409 const eu_inst = EU{ .float = 321.123 };
23982410
2399 try expectFmt("TU{ .int = 123 }", "{}", .{tu_inst});2411 try expectFmt("fmt.test.union.TU{ .int = 123 }", "{}", .{tu_inst});
24002412
2401 var buf: [100]u8 = undefined;2413 var buf: [100]u8 = undefined;
2402 const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});2414 const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});
2403 try std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@"));2415 try std.testing.expect(mem.eql(u8, uu_result[0..18], "fmt.test.union.UU@"));
24042416
2405 const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst});2417 const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst});
2406 try std.testing.expect(mem.eql(u8, eu_result[0..3], "EU@"));2418 try std.testing.expect(mem.eql(u8, eu_result[0..18], "fmt.test.union.EU@"));
2407}2419}
24082420
2409test "enum" {2421test "enum" {
2422 if (builtin.zig_backend == .stage1) {
2423 // stage1 fails to return fully qualified namespaces.
2424 return error.SkipZigTest;
2425 }
2410 const E = enum {2426 const E = enum {
2411 One,2427 One,
2412 Two,2428 Two,
...@@ -2415,10 +2431,14 @@ test "enum" {...@@ -2415,10 +2431,14 @@ test "enum" {
24152431
2416 const inst = E.Two;2432 const inst = E.Two;
24172433
2418 try expectFmt("E.Two", "{}", .{inst});2434 try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
2419}2435}
24202436
2421test "struct.self-referential" {2437test "struct.self-referential" {
2438 if (builtin.zig_backend == .stage1) {
2439 // stage1 fails to return fully qualified namespaces.
2440 return error.SkipZigTest;
2441 }
2422 const S = struct {2442 const S = struct {
2423 const SelfType = @This();2443 const SelfType = @This();
2424 a: ?*SelfType,2444 a: ?*SelfType,
...@@ -2429,10 +2449,14 @@ test "struct.self-referential" {...@@ -2429,10 +2449,14 @@ test "struct.self-referential" {
2429 };2449 };
2430 inst.a = &inst;2450 inst.a = &inst;
24312451
2432 try expectFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", .{inst});2452 try expectFmt("fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ ... } } } }", "{}", .{inst});
2433}2453}
24342454
2435test "struct.zero-size" {2455test "struct.zero-size" {
2456 if (builtin.zig_backend == .stage1) {
2457 // stage1 fails to return fully qualified namespaces.
2458 return error.SkipZigTest;
2459 }
2436 const A = struct {2460 const A = struct {
2437 fn foo() void {}2461 fn foo() void {}
2438 };2462 };
...@@ -2444,11 +2468,10 @@ test "struct.zero-size" {...@@ -2444,11 +2468,10 @@ test "struct.zero-size" {
2444 const a = A{};2468 const a = A{};
2445 const b = B{ .a = a, .c = 0 };2469 const b = B{ .a = a, .c = 0 };
24462470
2447 try expectFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b});2471 try expectFmt("fmt.test.struct.zero-size.B{ .a = fmt.test.struct.zero-size.A{ }, .c = 0 }", "{}", .{b});
2448}2472}
24492473
2450test "bytes.hex" {2474test "bytes.hex" {
2451 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2452 const some_bytes = "\xCA\xFE\xBA\xBE";2475 const some_bytes = "\xCA\xFE\xBA\xBE";
2453 try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(some_bytes)});2476 try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(some_bytes)});
2454 try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{fmtSliceHexUpper(some_bytes)});2477 try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{fmtSliceHexUpper(some_bytes)});
...@@ -2480,7 +2503,6 @@ pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {...@@ -2480,7 +2503,6 @@ pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {
2480}2503}
24812504
2482test "hexToBytes" {2505test "hexToBytes" {
2483 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2484 var buf: [32]u8 = undefined;2506 var buf: [32]u8 = undefined;
2485 try expectFmt("90" ** 32, "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "90" ** 32))});2507 try expectFmt("90" ** 32, "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "90" ** 32))});
2486 try expectFmt("ABCD", "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "ABCD"))});2508 try expectFmt("ABCD", "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "ABCD"))});
...@@ -2512,6 +2534,10 @@ test "formatFloatValue with comptime_float" {...@@ -2512,6 +2534,10 @@ test "formatFloatValue with comptime_float" {
2512}2534}
25132535
2514test "formatType max_depth" {2536test "formatType max_depth" {
2537 if (builtin.zig_backend == .stage1) {
2538 // stage1 fails to return fully qualified namespaces.
2539 return error.SkipZigTest;
2540 }
2515 const Vec2 = struct {2541 const Vec2 = struct {
2516 const SelfType = @This();2542 const SelfType = @This();
2517 x: f32,2543 x: f32,
...@@ -2562,19 +2588,19 @@ test "formatType max_depth" {...@@ -2562,19 +2588,19 @@ test "formatType max_depth" {
2562 var buf: [1000]u8 = undefined;2588 var buf: [1000]u8 = undefined;
2563 var fbs = std.io.fixedBufferStream(&buf);2589 var fbs = std.io.fixedBufferStream(&buf);
2564 try formatType(inst, "", FormatOptions{}, fbs.writer(), 0);2590 try formatType(inst, "", FormatOptions{}, fbs.writer(), 0);
2565 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "S{ ... }"));2591 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "fmt.test.formatType max_depth.S{ ... }"));
25662592
2567 fbs.reset();2593 fbs.reset();
2568 try formatType(inst, "", FormatOptions{}, fbs.writer(), 1);2594 try formatType(inst, "", FormatOptions{}, fbs.writer(), 1);
2569 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));2595 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "fmt.test.formatType max_depth.S{ .a = fmt.test.formatType max_depth.S{ ... }, .tu = fmt.test.formatType max_depth.TU{ ... }, .e = fmt.test.formatType max_depth.E.Two, .vec = (10.200,2.220) }"));
25702596
2571 fbs.reset();2597 fbs.reset();
2572 try formatType(inst, "", FormatOptions{}, fbs.writer(), 2);2598 try formatType(inst, "", FormatOptions{}, fbs.writer(), 2);
2573 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }"));2599 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "fmt.test.formatType max_depth.S{ .a = fmt.test.formatType max_depth.S{ .a = fmt.test.formatType max_depth.S{ ... }, .tu = fmt.test.formatType max_depth.TU{ ... }, .e = fmt.test.formatType max_depth.E.Two, .vec = (10.200,2.220) }, .tu = fmt.test.formatType max_depth.TU{ .ptr = fmt.test.formatType max_depth.TU{ ... } }, .e = fmt.test.formatType max_depth.E.Two, .vec = (10.200,2.220) }"));
25742600
2575 fbs.reset();2601 fbs.reset();
2576 try formatType(inst, "", FormatOptions{}, fbs.writer(), 3);2602 try formatType(inst, "", FormatOptions{}, fbs.writer(), 3);
2577 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }"));2603 try std.testing.expect(mem.eql(u8, fbs.getWritten(), "fmt.test.formatType max_depth.S{ .a = fmt.test.formatType max_depth.S{ .a = fmt.test.formatType max_depth.S{ .a = fmt.test.formatType max_depth.S{ ... }, .tu = fmt.test.formatType max_depth.TU{ ... }, .e = fmt.test.formatType max_depth.E.Two, .vec = (10.200,2.220) }, .tu = fmt.test.formatType max_depth.TU{ .ptr = fmt.test.formatType max_depth.TU{ ... } }, .e = fmt.test.formatType max_depth.E.Two, .vec = (10.200,2.220) }, .tu = fmt.test.formatType max_depth.TU{ .ptr = fmt.test.formatType max_depth.TU{ .ptr = fmt.test.formatType max_depth.TU{ ... } } }, .e = fmt.test.formatType max_depth.E.Two, .vec = (10.200,2.220) }"));
2578}2604}
25792605
2580test "positional" {2606test "positional" {
lib/std/io/stream_source.zig-1
...@@ -114,7 +114,6 @@ test "StreamSource (mutable buffer)" {...@@ -114,7 +114,6 @@ test "StreamSource (mutable buffer)" {
114}114}
115115
116test "StreamSource (const buffer)" {116test "StreamSource (const buffer)" {
117 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
118 const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);117 const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);
119 var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };118 var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };
120119
lib/std/math/copysign.zig+1
...@@ -13,6 +13,7 @@ pub fn copysign(magnitude: anytype, sign: @TypeOf(magnitude)) @TypeOf(magnitude)...@@ -13,6 +13,7 @@ pub fn copysign(magnitude: anytype, sign: @TypeOf(magnitude)) @TypeOf(magnitude)
13}13}
1414
15test "math.copysign" {15test "math.copysign" {
16 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
16 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {17 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
17 try expect(copysign(@as(T, 1.0), @as(T, 1.0)) == 1.0);18 try expect(copysign(@as(T, 1.0), @as(T, 1.0)) == 1.0);
18 try expect(copysign(@as(T, 2.0), @as(T, -2.0)) == -2.0);19 try expect(copysign(@as(T, 2.0), @as(T, -2.0)) == -2.0);
lib/std/math/signbit.zig+1
...@@ -10,6 +10,7 @@ pub fn signbit(x: anytype) bool {...@@ -10,6 +10,7 @@ pub fn signbit(x: anytype) bool {
10}10}
1111
12test "math.signbit" {12test "math.signbit" {
13 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
13 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {14 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
14 try expect(!signbit(@as(T, 0.0)));15 try expect(!signbit(@as(T, 0.0)));
15 try expect(!signbit(@as(T, 1.0)));16 try expect(!signbit(@as(T, 1.0)));
lib/std/mem.zig+1
...@@ -2080,6 +2080,7 @@ fn testReadIntImpl() !void {...@@ -2080,6 +2080,7 @@ fn testReadIntImpl() !void {
2080}2080}
20812081
2082test "writeIntSlice" {2082test "writeIntSlice" {
2083 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
2083 try testWriteIntImpl();2084 try testWriteIntImpl();
2084 comptime try testWriteIntImpl();2085 comptime try testWriteIntImpl();
2085}2086}
lib/std/priority_queue.zig+14
...@@ -286,6 +286,7 @@ const PQlt = PriorityQueue(u32, void, lessThan);...@@ -286,6 +286,7 @@ const PQlt = PriorityQueue(u32, void, lessThan);
286const PQgt = PriorityQueue(u32, void, greaterThan);286const PQgt = PriorityQueue(u32, void, greaterThan);
287287
288test "std.PriorityQueue: add and remove min heap" {288test "std.PriorityQueue: add and remove min heap" {
289 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
289 var queue = PQlt.init(testing.allocator, {});290 var queue = PQlt.init(testing.allocator, {});
290 defer queue.deinit();291 defer queue.deinit();
291292
...@@ -304,6 +305,7 @@ test "std.PriorityQueue: add and remove min heap" {...@@ -304,6 +305,7 @@ test "std.PriorityQueue: add and remove min heap" {
304}305}
305306
306test "std.PriorityQueue: add and remove same min heap" {307test "std.PriorityQueue: add and remove same min heap" {
308 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
307 var queue = PQlt.init(testing.allocator, {});309 var queue = PQlt.init(testing.allocator, {});
308 defer queue.deinit();310 defer queue.deinit();
309311
...@@ -353,6 +355,7 @@ test "std.PriorityQueue: peek" {...@@ -353,6 +355,7 @@ test "std.PriorityQueue: peek" {
353}355}
354356
355test "std.PriorityQueue: sift up with odd indices" {357test "std.PriorityQueue: sift up with odd indices" {
358 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
356 var queue = PQlt.init(testing.allocator, {});359 var queue = PQlt.init(testing.allocator, {});
357 defer queue.deinit();360 defer queue.deinit();
358 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };361 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
...@@ -367,6 +370,7 @@ test "std.PriorityQueue: sift up with odd indices" {...@@ -367,6 +370,7 @@ test "std.PriorityQueue: sift up with odd indices" {
367}370}
368371
369test "std.PriorityQueue: addSlice" {372test "std.PriorityQueue: addSlice" {
373 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
370 var queue = PQlt.init(testing.allocator, {});374 var queue = PQlt.init(testing.allocator, {});
371 defer queue.deinit();375 defer queue.deinit();
372 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };376 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
...@@ -412,6 +416,7 @@ test "std.PriorityQueue: fromOwnedSlice" {...@@ -412,6 +416,7 @@ test "std.PriorityQueue: fromOwnedSlice" {
412}416}
413417
414test "std.PriorityQueue: add and remove max heap" {418test "std.PriorityQueue: add and remove max heap" {
419 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
415 var queue = PQgt.init(testing.allocator, {});420 var queue = PQgt.init(testing.allocator, {});
416 defer queue.deinit();421 defer queue.deinit();
417422
...@@ -430,6 +435,7 @@ test "std.PriorityQueue: add and remove max heap" {...@@ -430,6 +435,7 @@ test "std.PriorityQueue: add and remove max heap" {
430}435}
431436
432test "std.PriorityQueue: add and remove same max heap" {437test "std.PriorityQueue: add and remove same max heap" {
438 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
433 var queue = PQgt.init(testing.allocator, {});439 var queue = PQgt.init(testing.allocator, {});
434 defer queue.deinit();440 defer queue.deinit();
435441
...@@ -470,6 +476,7 @@ test "std.PriorityQueue: iterator" {...@@ -470,6 +476,7 @@ test "std.PriorityQueue: iterator" {
470}476}
471477
472test "std.PriorityQueue: remove at index" {478test "std.PriorityQueue: remove at index" {
479 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
473 var queue = PQlt.init(testing.allocator, {});480 var queue = PQlt.init(testing.allocator, {});
474 defer queue.deinit();481 defer queue.deinit();
475482
...@@ -505,6 +512,7 @@ test "std.PriorityQueue: iterator while empty" {...@@ -505,6 +512,7 @@ test "std.PriorityQueue: iterator while empty" {
505}512}
506513
507test "std.PriorityQueue: shrinkAndFree" {514test "std.PriorityQueue: shrinkAndFree" {
515 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
508 var queue = PQlt.init(testing.allocator, {});516 var queue = PQlt.init(testing.allocator, {});
509 defer queue.deinit();517 defer queue.deinit();
510518
...@@ -528,6 +536,7 @@ test "std.PriorityQueue: shrinkAndFree" {...@@ -528,6 +536,7 @@ test "std.PriorityQueue: shrinkAndFree" {
528}536}
529537
530test "std.PriorityQueue: update min heap" {538test "std.PriorityQueue: update min heap" {
539 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
531 var queue = PQlt.init(testing.allocator, {});540 var queue = PQlt.init(testing.allocator, {});
532 defer queue.deinit();541 defer queue.deinit();
533542
...@@ -543,6 +552,7 @@ test "std.PriorityQueue: update min heap" {...@@ -543,6 +552,7 @@ test "std.PriorityQueue: update min heap" {
543}552}
544553
545test "std.PriorityQueue: update same min heap" {554test "std.PriorityQueue: update same min heap" {
555 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
546 var queue = PQlt.init(testing.allocator, {});556 var queue = PQlt.init(testing.allocator, {});
547 defer queue.deinit();557 defer queue.deinit();
548558
...@@ -559,6 +569,7 @@ test "std.PriorityQueue: update same min heap" {...@@ -559,6 +569,7 @@ test "std.PriorityQueue: update same min heap" {
559}569}
560570
561test "std.PriorityQueue: update max heap" {571test "std.PriorityQueue: update max heap" {
572 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
562 var queue = PQgt.init(testing.allocator, {});573 var queue = PQgt.init(testing.allocator, {});
563 defer queue.deinit();574 defer queue.deinit();
564575
...@@ -574,6 +585,7 @@ test "std.PriorityQueue: update max heap" {...@@ -574,6 +585,7 @@ test "std.PriorityQueue: update max heap" {
574}585}
575586
576test "std.PriorityQueue: update same max heap" {587test "std.PriorityQueue: update same max heap" {
588 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
577 var queue = PQgt.init(testing.allocator, {});589 var queue = PQgt.init(testing.allocator, {});
578 defer queue.deinit();590 defer queue.deinit();
579591
...@@ -590,6 +602,7 @@ test "std.PriorityQueue: update same max heap" {...@@ -590,6 +602,7 @@ test "std.PriorityQueue: update same max heap" {
590}602}
591603
592test "std.PriorityQueue: siftUp in remove" {604test "std.PriorityQueue: siftUp in remove" {
605 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
593 var queue = PQlt.init(testing.allocator, {});606 var queue = PQlt.init(testing.allocator, {});
594 defer queue.deinit();607 defer queue.deinit();
595608
...@@ -610,6 +623,7 @@ fn contextLessThan(context: []const u32, a: usize, b: usize) Order {...@@ -610,6 +623,7 @@ fn contextLessThan(context: []const u32, a: usize, b: usize) Order {
610const CPQlt = PriorityQueue(usize, []const u32, contextLessThan);623const CPQlt = PriorityQueue(usize, []const u32, contextLessThan);
611624
612test "std.PriorityQueue: add and remove min heap with contextful comparator" {625test "std.PriorityQueue: add and remove min heap with contextful comparator" {
626 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
613 const context = [_]u32{ 5, 3, 4, 2, 2, 8, 0 };627 const context = [_]u32{ 5, 3, 4, 2, 2, 8, 0 };
614628
615 var queue = CPQlt.init(testing.allocator, context[0..]);629 var queue = CPQlt.init(testing.allocator, context[0..]);
lib/std/tz.zig+3
...@@ -214,6 +214,7 @@ pub const Tz = struct {...@@ -214,6 +214,7 @@ pub const Tz = struct {
214};214};
215215
216test "slim" {216test "slim" {
217 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
217 const data = @embedFile("tz/asia_tokyo.tzif");218 const data = @embedFile("tz/asia_tokyo.tzif");
218 var in_stream = std.io.fixedBufferStream(data);219 var in_stream = std.io.fixedBufferStream(data);
219220
...@@ -227,6 +228,7 @@ test "slim" {...@@ -227,6 +228,7 @@ test "slim" {
227}228}
228229
229test "fat" {230test "fat" {
231 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
230 const data = @embedFile("tz/antarctica_davis.tzif");232 const data = @embedFile("tz/antarctica_davis.tzif");
231 var in_stream = std.io.fixedBufferStream(data);233 var in_stream = std.io.fixedBufferStream(data);
232234
...@@ -239,6 +241,7 @@ test "fat" {...@@ -239,6 +241,7 @@ test "fat" {
239}241}
240242
241test "legacy" {243test "legacy" {
244 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
242 // Taken from Slackware 8.0, from 2001245 // Taken from Slackware 8.0, from 2001
243 const data = @embedFile("tz/europe_vatican.tzif");246 const data = @embedFile("tz/europe_vatican.tzif");
244 var in_stream = std.io.fixedBufferStream(data);247 var in_stream = std.io.fixedBufferStream(data);
lib/std/unicode.zig-1
...@@ -804,7 +804,6 @@ pub fn fmtUtf16le(utf16le: []const u16) std.fmt.Formatter(formatUtf16le) {...@@ -804,7 +804,6 @@ pub fn fmtUtf16le(utf16le: []const u16) std.fmt.Formatter(formatUtf16le) {
804}804}
805805
806test "fmtUtf16le" {806test "fmtUtf16le" {
807 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
808 const expectFmt = std.testing.expectFmt;807 const expectFmt = std.testing.expectFmt;
809 try expectFmt("", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral(""))});808 try expectFmt("", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral(""))});
810 try expectFmt("foo", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral("foo"))});809 try expectFmt("foo", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral("foo"))});
lib/std/x.zig-1
...@@ -13,7 +13,6 @@ pub const net = struct {...@@ -13,7 +13,6 @@ pub const net = struct {
13};13};
1414
15test {15test {
16 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
17 inline for (.{ os, net }) |module| {16 inline for (.{ os, net }) |module| {
18 std.testing.refAllDecls(module);17 std.testing.refAllDecls(module);
19 }18 }
lib/std/x/os/io.zig+1
...@@ -117,6 +117,7 @@ pub const Reactor = struct {...@@ -117,6 +117,7 @@ pub const Reactor = struct {
117};117};
118118
119test "reactor/linux: drive async tcp client/listener pair" {119test "reactor/linux: drive async tcp client/listener pair" {
120 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
120 if (native_os.tag != .linux) return error.SkipZigTest;121 if (native_os.tag != .linux) return error.SkipZigTest;
121122
122 const ip = std.x.net.ip;123 const ip = std.x.net.ip;
lib/std/x/os/net.zig+1-1
...@@ -381,7 +381,7 @@ pub const IPv6 = extern struct {...@@ -381,7 +381,7 @@ pub const IPv6 = extern struct {
381 });381 });
382 }382 }
383383
384 const zero_span = span: {384 const zero_span: struct { from: usize, to: usize } = span: {
385 var i: usize = 0;385 var i: usize = 0;
386 while (i < self.octets.len) : (i += 2) {386 while (i < self.octets.len) : (i += 2) {
387 if (self.octets[i] == 0 and self.octets[i + 1] == 0) break;387 if (self.octets[i] == 0 and self.octets[i + 1] == 0) break;
src/AstGen.zig+7
...@@ -2753,7 +2753,10 @@ fn varDecl(...@@ -2753,7 +2753,10 @@ fn varDecl(
2753 const result_loc: ResultLoc = if (type_node != 0) .{2753 const result_loc: ResultLoc = if (type_node != 0) .{
2754 .ty = try typeExpr(gz, scope, type_node),2754 .ty = try typeExpr(gz, scope, type_node),
2755 } else .none;2755 } else .none;
2756 const prev_anon_name_strategy = gz.anon_name_strategy;
2757 gz.anon_name_strategy = .dbg_var;
2756 const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);2758 const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);
2759 gz.anon_name_strategy = prev_anon_name_strategy;
27572760
2758 try gz.addDbgVar(.dbg_var_val, ident_name, init_inst);2761 try gz.addDbgVar(.dbg_var_val, ident_name, init_inst);
27592762
...@@ -2777,6 +2780,7 @@ fn varDecl(...@@ -2777,6 +2780,7 @@ fn varDecl(
2777 var init_scope = gz.makeSubBlock(scope);2780 var init_scope = gz.makeSubBlock(scope);
2778 // we may add more instructions to gz before stacking init_scope2781 // we may add more instructions to gz before stacking init_scope
2779 init_scope.instructions_top = GenZir.unstacked_top;2782 init_scope.instructions_top = GenZir.unstacked_top;
2783 init_scope.anon_name_strategy = .dbg_var;
2780 defer init_scope.unstack();2784 defer init_scope.unstack();
27812785
2782 var resolve_inferred_alloc: Zir.Inst.Ref = .none;2786 var resolve_inferred_alloc: Zir.Inst.Ref = .none;
...@@ -2956,7 +2960,10 @@ fn varDecl(...@@ -2956,7 +2960,10 @@ fn varDecl(
2956 resolve_inferred_alloc = alloc;2960 resolve_inferred_alloc = alloc;
2957 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };2961 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };
2958 };2962 };
2963 const prev_anon_name_strategy = gz.anon_name_strategy;
2964 gz.anon_name_strategy = .dbg_var;
2959 _ = try reachableExprComptime(gz, scope, var_data.result_loc, var_decl.ast.init_node, node, is_comptime);2965 _ = try reachableExprComptime(gz, scope, var_data.result_loc, var_decl.ast.init_node, node, is_comptime);
2966 gz.anon_name_strategy = prev_anon_name_strategy;
2960 if (resolve_inferred_alloc != .none) {2967 if (resolve_inferred_alloc != .none) {
2961 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);2968 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
2962 }2969 }
src/Module.zig+5-2
...@@ -3790,9 +3790,12 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -3790,9 +3790,12 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
3790 defer liveness.deinit(gpa);3790 defer liveness.deinit(gpa);
37913791
3792 if (builtin.mode == .Debug and mod.comp.verbose_air) {3792 if (builtin.mode == .Debug and mod.comp.verbose_air) {
3793 std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name});3793 const fqn = try decl.getFullyQualifiedName(mod);
3794 defer mod.gpa.free(fqn);
3795
3796 std.debug.print("# Begin Function AIR: {s}:\n", .{fqn});
3794 @import("print_air.zig").dump(mod, air, liveness);3797 @import("print_air.zig").dump(mod, air, liveness);
3795 std.debug.print("# End Function AIR: {s}\n\n", .{decl.name});3798 std.debug.print("# End Function AIR: {s}\n\n", .{fqn});
3796 }3799 }
37973800
3798 mod.comp.bin_file.updateFunc(mod, func, air, liveness) catch |err| switch (err) {3801 mod.comp.bin_file.updateFunc(mod, func, air, liveness) catch |err| switch (err) {
src/Sema.zig+82-60
...@@ -914,9 +914,9 @@ fn analyzeBodyInner(...@@ -914,9 +914,9 @@ fn analyzeBodyInner(
914 // zig fmt: off914 // zig fmt: off
915 .variable => try sema.zirVarExtended( block, extended),915 .variable => try sema.zirVarExtended( block, extended),
916 .struct_decl => try sema.zirStructDecl( block, extended, inst),916 .struct_decl => try sema.zirStructDecl( block, extended, inst),
917 .enum_decl => try sema.zirEnumDecl( block, extended),917 .enum_decl => try sema.zirEnumDecl( block, extended, inst),
918 .union_decl => try sema.zirUnionDecl( block, extended, inst),918 .union_decl => try sema.zirUnionDecl( block, extended, inst),
919 .opaque_decl => try sema.zirOpaqueDecl( block, extended),919 .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst),
920 .this => try sema.zirThis( block, extended),920 .this => try sema.zirThis( block, extended),
921 .ret_addr => try sema.zirRetAddr( block, extended),921 .ret_addr => try sema.zirRetAddr( block, extended),
922 .builtin_src => try sema.zirBuiltinSrc( block, extended),922 .builtin_src => try sema.zirBuiltinSrc( block, extended),
...@@ -2101,7 +2101,7 @@ fn zirStructDecl(...@@ -2101,7 +2101,7 @@ fn zirStructDecl(
2101 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{2101 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2102 .ty = Type.type,2102 .ty = Type.type,
2103 .val = struct_val,2103 .val = struct_val,
2104 }, small.name_strategy, "struct");2104 }, small.name_strategy, "struct", inst);
2105 const new_decl = mod.declPtr(new_decl_index);2105 const new_decl = mod.declPtr(new_decl_index);
2106 new_decl.owns_tv = true;2106 new_decl.owns_tv = true;
2107 errdefer mod.abortAnonDecl(new_decl_index);2107 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -2133,6 +2133,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2133,6 +2133,7 @@ fn createAnonymousDeclTypeNamed(
2133 typed_value: TypedValue,2133 typed_value: TypedValue,
2134 name_strategy: Zir.Inst.NameStrategy,2134 name_strategy: Zir.Inst.NameStrategy,
2135 anon_prefix: []const u8,2135 anon_prefix: []const u8,
2136 inst: ?Zir.Inst.Index,
2136) !Decl.Index {2137) !Decl.Index {
2137 const mod = sema.mod;2138 const mod = sema.mod;
2138 const namespace = block.namespace;2139 const namespace = block.namespace;
...@@ -2152,11 +2153,13 @@ fn createAnonymousDeclTypeNamed(...@@ -2152,11 +2153,13 @@ fn createAnonymousDeclTypeNamed(
2152 const name = try std.fmt.allocPrintZ(sema.gpa, "{s}__{s}_{d}", .{2153 const name = try std.fmt.allocPrintZ(sema.gpa, "{s}__{s}_{d}", .{
2153 src_decl.name, anon_prefix, @enumToInt(new_decl_index),2154 src_decl.name, anon_prefix, @enumToInt(new_decl_index),
2154 });2155 });
2156 errdefer sema.gpa.free(name);
2155 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2157 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2156 return new_decl_index;2158 return new_decl_index;
2157 },2159 },
2158 .parent => {2160 .parent => {
2159 const name = try sema.gpa.dupeZ(u8, mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));2161 const name = try sema.gpa.dupeZ(u8, mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
2162 errdefer sema.gpa.free(name);
2160 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2163 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2161 return new_decl_index;2164 return new_decl_index;
2162 },2165 },
...@@ -2188,9 +2191,31 @@ fn createAnonymousDeclTypeNamed(...@@ -2188,9 +2191,31 @@ fn createAnonymousDeclTypeNamed(
21882191
2189 try buf.appendSlice(")");2192 try buf.appendSlice(")");
2190 const name = try buf.toOwnedSliceSentinel(0);2193 const name = try buf.toOwnedSliceSentinel(0);
2194 errdefer sema.gpa.free(name);
2191 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2195 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2192 return new_decl_index;2196 return new_decl_index;
2193 },2197 },
2198 .dbg_var => {
2199 const ref = Zir.indexToRef(inst.?);
2200 const zir_tags = sema.code.instructions.items(.tag);
2201 const zir_data = sema.code.instructions.items(.data);
2202 var i = inst.?;
2203 while (i < zir_tags.len) : (i += 1) switch (zir_tags[i]) {
2204 .dbg_var_ptr, .dbg_var_val => {
2205 if (zir_data[i].str_op.operand != ref) continue;
2206
2207 const name = try std.fmt.allocPrintZ(sema.gpa, "{s}.{s}", .{
2208 src_decl.name, zir_data[i].str_op.getStr(sema.code),
2209 });
2210 errdefer sema.gpa.free(name);
2211
2212 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2213 return new_decl_index;
2214 },
2215 else => {},
2216 };
2217 return sema.createAnonymousDeclTypeNamed(block, typed_value, .anon, anon_prefix, null);
2218 },
2194 }2219 }
2195}2220}
21962221
...@@ -2198,6 +2223,7 @@ fn zirEnumDecl(...@@ -2198,6 +2223,7 @@ fn zirEnumDecl(
2198 sema: *Sema,2223 sema: *Sema,
2199 block: *Block,2224 block: *Block,
2200 extended: Zir.Inst.Extended.InstData,2225 extended: Zir.Inst.Extended.InstData,
2226 inst: Zir.Inst.Index,
2201) CompileError!Air.Inst.Ref {2227) CompileError!Air.Inst.Ref {
2202 const tracy = trace(@src());2228 const tracy = trace(@src());
2203 defer tracy.end();2229 defer tracy.end();
...@@ -2252,7 +2278,7 @@ fn zirEnumDecl(...@@ -2252,7 +2278,7 @@ fn zirEnumDecl(
2252 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{2278 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2253 .ty = Type.type,2279 .ty = Type.type,
2254 .val = enum_val,2280 .val = enum_val,
2255 }, small.name_strategy, "enum");2281 }, small.name_strategy, "enum", inst);
2256 const new_decl = mod.declPtr(new_decl_index);2282 const new_decl = mod.declPtr(new_decl_index);
2257 new_decl.owns_tv = true;2283 new_decl.owns_tv = true;
2258 errdefer mod.abortAnonDecl(new_decl_index);2284 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -2472,7 +2498,7 @@ fn zirUnionDecl(...@@ -2472,7 +2498,7 @@ fn zirUnionDecl(
2472 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{2498 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2473 .ty = Type.type,2499 .ty = Type.type,
2474 .val = union_val,2500 .val = union_val,
2475 }, small.name_strategy, "union");2501 }, small.name_strategy, "union", inst);
2476 const new_decl = mod.declPtr(new_decl_index);2502 const new_decl = mod.declPtr(new_decl_index);
2477 new_decl.owns_tv = true;2503 new_decl.owns_tv = true;
2478 errdefer mod.abortAnonDecl(new_decl_index);2504 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -2504,6 +2530,7 @@ fn zirOpaqueDecl(...@@ -2504,6 +2530,7 @@ fn zirOpaqueDecl(
2504 sema: *Sema,2530 sema: *Sema,
2505 block: *Block,2531 block: *Block,
2506 extended: Zir.Inst.Extended.InstData,2532 extended: Zir.Inst.Extended.InstData,
2533 inst: Zir.Inst.Index,
2507) CompileError!Air.Inst.Ref {2534) CompileError!Air.Inst.Ref {
2508 const tracy = trace(@src());2535 const tracy = trace(@src());
2509 defer tracy.end();2536 defer tracy.end();
...@@ -2540,7 +2567,7 @@ fn zirOpaqueDecl(...@@ -2540,7 +2567,7 @@ fn zirOpaqueDecl(
2540 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{2567 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2541 .ty = Type.type,2568 .ty = Type.type,
2542 .val = opaque_val,2569 .val = opaque_val,
2543 }, small.name_strategy, "opaque");2570 }, small.name_strategy, "opaque", inst);
2544 const new_decl = mod.declPtr(new_decl_index);2571 const new_decl = mod.declPtr(new_decl_index);
2545 new_decl.owns_tv = true;2572 new_decl.owns_tv = true;
2546 errdefer mod.abortAnonDecl(new_decl_index);2573 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -2589,7 +2616,7 @@ fn zirErrorSetDecl(...@@ -2589,7 +2616,7 @@ fn zirErrorSetDecl(
2589 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{2616 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2590 .ty = Type.type,2617 .ty = Type.type,
2591 .val = error_set_val,2618 .val = error_set_val,
2592 }, name_strategy, "error");2619 }, name_strategy, "error", inst);
2593 const new_decl = mod.declPtr(new_decl_index);2620 const new_decl = mod.declPtr(new_decl_index);
2594 new_decl.owns_tv = true;2621 new_decl.owns_tv = true;
2595 errdefer mod.abortAnonDecl(new_decl_index);2622 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -4967,6 +4994,8 @@ fn lookupInNamespace(...@@ -4967,6 +4994,8 @@ fn lookupInNamespace(
4967 var it = check_ns.usingnamespace_set.iterator();4994 var it = check_ns.usingnamespace_set.iterator();
4968 while (it.next()) |entry| {4995 while (it.next()) |entry| {
4969 const sub_usingnamespace_decl_index = entry.key_ptr.*;4996 const sub_usingnamespace_decl_index = entry.key_ptr.*;
4997 // Skip the decl we're currently analysing.
4998 if (sub_usingnamespace_decl_index == sema.owner_decl_index) continue;
4970 const sub_usingnamespace_decl = mod.declPtr(sub_usingnamespace_decl_index);4999 const sub_usingnamespace_decl = mod.declPtr(sub_usingnamespace_decl_index);
4971 const sub_is_pub = entry.value_ptr.*;5000 const sub_is_pub = entry.value_ptr.*;
4972 if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScope()) {5001 if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScope()) {
...@@ -6180,6 +6209,17 @@ fn zirErrorToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -6180,6 +6209,17 @@ fn zirErrorToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
6180 }6209 }
6181 }6210 }
61826211
6212 const op_ty = sema.typeOf(op);
6213 try sema.resolveInferredErrorSetTy(block, src, op_ty);
6214 if (!op_ty.isAnyError()) {
6215 const names = op_ty.errorSetNames();
6216 switch (names.len) {
6217 0 => return sema.addConstant(result_ty, Value.zero),
6218 1 => return sema.addIntUnsigned(result_ty, sema.mod.global_error_set.get(names[0]).?),
6219 else => {},
6220 }
6221 }
6222
6183 try sema.requireRuntimeBlock(block, src);6223 try sema.requireRuntimeBlock(block, src);
6184 return block.addBitCast(result_ty, op_coerced);6224 return block.addBitCast(result_ty, op_coerced);
6185}6225}
...@@ -6558,7 +6598,7 @@ fn analyzeErrUnionPayload(...@@ -6558,7 +6598,7 @@ fn analyzeErrUnionPayload(
65586598
6559 // If the error set has no fields then no safety check is needed.6599 // If the error set has no fields then no safety check is needed.
6560 if (safety_check and block.wantSafety() and6600 if (safety_check and block.wantSafety() and
6561 err_union_ty.errorUnionSet().errorSetCardinality() != .zero)6601 !err_union_ty.errorUnionSet().errorSetIsEmpty())
6562 {6602 {
6563 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);6603 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);
6564 }6604 }
...@@ -6644,7 +6684,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -6644,7 +6684,7 @@ fn analyzeErrUnionPayloadPtr(
66446684
6645 // If the error set has no fields then no safety check is needed.6685 // If the error set has no fields then no safety check is needed.
6646 if (safety_check and block.wantSafety() and6686 if (safety_check and block.wantSafety() and
6647 err_union_ty.errorUnionSet().errorSetCardinality() != .zero)6687 !err_union_ty.errorUnionSet().errorSetIsEmpty())
6648 {6688 {
6649 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);6689 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);
6650 }6690 }
...@@ -11859,10 +11899,14 @@ fn zirBuiltinSrc(...@@ -11859,10 +11899,14 @@ fn zirBuiltinSrc(
11859 const file_name_val = blk: {11899 const file_name_val = blk: {
11860 var anon_decl = try block.startAnonDecl(src);11900 var anon_decl = try block.startAnonDecl(src);
11861 defer anon_decl.deinit();11901 defer anon_decl.deinit();
11862 const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena());11902 const relative_path = try fn_owner_decl.getFileScope().fullPath(sema.arena);
11903 const absolute_path = std.fs.realpathAlloc(sema.arena, relative_path) catch |err| {
11904 return sema.fail(block, src, "failed to get absolute path of file '{s}': {s}", .{ relative_path, @errorName(err) });
11905 };
11906 const aboslute_duped = try anon_decl.arena().dupeZ(u8, absolute_path);
11863 const new_decl = try anon_decl.finish(11907 const new_decl = try anon_decl.finish(
11864 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), name.len),11908 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), aboslute_duped.len),
11865 try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),11909 try Value.Tag.bytes.create(anon_decl.arena(), aboslute_duped[0 .. aboslute_duped.len + 1]),
11866 0, // default alignment11910 0, // default alignment
11867 );11911 );
11868 break :blk try Value.Tag.decl_ref.create(sema.arena, new_decl);11912 break :blk try Value.Tag.decl_ref.create(sema.arena, new_decl);
...@@ -11873,6 +11917,7 @@ fn zirBuiltinSrc(...@@ -11873,6 +11917,7 @@ fn zirBuiltinSrc(
11873 field_values[0] = file_name_val;11917 field_values[0] = file_name_val;
11874 // fn_name: [:0]const u8,11918 // fn_name: [:0]const u8,
11875 field_values[1] = func_name_val;11919 field_values[1] = func_name_val;
11920 // TODO these should be runtime only!
11876 // line: u3211921 // line: u32
11877 field_values[2] = try Value.Tag.int_u64.create(sema.arena, extra.line + 1);11922 field_values[2] = try Value.Tag.int_u64.create(sema.arena, extra.line + 1);
11878 // column: u32,11923 // column: u32,
...@@ -13712,10 +13757,10 @@ fn zirStructInit(...@@ -13712,10 +13757,10 @@ fn zirStructInit(
13712 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;13757 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
13713 const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);13758 const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
13714 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);13759 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
13760 const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
1371513761
13716 const init_inst = try sema.resolveInst(item.data.init);13762 const init_inst = try sema.resolveInst(item.data.init);
13717 if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| {13763 if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| {
13718 const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
13719 return sema.addConstantMaybeRef(13764 return sema.addConstantMaybeRef(
13720 block,13765 block,
13721 src,13766 src,
...@@ -13734,6 +13779,8 @@ fn zirStructInit(...@@ -13734,6 +13779,8 @@ fn zirStructInit(
13734 const alloc = try block.addTy(.alloc, alloc_ty);13779 const alloc = try block.addTy(.alloc, alloc_ty);
13735 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty);13780 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty);
13736 try sema.storePtr(block, src, field_ptr, init_inst);13781 try sema.storePtr(block, src, field_ptr, init_inst);
13782 const new_tag = try sema.addConstant(resolved_ty.unionTagTypeHypothetical(), tag_val);
13783 _ = try block.addBinOp(.set_union_tag, alloc, new_tag);
13737 return alloc;13784 return alloc;
13738 }13785 }
1373913786
...@@ -14614,7 +14661,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14614,7 +14661,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14614 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{14661 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
14615 .ty = Type.type,14662 .ty = Type.type,
14616 .val = enum_val,14663 .val = enum_val,
14617 }, .anon, "enum");14664 }, .anon, "enum", null);
14618 const new_decl = mod.declPtr(new_decl_index);14665 const new_decl = mod.declPtr(new_decl_index);
14619 new_decl.owns_tv = true;14666 new_decl.owns_tv = true;
14620 errdefer mod.abortAnonDecl(new_decl_index);14667 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -14704,7 +14751,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14704,7 +14751,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14704 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{14751 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
14705 .ty = Type.type,14752 .ty = Type.type,
14706 .val = opaque_val,14753 .val = opaque_val,
14707 }, .anon, "opaque");14754 }, .anon, "opaque", null);
14708 const new_decl = mod.declPtr(new_decl_index);14755 const new_decl = mod.declPtr(new_decl_index);
14709 new_decl.owns_tv = true;14756 new_decl.owns_tv = true;
14710 errdefer mod.abortAnonDecl(new_decl_index);14757 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -14755,7 +14802,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14755,7 +14802,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14755 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{14802 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
14756 .ty = Type.type,14803 .ty = Type.type,
14757 .val = new_union_val,14804 .val = new_union_val,
14758 }, .anon, "union");14805 }, .anon, "union", null);
14759 const new_decl = mod.declPtr(new_decl_index);14806 const new_decl = mod.declPtr(new_decl_index);
14760 new_decl.owns_tv = true;14807 new_decl.owns_tv = true;
14761 errdefer mod.abortAnonDecl(new_decl_index);14808 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -14923,7 +14970,7 @@ fn reifyStruct(...@@ -14923,7 +14970,7 @@ fn reifyStruct(
14923 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{14970 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
14924 .ty = Type.type,14971 .ty = Type.type,
14925 .val = new_struct_val,14972 .val = new_struct_val,
14926 }, .anon, "struct");14973 }, .anon, "struct", null);
14927 const new_decl = mod.declPtr(new_decl_index);14974 const new_decl = mod.declPtr(new_decl_index);
14928 new_decl.owns_tv = true;14975 new_decl.owns_tv = true;
14929 errdefer mod.abortAnonDecl(new_decl_index);14976 errdefer mod.abortAnonDecl(new_decl_index);
...@@ -19700,7 +19747,8 @@ fn coerce(...@@ -19700,7 +19747,8 @@ fn coerce(
19700 // pointer to tuple to slice19747 // pointer to tuple to slice
19701 if (inst_ty.isSinglePointer() and19748 if (inst_ty.isSinglePointer() and
19702 inst_ty.childType().isTuple() and19749 inst_ty.childType().isTuple() and
19703 !dest_info.mutable and dest_info.size == .Slice)19750 (!dest_info.mutable or inst_ty.ptrIsMutable() or inst_ty.childType().tupleFields().types.len == 0) and
19751 dest_info.size == .Slice)
19704 {19752 {
19705 return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src);19753 return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src);
19706 }19754 }
...@@ -23540,7 +23588,17 @@ pub fn resolveTypeFully(...@@ -23540,7 +23588,17 @@ pub fn resolveTypeFully(
23540 const child_ty = try sema.resolveTypeFields(block, src, ty.childType());23588 const child_ty = try sema.resolveTypeFields(block, src, ty.childType());
23541 return resolveTypeFully(sema, block, src, child_ty);23589 return resolveTypeFully(sema, block, src, child_ty);
23542 },23590 },
23543 .Struct => return resolveStructFully(sema, block, src, ty),23591 .Struct => switch (ty.tag()) {
23592 .@"struct" => return resolveStructFully(sema, block, src, ty),
23593 .tuple, .anon_struct => {
23594 const tuple = ty.tupleFields();
23595
23596 for (tuple.types) |field_ty| {
23597 try sema.resolveTypeFully(block, src, field_ty);
23598 }
23599 },
23600 else => {},
23601 },
23544 .Union => return resolveUnionFully(sema, block, src, ty),23602 .Union => return resolveUnionFully(sema, block, src, ty),
23545 .Array => return resolveTypeFully(sema, block, src, ty.childType()),23603 .Array => return resolveTypeFully(sema, block, src, ty.childType()),
23546 .Optional => {23604 .Optional => {
...@@ -23575,7 +23633,7 @@ fn resolveStructFully(...@@ -23575,7 +23633,7 @@ fn resolveStructFully(
23575 try resolveStructLayout(sema, block, src, ty);23633 try resolveStructLayout(sema, block, src, ty);
2357623634
23577 const resolved_ty = try sema.resolveTypeFields(block, src, ty);23635 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
23578 const payload = resolved_ty.castTag(.@"struct") orelse return;23636 const payload = resolved_ty.castTag(.@"struct").?;
23579 const struct_obj = payload.data;23637 const struct_obj = payload.data;
2358023638
23581 switch (struct_obj.status) {23639 switch (struct_obj.status) {
...@@ -24425,6 +24483,10 @@ pub fn typeHasOnePossibleValue(...@@ -24425,6 +24483,10 @@ pub fn typeHasOnePossibleValue(
24425 .bool,24483 .bool,
24426 .type,24484 .type,
24427 .anyerror,24485 .anyerror,
24486 .error_set_single,
24487 .error_set,
24488 .error_set_merged,
24489 .error_union,
24428 .fn_noreturn_no_args,24490 .fn_noreturn_no_args,
24429 .fn_void_no_args,24491 .fn_void_no_args,
24430 .fn_naked_noreturn_no_args,24492 .fn_naked_noreturn_no_args,
...@@ -24481,46 +24543,6 @@ pub fn typeHasOnePossibleValue(...@@ -24481,46 +24543,6 @@ pub fn typeHasOnePossibleValue(
24481 }24543 }
24482 },24544 },
2448324545
24484 .error_union => {
24485 const error_ty = ty.errorUnionSet();
24486 switch (error_ty.errorSetCardinality()) {
24487 .zero => {
24488 const payload_ty = ty.errorUnionPayload();
24489 if (try typeHasOnePossibleValue(sema, block, src, payload_ty)) |payload_val| {
24490 return try Value.Tag.eu_payload.create(sema.arena, payload_val);
24491 } else {
24492 return null;
24493 }
24494 },
24495 .one => {
24496 if (ty.errorUnionPayload().isNoReturn()) {
24497 const error_val = (try typeHasOnePossibleValue(sema, block, src, error_ty)).?;
24498 return error_val;
24499 } else {
24500 return null;
24501 }
24502 },
24503 .many => return null,
24504 }
24505 },
24506
24507 .error_set_single => {
24508 const name = ty.castTag(.error_set_single).?.data;
24509 return try Value.Tag.@"error".create(sema.arena, .{ .name = name });
24510 },
24511 .error_set => {
24512 const err_set_obj = ty.castTag(.error_set).?.data;
24513 const names = err_set_obj.names.keys();
24514 if (names.len > 1) return null;
24515 return try Value.Tag.@"error".create(sema.arena, .{ .name = names[0] });
24516 },
24517 .error_set_merged => {
24518 const name_map = ty.castTag(.error_set_merged).?.data;
24519 const names = name_map.keys();
24520 if (names.len > 1) return null;
24521 return try Value.Tag.@"error".create(sema.arena, .{ .name = names[0] });
24522 },
24523
24524 .@"struct" => {24546 .@"struct" => {
24525 const resolved_ty = try sema.resolveTypeFields(block, src, ty);24547 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
24526 const s = resolved_ty.castTag(.@"struct").?.data;24548 const s = resolved_ty.castTag(.@"struct").?.data;
src/TypedValue.zig+64-11
...@@ -144,7 +144,41 @@ pub fn print(...@@ -144,7 +144,41 @@ pub fn print(
144 return writer.writeAll(".{ ... }");144 return writer.writeAll(".{ ... }");
145 }145 }
146 const vals = val.castTag(.aggregate).?.data;146 const vals = val.castTag(.aggregate).?.data;
147 if (ty.zigTypeTag() == .Struct) {147 if (ty.castTag(.anon_struct)) |anon_struct| {
148 const field_names = anon_struct.data.names;
149 const types = anon_struct.data.types;
150 const max_len = std.math.min(types.len, max_aggregate_items);
151
152 var i: u32 = 0;
153 while (i < max_len) : (i += 1) {
154 if (i != 0) try writer.writeAll(", ");
155 try writer.print(".{s} = ", .{field_names[i]});
156 try print(.{
157 .ty = types[i],
158 .val = vals[i],
159 }, writer, level - 1, mod);
160 }
161 if (types.len > max_aggregate_items) {
162 try writer.writeAll(", ...");
163 }
164 return writer.writeAll(" }");
165 } else if (ty.isTuple()) {
166 const fields = ty.tupleFields();
167 const max_len = std.math.min(fields.types.len, max_aggregate_items);
168
169 var i: u32 = 0;
170 while (i < max_len) : (i += 1) {
171 if (i != 0) try writer.writeAll(", ");
172 try print(.{
173 .ty = fields.types[i],
174 .val = vals[i],
175 }, writer, level - 1, mod);
176 }
177 if (fields.types.len > max_aggregate_items) {
178 try writer.writeAll(", ...");
179 }
180 return writer.writeAll(" }");
181 } else if (ty.zigTypeTag() == .Struct) {
148 try writer.writeAll(".{ ");182 try writer.writeAll(".{ ");
149 const struct_fields = ty.structFields();183 const struct_fields = ty.structFields();
150 const len = struct_fields.count();184 const len = struct_fields.count();
...@@ -194,7 +228,7 @@ pub fn print(...@@ -194,7 +228,7 @@ pub fn print(
194 try writer.writeAll(".{ ");228 try writer.writeAll(".{ ");
195229
196 try print(.{230 try print(.{
197 .ty = ty.unionTagType().?,231 .ty = ty.cast(Type.Payload.Union).?.data.tag_ty,
198 .val = union_val.tag,232 .val = union_val.tag,
199 }, writer, level - 1, mod);233 }, writer, level - 1, mod);
200 try writer.writeAll(" = ");234 try writer.writeAll(" = ");
...@@ -278,19 +312,27 @@ pub fn print(...@@ -278,19 +312,27 @@ pub fn print(
278 .elem_ptr => {312 .elem_ptr => {
279 const elem_ptr = val.castTag(.elem_ptr).?.data;313 const elem_ptr = val.castTag(.elem_ptr).?.data;
280 try writer.writeAll("&");314 try writer.writeAll("&");
281 try print(.{315 if (level == 0) {
282 .ty = elem_ptr.elem_ty,316 try writer.writeAll("(ptr)");
283 .val = elem_ptr.array_ptr,317 } else {
284 }, writer, level - 1, mod);318 try print(.{
319 .ty = elem_ptr.elem_ty,
320 .val = elem_ptr.array_ptr,
321 }, writer, level - 1, mod);
322 }
285 return writer.print("[{}]", .{elem_ptr.index});323 return writer.print("[{}]", .{elem_ptr.index});
286 },324 },
287 .field_ptr => {325 .field_ptr => {
288 const field_ptr = val.castTag(.field_ptr).?.data;326 const field_ptr = val.castTag(.field_ptr).?.data;
289 try writer.writeAll("&");327 try writer.writeAll("&");
290 try print(.{328 if (level == 0) {
291 .ty = field_ptr.container_ty,329 try writer.writeAll("(ptr)");
292 .val = field_ptr.container_ptr,330 } else {
293 }, writer, level - 1, mod);331 try print(.{
332 .ty = field_ptr.container_ty,
333 .val = field_ptr.container_ptr,
334 }, writer, level - 1, mod);
335 }
294336
295 if (field_ptr.container_ty.zigTypeTag() == .Struct) {337 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
296 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];338 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];
...@@ -344,6 +386,9 @@ pub fn print(...@@ -344,6 +386,9 @@ pub fn print(
344 return writer.writeAll(" }");386 return writer.writeAll(" }");
345 },387 },
346 .slice => {388 .slice => {
389 if (level == 0) {
390 return writer.writeAll(".{ ... }");
391 }
347 const payload = val.castTag(.slice).?.data;392 const payload = val.castTag(.slice).?.data;
348 try writer.writeAll(".{ ");393 try writer.writeAll(".{ ");
349 const elem_ty = ty.elemType2();394 const elem_ty = ty.elemType2();
...@@ -372,17 +417,25 @@ pub fn print(...@@ -372,17 +417,25 @@ pub fn print(
372 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),417 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
373 .eu_payload => {418 .eu_payload => {
374 val = val.castTag(.eu_payload).?.data;419 val = val.castTag(.eu_payload).?.data;
420 ty = ty.errorUnionPayload();
375 },421 },
376 .opt_payload => {422 .opt_payload => {
377 val = val.castTag(.opt_payload).?.data;423 val = val.castTag(.opt_payload).?.data;
424 var buf: Type.Payload.ElemType = undefined;
425 ty = ty.optionalChild(&buf);
426 return print(.{ .ty = ty, .val = val }, writer, level, mod);
378 },427 },
379 .eu_payload_ptr => {428 .eu_payload_ptr => {
380 try writer.writeAll("&");429 try writer.writeAll("&");
381 val = val.castTag(.eu_payload_ptr).?.data.container_ptr;430 val = val.castTag(.eu_payload_ptr).?.data.container_ptr;
431 ty = ty.elemType2().errorUnionPayload();
382 },432 },
383 .opt_payload_ptr => {433 .opt_payload_ptr => {
384 try writer.writeAll("&");434 try writer.writeAll("&");
385 val = val.castTag(.opt_payload_ptr).?.data.container_ptr;435 val = val.castTag(.opt_payload).?.data;
436 var buf: Type.Payload.ElemType = undefined;
437 ty = ty.elemType2().optionalChild(&buf);
438 return print(.{ .ty = ty, .val = val }, writer, level, mod);
386 },439 },
387440
388 // TODO these should not appear in this function441 // TODO these should not appear in this function
src/Zir.zig+2
...@@ -3156,6 +3156,8 @@ pub const Inst = struct {...@@ -3156,6 +3156,8 @@ pub const Inst = struct {
3156 /// Create an anonymous name for this declaration.3156 /// Create an anonymous name for this declaration.
3157 /// Like this: "ParentDeclName_struct_69"3157 /// Like this: "ParentDeclName_struct_69"
3158 anon,3158 anon,
3159 /// Use the name specified in the next `dbg_var_{val,ptr}` instruction.
3160 dbg_var,
3159 };3161 };
31603162
3161 /// Trailing:3163 /// Trailing:
src/arch/aarch64/CodeGen.zig+3-8
...@@ -2277,7 +2277,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -2277,7 +2277,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
2277fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {2277fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
2278 const err_ty = error_union_ty.errorUnionSet();2278 const err_ty = error_union_ty.errorUnionSet();
2279 const payload_ty = error_union_ty.errorUnionPayload();2279 const payload_ty = error_union_ty.errorUnionPayload();
2280 if (err_ty.errorSetCardinality() == .zero) {2280 if (err_ty.errorSetIsEmpty()) {
2281 return MCValue{ .immediate = 0 };2281 return MCValue{ .immediate = 0 };
2282 }2282 }
2283 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {2283 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
...@@ -2311,7 +2311,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2311,7 +2311,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2311fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {2311fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
2312 const err_ty = error_union_ty.errorUnionSet();2312 const err_ty = error_union_ty.errorUnionSet();
2313 const payload_ty = error_union_ty.errorUnionPayload();2313 const payload_ty = error_union_ty.errorUnionPayload();
2314 if (err_ty.errorSetCardinality() == .zero) {2314 if (err_ty.errorSetIsEmpty()) {
2315 return error_union_mcv;2315 return error_union_mcv;
2316 }2316 }
2317 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {2317 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
...@@ -3590,7 +3590,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {...@@ -3590,7 +3590,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
3590 const error_type = ty.errorUnionSet();3590 const error_type = ty.errorUnionSet();
3591 const payload_type = ty.errorUnionPayload();3591 const payload_type = ty.errorUnionPayload();
35923592
3593 if (error_type.errorSetCardinality() == .zero) {3593 if (error_type.errorSetIsEmpty()) {
3594 return MCValue{ .immediate = 0 }; // always false3594 return MCValue{ .immediate = 0 }; // always false
3595 }3595 }
35963596
...@@ -4687,11 +4687,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4687,11 +4687,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4687 const error_type = typed_value.ty.errorUnionSet();4687 const error_type = typed_value.ty.errorUnionSet();
4688 const payload_type = typed_value.ty.errorUnionPayload();4688 const payload_type = typed_value.ty.errorUnionPayload();
46894689
4690 if (error_type.errorSetCardinality() == .zero) {
4691 const payload_val = typed_value.val.castTag(.eu_payload).?.data;
4692 return self.genTypedValue(.{ .ty = payload_type, .val = payload_val });
4693 }
4694
4695 const is_pl = typed_value.val.errorUnionIsPayload();4690 const is_pl = typed_value.val.errorUnionIsPayload();
46964691
4697 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {4692 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
src/arch/arm/CodeGen.zig+3-9
...@@ -1773,7 +1773,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -1773,7 +1773,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1773fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {1773fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
1774 const err_ty = error_union_ty.errorUnionSet();1774 const err_ty = error_union_ty.errorUnionSet();
1775 const payload_ty = error_union_ty.errorUnionPayload();1775 const payload_ty = error_union_ty.errorUnionPayload();
1776 if (err_ty.errorSetCardinality() == .zero) {1776 if (err_ty.errorSetIsEmpty()) {
1777 return MCValue{ .immediate = 0 };1777 return MCValue{ .immediate = 0 };
1778 }1778 }
1779 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1779 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
...@@ -1810,7 +1810,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1810,7 +1810,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
1810fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {1810fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
1811 const err_ty = error_union_ty.errorUnionSet();1811 const err_ty = error_union_ty.errorUnionSet();
1812 const payload_ty = error_union_ty.errorUnionPayload();1812 const payload_ty = error_union_ty.errorUnionPayload();
1813 if (err_ty.errorSetCardinality() == .zero) {1813 if (err_ty.errorSetIsEmpty()) {
1814 return error_union_mcv;1814 return error_union_mcv;
1815 }1815 }
1816 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1816 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
...@@ -3922,7 +3922,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {...@@ -3922,7 +3922,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
3922 const error_type = ty.errorUnionSet();3922 const error_type = ty.errorUnionSet();
3923 const error_int_type = Type.initTag(.u16);3923 const error_int_type = Type.initTag(.u16);
39243924
3925 if (error_type.errorSetCardinality() == .zero) {3925 if (error_type.errorSetIsEmpty()) {
3926 return MCValue{ .immediate = 0 }; // always false3926 return MCValue{ .immediate = 0 }; // always false
3927 }3927 }
39283928
...@@ -5368,12 +5368,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5368,12 +5368,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5368 .ErrorUnion => {5368 .ErrorUnion => {
5369 const error_type = typed_value.ty.errorUnionSet();5369 const error_type = typed_value.ty.errorUnionSet();
5370 const payload_type = typed_value.ty.errorUnionPayload();5370 const payload_type = typed_value.ty.errorUnionPayload();
5371
5372 if (error_type.errorSetCardinality() == .zero) {
5373 const payload_val = typed_value.val.castTag(.eu_payload).?.data;
5374 return self.genTypedValue(.{ .ty = payload_type, .val = payload_val });
5375 }
5376
5377 const is_pl = typed_value.val.errorUnionIsPayload();5371 const is_pl = typed_value.val.errorUnionIsPayload();
53785372
5379 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {5373 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
src/arch/wasm/CodeGen.zig+19-41
...@@ -1377,11 +1377,7 @@ fn isByRef(ty: Type, target: std.Target) bool {...@@ -1377,11 +1377,7 @@ fn isByRef(ty: Type, target: std.Target) bool {
1377 .Int => return ty.intInfo(target).bits > 64,1377 .Int => return ty.intInfo(target).bits > 64,
1378 .Float => return ty.floatBits(target) > 64,1378 .Float => return ty.floatBits(target) > 64,
1379 .ErrorUnion => {1379 .ErrorUnion => {
1380 const err_ty = ty.errorUnionSet();
1381 const pl_ty = ty.errorUnionPayload();1380 const pl_ty = ty.errorUnionPayload();
1382 if (err_ty.errorSetCardinality() == .zero) {
1383 return isByRef(pl_ty, target);
1384 }
1385 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {1381 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
1386 return false;1382 return false;
1387 }1383 }
...@@ -1817,11 +1813,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1817,11 +1813,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
1817fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {1813fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
1818 switch (ty.zigTypeTag()) {1814 switch (ty.zigTypeTag()) {
1819 .ErrorUnion => {1815 .ErrorUnion => {
1820 const err_ty = ty.errorUnionSet();
1821 const pl_ty = ty.errorUnionPayload();1816 const pl_ty = ty.errorUnionPayload();
1822 if (err_ty.errorSetCardinality() == .zero) {
1823 return self.store(lhs, rhs, pl_ty, 0);
1824 }
1825 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {1817 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
1826 return self.store(lhs, rhs, Type.anyerror, 0);1818 return self.store(lhs, rhs, Type.anyerror, 0);
1827 }1819 }
...@@ -2357,10 +2349,6 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -2357,10 +2349,6 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
2357 },2349 },
2358 .ErrorUnion => {2350 .ErrorUnion => {
2359 const error_type = ty.errorUnionSet();2351 const error_type = ty.errorUnionSet();
2360 if (error_type.errorSetCardinality() == .zero) {
2361 const pl_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef);
2362 return self.lowerConstant(pl_val, ty.errorUnionPayload());
2363 }
2364 const is_pl = val.errorUnionIsPayload();2352 const is_pl = val.errorUnionIsPayload();
2365 const err_val = if (!is_pl) val else Value.initTag(.zero);2353 const err_val = if (!is_pl) val else Value.initTag(.zero);
2366 return self.lowerConstant(err_val, error_type);2354 return self.lowerConstant(err_val, error_type);
...@@ -2929,7 +2917,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W...@@ -2929,7 +2917,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W
2929 const err_union_ty = self.air.typeOf(un_op);2917 const err_union_ty = self.air.typeOf(un_op);
2930 const pl_ty = err_union_ty.errorUnionPayload();2918 const pl_ty = err_union_ty.errorUnionPayload();
29312919
2932 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {2920 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
2933 switch (opcode) {2921 switch (opcode) {
2934 .i32_ne => return WValue{ .imm32 = 0 },2922 .i32_ne => return WValue{ .imm32 = 0 },
2935 .i32_eq => return WValue{ .imm32 = 1 },2923 .i32_eq => return WValue{ .imm32 = 1 },
...@@ -2962,10 +2950,6 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -2962,10 +2950,6 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool)
2962 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;2950 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
2963 const payload_ty = err_ty.errorUnionPayload();2951 const payload_ty = err_ty.errorUnionPayload();
29642952
2965 if (err_ty.errorUnionSet().errorSetCardinality() == .zero) {
2966 return operand;
2967 }
2968
2969 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return WValue{ .none = {} };2953 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return WValue{ .none = {} };
29702954
2971 const pl_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target));2955 const pl_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target));
...@@ -2984,7 +2968,7 @@ fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) In...@@ -2984,7 +2968,7 @@ fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) In
2984 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;2968 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
2985 const payload_ty = err_ty.errorUnionPayload();2969 const payload_ty = err_ty.errorUnionPayload();
29862970
2987 if (err_ty.errorUnionSet().errorSetCardinality() == .zero) {2971 if (err_ty.errorUnionSet().errorSetIsEmpty()) {
2988 return WValue{ .imm32 = 0 };2972 return WValue{ .imm32 = 0 };
2989 }2973 }
29902974
...@@ -3002,10 +2986,6 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3002,10 +2986,6 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3002 const operand = try self.resolveInst(ty_op.operand);2986 const operand = try self.resolveInst(ty_op.operand);
3003 const err_ty = self.air.typeOfIndex(inst);2987 const err_ty = self.air.typeOfIndex(inst);
30042988
3005 if (err_ty.errorUnionSet().errorSetCardinality() == .zero) {
3006 return operand;
3007 }
3008
3009 const pl_ty = self.air.typeOf(ty_op.operand);2989 const pl_ty = self.air.typeOf(ty_op.operand);
3010 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {2990 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
3011 return operand;2991 return operand;
...@@ -4633,29 +4613,27 @@ fn lowerTry(...@@ -4633,29 +4613,27 @@ fn lowerTry(
4633 return self.fail("TODO: lowerTry for pointers", .{});4613 return self.fail("TODO: lowerTry for pointers", .{});
4634 }4614 }
46354615
4636 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {
4637 return err_union;
4638 }
4639
4640 const pl_ty = err_union_ty.errorUnionPayload();4616 const pl_ty = err_union_ty.errorUnionPayload();
4641 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime();4617 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime();
46424618
4643 // Block we can jump out of when error is not set4619 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
4644 try self.startBlock(.block, wasm.block_empty);4620 // Block we can jump out of when error is not set
46454621 try self.startBlock(.block, wasm.block_empty);
4646 // check if the error tag is set for the error union.4622
4647 try self.emitWValue(err_union);4623 // check if the error tag is set for the error union.
4648 if (pl_has_bits) {4624 try self.emitWValue(err_union);
4649 const err_offset = @intCast(u32, errUnionErrorOffset(pl_ty, self.target));4625 if (pl_has_bits) {
4650 try self.addMemArg(.i32_load16_u, .{4626 const err_offset = @intCast(u32, errUnionErrorOffset(pl_ty, self.target));
4651 .offset = err_union.offset() + err_offset,4627 try self.addMemArg(.i32_load16_u, .{
4652 .alignment = Type.anyerror.abiAlignment(self.target),4628 .offset = err_union.offset() + err_offset,
4653 });4629 .alignment = Type.anyerror.abiAlignment(self.target),
4630 });
4631 }
4632 try self.addTag(.i32_eqz);
4633 try self.addLabel(.br_if, 0); // jump out of block when error is '0'
4634 try self.genBody(body);
4635 try self.endBlock();
4654 }4636 }
4655 try self.addTag(.i32_eqz);
4656 try self.addLabel(.br_if, 0); // jump out of block when error is '0'
4657 try self.genBody(body);
4658 try self.endBlock();
46594637
4660 // if we reach here it means error was not set, and we want the payload4638 // if we reach here it means error was not set, and we want the payload
4661 if (!pl_has_bits) {4639 if (!pl_has_bits) {
src/arch/x86_64/CodeGen.zig+2-19
...@@ -1806,7 +1806,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1806,7 +1806,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
1806 const operand = try self.resolveInst(ty_op.operand);1806 const operand = try self.resolveInst(ty_op.operand);
18071807
1808 const result: MCValue = result: {1808 const result: MCValue = result: {
1809 if (err_ty.errorSetCardinality() == .zero) {1809 if (err_ty.errorSetIsEmpty()) {
1810 break :result MCValue{ .immediate = 0 };1810 break :result MCValue{ .immediate = 0 };
1811 }1811 }
18121812
...@@ -1857,14 +1857,8 @@ fn genUnwrapErrorUnionPayloadMir(...@@ -1857,14 +1857,8 @@ fn genUnwrapErrorUnionPayloadMir(
1857 err_union: MCValue,1857 err_union: MCValue,
1858) !MCValue {1858) !MCValue {
1859 const payload_ty = err_union_ty.errorUnionPayload();1859 const payload_ty = err_union_ty.errorUnionPayload();
1860 const err_ty = err_union_ty.errorUnionSet();
18611860
1862 const result: MCValue = result: {1861 const result: MCValue = result: {
1863 if (err_ty.errorSetCardinality() == .zero) {
1864 // TODO check if we can reuse
1865 break :result err_union;
1866 }
1867
1868 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1862 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1869 break :result MCValue.none;1863 break :result MCValue.none;
1870 }1864 }
...@@ -1991,15 +1985,10 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -1991,15 +1985,10 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
1991 }1985 }
19921986
1993 const error_union_ty = self.air.getRefType(ty_op.ty);1987 const error_union_ty = self.air.getRefType(ty_op.ty);
1994 const error_ty = error_union_ty.errorUnionSet();
1995 const payload_ty = error_union_ty.errorUnionPayload();1988 const payload_ty = error_union_ty.errorUnionPayload();
1996 const operand = try self.resolveInst(ty_op.operand);1989 const operand = try self.resolveInst(ty_op.operand);
19971990
1998 const result: MCValue = result: {1991 const result: MCValue = result: {
1999 if (error_ty.errorSetCardinality() == .zero) {
2000 break :result operand;
2001 }
2002
2003 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1992 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2004 break :result operand;1993 break :result operand;
2005 }1994 }
...@@ -4651,7 +4640,7 @@ fn isNonNull(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCV...@@ -4651,7 +4640,7 @@ fn isNonNull(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCV
4651fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {4640fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {
4652 const err_type = ty.errorUnionSet();4641 const err_type = ty.errorUnionSet();
46534642
4654 if (err_type.errorSetCardinality() == .zero) {4643 if (err_type.errorSetIsEmpty()) {
4655 return MCValue{ .immediate = 0 }; // always false4644 return MCValue{ .immediate = 0 }; // always false
4656 }4645 }
46574646
...@@ -6909,12 +6898,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -6909,12 +6898,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
6909 .ErrorUnion => {6898 .ErrorUnion => {
6910 const error_type = typed_value.ty.errorUnionSet();6899 const error_type = typed_value.ty.errorUnionSet();
6911 const payload_type = typed_value.ty.errorUnionPayload();6900 const payload_type = typed_value.ty.errorUnionPayload();
6912
6913 if (error_type.errorSetCardinality() == .zero) {
6914 const payload_val = typed_value.val.castTag(.eu_payload).?.data;
6915 return self.genTypedValue(.{ .ty = payload_type, .val = payload_val });
6916 }
6917
6918 const is_pl = typed_value.val.errorUnionIsPayload();6901 const is_pl = typed_value.val.errorUnionIsPayload();
69196902
6920 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {6903 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
src/codegen.zig-9
...@@ -705,15 +705,6 @@ pub fn generateSymbol(...@@ -705,15 +705,6 @@ pub fn generateSymbol(
705 .ErrorUnion => {705 .ErrorUnion => {
706 const error_ty = typed_value.ty.errorUnionSet();706 const error_ty = typed_value.ty.errorUnionSet();
707 const payload_ty = typed_value.ty.errorUnionPayload();707 const payload_ty = typed_value.ty.errorUnionPayload();
708
709 if (error_ty.errorSetCardinality() == .zero) {
710 const payload_val = typed_value.val.castTag(.eu_payload).?.data;
711 return generateSymbol(bin_file, src_loc, .{
712 .ty = payload_ty,
713 .val = payload_val,
714 }, code, debug_output, reloc_info);
715 }
716
717 const is_payload = typed_value.val.errorUnionIsPayload();708 const is_payload = typed_value.val.errorUnionIsPayload();
718709
719 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {710 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
src/codegen/c.zig+24-52
...@@ -752,12 +752,6 @@ pub const DeclGen = struct {...@@ -752,12 +752,6 @@ pub const DeclGen = struct {
752 const error_type = ty.errorUnionSet();752 const error_type = ty.errorUnionSet();
753 const payload_type = ty.errorUnionPayload();753 const payload_type = ty.errorUnionPayload();
754754
755 if (error_type.errorSetCardinality() == .zero) {
756 // We use the payload directly as the type.
757 const payload_val = val.castTag(.eu_payload).?.data;
758 return dg.renderValue(writer, payload_type, payload_val, location);
759 }
760
761 if (!payload_type.hasRuntimeBits()) {755 if (!payload_type.hasRuntimeBits()) {
762 // We use the error type directly as the type.756 // We use the error type directly as the type.
763 const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val;757 const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val;
...@@ -1381,13 +1375,8 @@ pub const DeclGen = struct {...@@ -1381,13 +1375,8 @@ pub const DeclGen = struct {
1381 return w.writeAll("uint16_t");1375 return w.writeAll("uint16_t");
1382 },1376 },
1383 .ErrorUnion => {1377 .ErrorUnion => {
1384 const error_ty = t.errorUnionSet();
1385 const payload_ty = t.errorUnionPayload();1378 const payload_ty = t.errorUnionPayload();
13861379
1387 if (error_ty.errorSetCardinality() == .zero) {
1388 return dg.renderType(w, payload_ty);
1389 }
1390
1391 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1380 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1392 return dg.renderType(w, Type.anyerror);1381 return dg.renderType(w, Type.anyerror);
1393 }1382 }
...@@ -2892,41 +2881,36 @@ fn lowerTry(...@@ -2892,41 +2881,36 @@ fn lowerTry(
2892 operand_is_ptr: bool,2881 operand_is_ptr: bool,
2893 result_ty: Type,2882 result_ty: Type,
2894) !CValue {2883) !CValue {
2895 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {2884 const writer = f.object.writer();
2896 // If the error set has no fields, then the payload and the error
2897 // union are the same value.
2898 return err_union;
2899 }
2900
2901 const payload_ty = err_union_ty.errorUnionPayload();2885 const payload_ty = err_union_ty.errorUnionPayload();
2902 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();2886 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
29032887
2904 const writer = f.object.writer();2888 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
29052889 err: {
2906 err: {2890 if (!payload_has_bits) {
2907 if (!payload_has_bits) {2891 if (operand_is_ptr) {
2908 if (operand_is_ptr) {2892 try writer.writeAll("if(*");
2909 try writer.writeAll("if(*");2893 } else {
2910 } else {2894 try writer.writeAll("if(");
2895 }
2896 try f.writeCValue(writer, err_union);
2897 try writer.writeAll(")");
2898 break :err;
2899 }
2900 if (operand_is_ptr or isByRef(err_union_ty)) {
2911 try writer.writeAll("if(");2901 try writer.writeAll("if(");
2902 try f.writeCValue(writer, err_union);
2903 try writer.writeAll("->error)");
2904 break :err;
2912 }2905 }
2913 try f.writeCValue(writer, err_union);
2914 try writer.writeAll(")");
2915 break :err;
2916 }
2917 if (operand_is_ptr or isByRef(err_union_ty)) {
2918 try writer.writeAll("if(");2906 try writer.writeAll("if(");
2919 try f.writeCValue(writer, err_union);2907 try f.writeCValue(writer, err_union);
2920 try writer.writeAll("->error)");2908 try writer.writeAll(".error)");
2921 break :err;
2922 }2909 }
2923 try writer.writeAll("if(");
2924 try f.writeCValue(writer, err_union);
2925 try writer.writeAll(".error)");
2926 }
29272910
2928 try genBody(f, body);2911 try genBody(f, body);
2929 try f.object.indent_writer.insertNewline();2912 try f.object.indent_writer.insertNewline();
2913 }
29302914
2931 if (!payload_has_bits) {2915 if (!payload_has_bits) {
2932 if (!operand_is_ptr) {2916 if (!operand_is_ptr) {
...@@ -3466,7 +3450,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3466,7 +3450,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
34663450
3467 if (operand_ty.zigTypeTag() == .Pointer) {3451 if (operand_ty.zigTypeTag() == .Pointer) {
3468 const err_union_ty = operand_ty.childType();3452 const err_union_ty = operand_ty.childType();
3469 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {3453 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
3470 return CValue{ .bytes = "0" };3454 return CValue{ .bytes = "0" };
3471 }3455 }
3472 if (!err_union_ty.errorUnionPayload().hasRuntimeBits()) {3456 if (!err_union_ty.errorUnionPayload().hasRuntimeBits()) {
...@@ -3478,7 +3462,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3478,7 +3462,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3478 try writer.writeAll(";\n");3462 try writer.writeAll(";\n");
3479 return local;3463 return local;
3480 }3464 }
3481 if (operand_ty.errorUnionSet().errorSetCardinality() == .zero) {3465 if (operand_ty.errorUnionSet().errorSetIsEmpty()) {
3482 return CValue{ .bytes = "0" };3466 return CValue{ .bytes = "0" };
3483 }3467 }
3484 if (!operand_ty.errorUnionPayload().hasRuntimeBits()) {3468 if (!operand_ty.errorUnionPayload().hasRuntimeBits()) {
...@@ -3507,10 +3491,6 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]c...@@ -3507,10 +3491,6 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]c
3507 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;3491 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
3508 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;3492 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
35093493
3510 if (error_union_ty.errorUnionSet().errorSetCardinality() == .zero) {
3511 return operand;
3512 }
3513
3514 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {3494 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {
3515 return CValue.none;3495 return CValue.none;
3516 }3496 }
...@@ -3575,11 +3555,6 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3575,11 +3555,6 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
3575 const error_ty = error_union_ty.errorUnionSet();3555 const error_ty = error_union_ty.errorUnionSet();
3576 const payload_ty = error_union_ty.errorUnionPayload();3556 const payload_ty = error_union_ty.errorUnionPayload();
35773557
3578 if (error_ty.errorSetCardinality() == .zero) {
3579 // TODO: write undefined bytes through the pointer here
3580 return operand;
3581 }
3582
3583 // First, set the non-error value.3558 // First, set the non-error value.
3584 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3559 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3585 try f.writeCValueDeref(writer, operand);3560 try f.writeCValueDeref(writer, operand);
...@@ -3623,9 +3598,6 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3623,9 +3598,6 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
3623 const operand = try f.resolveInst(ty_op.operand);3598 const operand = try f.resolveInst(ty_op.operand);
36243599
3625 const inst_ty = f.air.typeOfIndex(inst);3600 const inst_ty = f.air.typeOfIndex(inst);
3626 if (inst_ty.errorUnionSet().errorSetCardinality() == .zero) {
3627 return operand;
3628 }
3629 const local = try f.allocLocal(inst_ty, .Const);3601 const local = try f.allocLocal(inst_ty, .Const);
3630 try writer.writeAll(" = { .error = 0, .payload = ");3602 try writer.writeAll(" = { .error = 0, .payload = ");
3631 try f.writeCValue(writer, operand);3603 try f.writeCValue(writer, operand);
...@@ -3652,7 +3624,7 @@ fn airIsErr(...@@ -3652,7 +3624,7 @@ fn airIsErr(
36523624
3653 try writer.writeAll(" = ");3625 try writer.writeAll(" = ");
36543626
3655 if (error_ty.errorSetCardinality() == .zero) {3627 if (error_ty.errorSetIsEmpty()) {
3656 try writer.print("0 {s} 0;\n", .{op_str});3628 try writer.print("0 {s} 0;\n", .{op_str});
3657 } else {3629 } else {
3658 if (is_ptr) {3630 if (is_ptr) {
src/codegen/llvm.zig+38-79
...@@ -599,6 +599,13 @@ pub const Object = struct {...@@ -599,6 +599,13 @@ pub const Object = struct {
599 self.llvm_module.dump();599 self.llvm_module.dump();
600 }600 }
601601
602 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
603 defer arena_allocator.deinit();
604 const arena = arena_allocator.allocator();
605
606 const mod = comp.bin_file.options.module.?;
607 const cache_dir = mod.zig_cache_artifact_directory;
608
602 if (std.debug.runtime_safety) {609 if (std.debug.runtime_safety) {
603 var error_message: [*:0]const u8 = undefined;610 var error_message: [*:0]const u8 = undefined;
604 // verifyModule always allocs the error_message even if there is no error611 // verifyModule always allocs the error_message even if there is no error
...@@ -606,17 +613,15 @@ pub const Object = struct {...@@ -606,17 +613,15 @@ pub const Object = struct {
606613
607 if (self.llvm_module.verify(.ReturnStatus, &error_message).toBool()) {614 if (self.llvm_module.verify(.ReturnStatus, &error_message).toBool()) {
608 std.debug.print("\n{s}\n", .{error_message});615 std.debug.print("\n{s}\n", .{error_message});
616
617 if (try locPath(arena, comp.emit_llvm_ir, cache_dir)) |emit_llvm_ir_path| {
618 _ = self.llvm_module.printModuleToFile(emit_llvm_ir_path, &error_message);
619 }
620
609 @panic("LLVM module verification failed");621 @panic("LLVM module verification failed");
610 }622 }
611 }623 }
612624
613 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
614 defer arena_allocator.deinit();
615 const arena = arena_allocator.allocator();
616
617 const mod = comp.bin_file.options.module.?;
618 const cache_dir = mod.zig_cache_artifact_directory;
619
620 var emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|625 var emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|
621 try emit.basenamePath(arena, try arena.dupeZ(u8, comp.bin_file.intermediary_basename.?))626 try emit.basenamePath(arena, try arena.dupeZ(u8, comp.bin_file.intermediary_basename.?))
622 else627 else
...@@ -1566,22 +1571,6 @@ pub const Object = struct {...@@ -1566,22 +1571,6 @@ pub const Object = struct {
1566 },1571 },
1567 .ErrorUnion => {1572 .ErrorUnion => {
1568 const payload_ty = ty.errorUnionPayload();1573 const payload_ty = ty.errorUnionPayload();
1569 switch (ty.errorUnionSet().errorSetCardinality()) {
1570 .zero => {
1571 const payload_di_ty = try o.lowerDebugType(payload_ty, .full);
1572 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1573 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(payload_di_ty), .{ .mod = o.module });
1574 return payload_di_ty;
1575 },
1576 .one => {
1577 if (payload_ty.isNoReturn()) {
1578 const di_type = dib.createBasicType("void", 0, DW.ATE.signed);
1579 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1580 return di_type;
1581 }
1582 },
1583 .many => {},
1584 }
1585 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1574 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1586 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);1575 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);
1587 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1576 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
...@@ -2549,15 +2538,6 @@ pub const DeclGen = struct {...@@ -2549,15 +2538,6 @@ pub const DeclGen = struct {
2549 },2538 },
2550 .ErrorUnion => {2539 .ErrorUnion => {
2551 const payload_ty = t.errorUnionPayload();2540 const payload_ty = t.errorUnionPayload();
2552 switch (t.errorUnionSet().errorSetCardinality()) {
2553 .zero => return dg.lowerType(payload_ty),
2554 .one => {
2555 if (payload_ty.isNoReturn()) {
2556 return dg.context.voidType();
2557 }
2558 },
2559 .many => {},
2560 }
2561 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {2541 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2562 return try dg.lowerType(Type.anyerror);2542 return try dg.lowerType(Type.anyerror);
2563 }2543 }
...@@ -3217,10 +3197,6 @@ pub const DeclGen = struct {...@@ -3217,10 +3197,6 @@ pub const DeclGen = struct {
3217 },3197 },
3218 .ErrorUnion => {3198 .ErrorUnion => {
3219 const payload_type = tv.ty.errorUnionPayload();3199 const payload_type = tv.ty.errorUnionPayload();
3220 if (tv.ty.errorUnionSet().errorSetCardinality() == .zero) {
3221 const payload_val = tv.val.castTag(.eu_payload).?.data;
3222 return dg.lowerValue(.{ .ty = payload_type, .val = payload_val });
3223 }
3224 const is_pl = tv.val.errorUnionIsPayload();3200 const is_pl = tv.val.errorUnionIsPayload();
32253201
3226 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {3202 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
...@@ -4790,40 +4766,37 @@ pub const FuncGen = struct {...@@ -4790,40 +4766,37 @@ pub const FuncGen = struct {
4790 }4766 }
47914767
4792 fn lowerTry(fg: *FuncGen, err_union: *const llvm.Value, body: []const Air.Inst.Index, err_union_ty: Type, operand_is_ptr: bool, result_ty: Type) !?*const llvm.Value {4768 fn lowerTry(fg: *FuncGen, err_union: *const llvm.Value, body: []const Air.Inst.Index, err_union_ty: Type, operand_is_ptr: bool, result_ty: Type) !?*const llvm.Value {
4793 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {
4794 // If the error set has no fields, then the payload and the error
4795 // union are the same value.
4796 return err_union;
4797 }
4798
4799 const payload_ty = err_union_ty.errorUnionPayload();4769 const payload_ty = err_union_ty.errorUnionPayload();
4800 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();4770 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
4801 const target = fg.dg.module.getTarget();4771 const target = fg.dg.module.getTarget();
4802 const is_err = err: {4772
4803 const err_set_ty = try fg.dg.lowerType(Type.anyerror);4773 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
4804 const zero = err_set_ty.constNull();4774 const is_err = err: {
4805 if (!payload_has_bits) {4775 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
4806 const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;4776 const zero = err_set_ty.constNull();
4807 break :err fg.builder.buildICmp(.NE, loaded, zero, "");4777 if (!payload_has_bits) {
4808 }4778 const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;
4809 const err_field_index = errUnionErrorOffset(payload_ty, target);4779 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4810 if (operand_is_ptr or isByRef(err_union_ty)) {4780 }
4811 const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");4781 const err_field_index = errUnionErrorOffset(payload_ty, target);
4812 const loaded = fg.builder.buildLoad(err_field_ptr, "");4782 if (operand_is_ptr or isByRef(err_union_ty)) {
4783 const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");
4784 const loaded = fg.builder.buildLoad(err_field_ptr, "");
4785 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4786 }
4787 const loaded = fg.builder.buildExtractValue(err_union, err_field_index, "");
4813 break :err fg.builder.buildICmp(.NE, loaded, zero, "");4788 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4814 }4789 };
4815 const loaded = fg.builder.buildExtractValue(err_union, err_field_index, "");
4816 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4817 };
48184790
4819 const return_block = fg.context.appendBasicBlock(fg.llvm_func, "TryRet");4791 const return_block = fg.context.appendBasicBlock(fg.llvm_func, "TryRet");
4820 const continue_block = fg.context.appendBasicBlock(fg.llvm_func, "TryCont");4792 const continue_block = fg.context.appendBasicBlock(fg.llvm_func, "TryCont");
4821 _ = fg.builder.buildCondBr(is_err, return_block, continue_block);4793 _ = fg.builder.buildCondBr(is_err, return_block, continue_block);
48224794
4823 fg.builder.positionBuilderAtEnd(return_block);4795 fg.builder.positionBuilderAtEnd(return_block);
4824 try fg.genBody(body);4796 try fg.genBody(body);
48254797
4826 fg.builder.positionBuilderAtEnd(continue_block);4798 fg.builder.positionBuilderAtEnd(continue_block);
4799 }
4827 if (!payload_has_bits) {4800 if (!payload_has_bits) {
4828 if (!operand_is_ptr) return null;4801 if (!operand_is_ptr) return null;
48294802
...@@ -5660,7 +5633,7 @@ pub const FuncGen = struct {...@@ -5660,7 +5633,7 @@ pub const FuncGen = struct {
5660 const err_set_ty = try self.dg.lowerType(Type.initTag(.anyerror));5633 const err_set_ty = try self.dg.lowerType(Type.initTag(.anyerror));
5661 const zero = err_set_ty.constNull();5634 const zero = err_set_ty.constNull();
56625635
5663 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {5636 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
5664 const llvm_i1 = self.context.intType(1);5637 const llvm_i1 = self.context.intType(1);
5665 switch (op) {5638 switch (op) {
5666 .EQ => return llvm_i1.constInt(1, .False), // 0 == 05639 .EQ => return llvm_i1.constInt(1, .False), // 0 == 0
...@@ -5783,13 +5756,6 @@ pub const FuncGen = struct {...@@ -5783,13 +5756,6 @@ pub const FuncGen = struct {
57835756
5784 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5757 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5785 const operand = try self.resolveInst(ty_op.operand);5758 const operand = try self.resolveInst(ty_op.operand);
5786 const operand_ty = self.air.typeOf(ty_op.operand);
5787 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5788 if (error_union_ty.errorUnionSet().errorSetCardinality() == .zero) {
5789 // If the error set has no fields, then the payload and the error
5790 // union are the same value.
5791 return operand;
5792 }
5793 const result_ty = self.air.typeOfIndex(inst);5759 const result_ty = self.air.typeOfIndex(inst);
5794 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;5760 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
5795 const target = self.dg.module.getTarget();5761 const target = self.dg.module.getTarget();
...@@ -5820,7 +5786,7 @@ pub const FuncGen = struct {...@@ -5820,7 +5786,7 @@ pub const FuncGen = struct {
5820 const operand = try self.resolveInst(ty_op.operand);5786 const operand = try self.resolveInst(ty_op.operand);
5821 const operand_ty = self.air.typeOf(ty_op.operand);5787 const operand_ty = self.air.typeOf(ty_op.operand);
5822 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;5788 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5823 if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) {5789 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
5824 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);5790 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
5825 if (operand_is_ptr) {5791 if (operand_is_ptr) {
5826 return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), "");5792 return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), "");
...@@ -5851,10 +5817,6 @@ pub const FuncGen = struct {...@@ -5851,10 +5817,6 @@ pub const FuncGen = struct {
5851 const operand = try self.resolveInst(ty_op.operand);5817 const operand = try self.resolveInst(ty_op.operand);
5852 const error_union_ty = self.air.typeOf(ty_op.operand).childType();5818 const error_union_ty = self.air.typeOf(ty_op.operand).childType();
58535819
5854 if (error_union_ty.errorUnionSet().errorSetCardinality() == .zero) {
5855 // TODO: write undefined bytes through the pointer here
5856 return operand;
5857 }
5858 const payload_ty = error_union_ty.errorUnionPayload();5820 const payload_ty = error_union_ty.errorUnionPayload();
5859 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });5821 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
5860 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {5822 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
...@@ -5933,9 +5895,6 @@ pub const FuncGen = struct {...@@ -5933,9 +5895,6 @@ pub const FuncGen = struct {
5933 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5895 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5934 const inst_ty = self.air.typeOfIndex(inst);5896 const inst_ty = self.air.typeOfIndex(inst);
5935 const operand = try self.resolveInst(ty_op.operand);5897 const operand = try self.resolveInst(ty_op.operand);
5936 if (inst_ty.errorUnionSet().errorSetCardinality() == .zero) {
5937 return operand;
5938 }
5939 const payload_ty = self.air.typeOf(ty_op.operand);5898 const payload_ty = self.air.typeOf(ty_op.operand);
5940 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {5899 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
5941 return operand;5900 return operand;
src/codegen/llvm/bindings.zig+3
...@@ -390,6 +390,9 @@ pub const Module = opaque {...@@ -390,6 +390,9 @@ pub const Module = opaque {
390390
391 pub const setModuleInlineAsm2 = LLVMSetModuleInlineAsm2;391 pub const setModuleInlineAsm2 = LLVMSetModuleInlineAsm2;
392 extern fn LLVMSetModuleInlineAsm2(M: *const Module, Asm: [*]const u8, Len: usize) void;392 extern fn LLVMSetModuleInlineAsm2(M: *const Module, Asm: [*]const u8, Len: usize) void;
393
394 pub const printModuleToFile = LLVMPrintModuleToFile;
395 extern fn LLVMPrintModuleToFile(M: *const Module, Filename: [*:0]const u8, ErrorMessage: *[*:0]const u8) Bool;
393};396};
394397
395pub const lookupIntrinsicID = LLVMLookupIntrinsicID;398pub const lookupIntrinsicID = LLVMLookupIntrinsicID;
src/print_air.zig+30-8
...@@ -4,6 +4,7 @@ const fmtIntSizeBin = std.fmt.fmtIntSizeBin;...@@ -4,6 +4,7 @@ const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
44
5const Module = @import("Module.zig");5const Module = @import("Module.zig");
6const Value = @import("value.zig").Value;6const Value = @import("value.zig").Value;
7const Type = @import("type.zig").Type;
7const Air = @import("Air.zig");8const Air = @import("Air.zig");
8const Liveness = @import("Liveness.zig");9const Liveness = @import("Liveness.zig");
910
...@@ -304,14 +305,27 @@ const Writer = struct {...@@ -304,14 +305,27 @@ const Writer = struct {
304 // no-op, no argument to write305 // no-op, no argument to write
305 }306 }
306307
308 fn writeType(w: *Writer, s: anytype, ty: Type) !void {
309 const t = ty.tag();
310 switch (t) {
311 .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"),
312 .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"),
313 .generic_poison => try s.writeAll("(generic_poison)"),
314 .var_args_param => try s.writeAll("(var_args_param)"),
315 .bound_fn => try s.writeAll("(bound_fn)"),
316 else => try ty.print(s, w.module),
317 }
318 }
319
307 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {320 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
308 const ty = w.air.instructions.items(.data)[inst].ty;321 const ty = w.air.instructions.items(.data)[inst].ty;
309 try s.print("{}", .{ty.fmtDebug()});322 try w.writeType(s, ty);
310 }323 }
311324
312 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {325 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
313 const ty_op = w.air.instructions.items(.data)[inst].ty_op;326 const ty_op = w.air.instructions.items(.data)[inst].ty_op;
314 try s.print("{}, ", .{w.air.getRefType(ty_op.ty).fmtDebug()});327 try w.writeType(s, w.air.getRefType(ty_op.ty));
328 try s.writeAll(", ");
315 try w.writeOperand(s, inst, 0, ty_op.operand);329 try w.writeOperand(s, inst, 0, ty_op.operand);
316 }330 }
317331
...@@ -320,7 +334,8 @@ const Writer = struct {...@@ -320,7 +334,8 @@ const Writer = struct {
320 const extra = w.air.extraData(Air.Block, ty_pl.payload);334 const extra = w.air.extraData(Air.Block, ty_pl.payload);
321 const body = w.air.extra[extra.end..][0..extra.data.body_len];335 const body = w.air.extra[extra.end..][0..extra.data.body_len];
322336
323 try s.print("{}, {{\n", .{w.air.getRefType(ty_pl.ty).fmtDebug()});337 try w.writeType(s, w.air.getRefType(ty_pl.ty));
338 try s.writeAll(", {\n");
324 const old_indent = w.indent;339 const old_indent = w.indent;
325 w.indent += 2;340 w.indent += 2;
326 try w.writeBody(s, body);341 try w.writeBody(s, body);
...@@ -335,7 +350,8 @@ const Writer = struct {...@@ -335,7 +350,8 @@ const Writer = struct {
335 const len = @intCast(usize, vector_ty.arrayLen());350 const len = @intCast(usize, vector_ty.arrayLen());
336 const elements = @ptrCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);351 const elements = @ptrCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);
337352
338 try s.print("{}, [", .{vector_ty.fmtDebug()});353 try w.writeType(s, vector_ty);
354 try s.writeAll(", [");
339 for (elements) |elem, i| {355 for (elements) |elem, i| {
340 if (i != 0) try s.writeAll(", ");356 if (i != 0) try s.writeAll(", ");
341 try w.writeOperand(s, inst, i, elem);357 try w.writeOperand(s, inst, i, elem);
...@@ -408,7 +424,8 @@ const Writer = struct {...@@ -408,7 +424,8 @@ const Writer = struct {
408 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;424 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
409425
410 const elem_ty = w.air.typeOfIndex(inst).childType();426 const elem_ty = w.air.typeOfIndex(inst).childType();
411 try s.print("{}, ", .{elem_ty.fmtDebug()});427 try w.writeType(s, elem_ty);
428 try s.writeAll(", ");
412 try w.writeOperand(s, inst, 0, pl_op.operand);429 try w.writeOperand(s, inst, 0, pl_op.operand);
413 try s.writeAll(", ");430 try s.writeAll(", ");
414 try w.writeOperand(s, inst, 1, extra.lhs);431 try w.writeOperand(s, inst, 1, extra.lhs);
...@@ -511,7 +528,9 @@ const Writer = struct {...@@ -511,7 +528,9 @@ const Writer = struct {
511 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {528 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
512 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;529 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
513 const val = w.air.values[ty_pl.payload];530 const val = w.air.values[ty_pl.payload];
514 try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty).fmtDebug(), val.fmtDebug() });531 const ty = w.air.getRefType(ty_pl.ty);
532 try w.writeType(s, ty);
533 try s.print(", {}", .{val.fmtValue(ty, w.module)});
515 }534 }
516535
517 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {536 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
...@@ -523,7 +542,7 @@ const Writer = struct {...@@ -523,7 +542,7 @@ const Writer = struct {
523 var op_index: usize = 0;542 var op_index: usize = 0;
524543
525 const ret_ty = w.air.typeOfIndex(inst);544 const ret_ty = w.air.typeOfIndex(inst);
526 try s.print("{}", .{ret_ty.fmtDebug()});545 try w.writeType(s, ret_ty);
527546
528 if (is_volatile) {547 if (is_volatile) {
529 try s.writeAll(", volatile");548 try s.writeAll(", volatile");
...@@ -647,7 +666,10 @@ const Writer = struct {...@@ -647,7 +666,10 @@ const Writer = struct {
647 const body = w.air.extra[extra.end..][0..extra.data.body_len];666 const body = w.air.extra[extra.end..][0..extra.data.body_len];
648667
649 try w.writeOperand(s, inst, 0, extra.data.ptr);668 try w.writeOperand(s, inst, 0, extra.data.ptr);
650 try s.print(", {}, {{\n", .{w.air.getRefType(ty_pl.ty).fmtDebug()});669
670 try s.writeAll(", ");
671 try w.writeType(s, w.air.getRefType(ty_pl.ty));
672 try s.writeAll(", {\n");
651 const old_indent = w.indent;673 const old_indent = w.indent;
652 w.indent += 2;674 w.indent += 2;
653 try w.writeBody(s, body);675 try w.writeBody(s, body);
src/type.zig+29-163
...@@ -2366,6 +2366,10 @@ pub const Type = extern union {...@@ -2366,6 +2366,10 @@ pub const Type = extern union {
2366 .anyopaque,2366 .anyopaque,
2367 .@"opaque",2367 .@"opaque",
2368 .type_info,2368 .type_info,
2369 .error_set_single,
2370 .error_union,
2371 .error_set,
2372 .error_set_merged,
2369 => return true,2373 => return true,
23702374
2371 // These are false because they are comptime-only types.2375 // These are false because they are comptime-only types.
...@@ -2389,20 +2393,8 @@ pub const Type = extern union {...@@ -2389,20 +2393,8 @@ pub const Type = extern union {
2389 .fn_void_no_args,2393 .fn_void_no_args,
2390 .fn_naked_noreturn_no_args,2394 .fn_naked_noreturn_no_args,
2391 .fn_ccc_void_no_args,2395 .fn_ccc_void_no_args,
2392 .error_set_single,
2393 => return false,2396 => return false,
23942397
2395 .error_set => {
2396 const err_set_obj = ty.castTag(.error_set).?.data;
2397 const names = err_set_obj.names.keys();
2398 return names.len > 1;
2399 },
2400 .error_set_merged => {
2401 const name_map = ty.castTag(.error_set_merged).?.data;
2402 const names = name_map.keys();
2403 return names.len > 1;
2404 },
2405
2406 // These types have more than one possible value, so the result is the same as2398 // These types have more than one possible value, so the result is the same as
2407 // asking whether they are comptime-only types.2399 // asking whether they are comptime-only types.
2408 .anyframe_T,2400 .anyframe_T,
...@@ -2443,25 +2435,6 @@ pub const Type = extern union {...@@ -2443,25 +2435,6 @@ pub const Type = extern union {
2443 }2435 }
2444 },2436 },
24452437
2446 .error_union => {
2447 // This code needs to be kept in sync with the equivalent switch prong
2448 // in abiSizeAdvanced.
2449 const data = ty.castTag(.error_union).?.data;
2450 switch (data.error_set.errorSetCardinality()) {
2451 .zero => return hasRuntimeBitsAdvanced(data.payload, ignore_comptime_only, sema_kit),
2452 .one => return !data.payload.isNoReturn(),
2453 .many => {
2454 if (ignore_comptime_only) {
2455 return true;
2456 } else if (sema_kit) |sk| {
2457 return !(try sk.sema.typeRequiresComptime(sk.block, sk.src, ty));
2458 } else {
2459 return !comptimeOnly(ty);
2460 }
2461 },
2462 }
2463 },
2464
2465 .@"struct" => {2438 .@"struct" => {
2466 const struct_obj = ty.castTag(.@"struct").?.data;2439 const struct_obj = ty.castTag(.@"struct").?.data;
2467 if (struct_obj.status == .field_types_wip) {2440 if (struct_obj.status == .field_types_wip) {
...@@ -2926,27 +2899,11 @@ pub const Type = extern union {...@@ -2926,27 +2899,11 @@ pub const Type = extern union {
2926 .anyerror_void_error_union,2899 .anyerror_void_error_union,
2927 .anyerror,2900 .anyerror,
2928 .error_set_inferred,2901 .error_set_inferred,
2902 .error_set_single,
2903 .error_set,
2904 .error_set_merged,
2929 => return AbiAlignmentAdvanced{ .scalar = 2 },2905 => return AbiAlignmentAdvanced{ .scalar = 2 },
29302906
2931 .error_set => {
2932 const err_set_obj = ty.castTag(.error_set).?.data;
2933 const names = err_set_obj.names.keys();
2934 if (names.len <= 1) {
2935 return AbiAlignmentAdvanced{ .scalar = 0 };
2936 } else {
2937 return AbiAlignmentAdvanced{ .scalar = 2 };
2938 }
2939 },
2940 .error_set_merged => {
2941 const name_map = ty.castTag(.error_set_merged).?.data;
2942 const names = name_map.keys();
2943 if (names.len <= 1) {
2944 return AbiAlignmentAdvanced{ .scalar = 0 };
2945 } else {
2946 return AbiAlignmentAdvanced{ .scalar = 2 };
2947 }
2948 },
2949
2950 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),2907 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
29512908
2952 // TODO audit this - is there any more complicated logic to determine2909 // TODO audit this - is there any more complicated logic to determine
...@@ -2971,12 +2928,7 @@ pub const Type = extern union {...@@ -2971,12 +2928,7 @@ pub const Type = extern union {
29712928
2972 switch (child_type.zigTypeTag()) {2929 switch (child_type.zigTypeTag()) {
2973 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },2930 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
2974 .ErrorSet => switch (child_type.errorSetCardinality()) {2931 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, target, strat),
2975 // `?error{}` is comptime-known to be null.
2976 .zero => return AbiAlignmentAdvanced{ .scalar = 0 },
2977 .one => return AbiAlignmentAdvanced{ .scalar = 1 },
2978 .many => return abiAlignmentAdvanced(Type.anyerror, target, strat),
2979 },
2980 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },2932 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },
2981 else => {},2933 else => {},
2982 }2934 }
...@@ -2999,15 +2951,6 @@ pub const Type = extern union {...@@ -2999,15 +2951,6 @@ pub const Type = extern union {
2999 // This code needs to be kept in sync with the equivalent switch prong2951 // This code needs to be kept in sync with the equivalent switch prong
3000 // in abiSizeAdvanced.2952 // in abiSizeAdvanced.
3001 const data = ty.castTag(.error_union).?.data;2953 const data = ty.castTag(.error_union).?.data;
3002 switch (data.error_set.errorSetCardinality()) {
3003 .zero => return abiAlignmentAdvanced(data.payload, target, strat),
3004 .one => {
3005 if (data.payload.isNoReturn()) {
3006 return AbiAlignmentAdvanced{ .scalar = 0 };
3007 }
3008 },
3009 .many => {},
3010 }
3011 const code_align = abiAlignment(Type.anyerror, target);2954 const code_align = abiAlignment(Type.anyerror, target);
3012 switch (strat) {2955 switch (strat) {
3013 .eager, .sema_kit => {2956 .eager, .sema_kit => {
...@@ -3118,7 +3061,6 @@ pub const Type = extern union {...@@ -3118,7 +3061,6 @@ pub const Type = extern union {
3118 .@"undefined",3061 .@"undefined",
3119 .enum_literal,3062 .enum_literal,
3120 .type_info,3063 .type_info,
3121 .error_set_single,
3122 => return AbiAlignmentAdvanced{ .scalar = 0 },3064 => return AbiAlignmentAdvanced{ .scalar = 0 },
31233065
3124 .noreturn,3066 .noreturn,
...@@ -3237,7 +3179,6 @@ pub const Type = extern union {...@@ -3237,7 +3179,6 @@ pub const Type = extern union {
3237 .empty_struct_literal,3179 .empty_struct_literal,
3238 .empty_struct,3180 .empty_struct,
3239 .void,3181 .void,
3240 .error_set_single,
3241 => return AbiSizeAdvanced{ .scalar = 0 },3182 => return AbiSizeAdvanced{ .scalar = 0 },
32423183
3243 .@"struct", .tuple, .anon_struct => switch (ty.containerLayout()) {3184 .@"struct", .tuple, .anon_struct => switch (ty.containerLayout()) {
...@@ -3396,27 +3337,11 @@ pub const Type = extern union {...@@ -3396,27 +3337,11 @@ pub const Type = extern union {
3396 .anyerror_void_error_union,3337 .anyerror_void_error_union,
3397 .anyerror,3338 .anyerror,
3398 .error_set_inferred,3339 .error_set_inferred,
3340 .error_set,
3341 .error_set_merged,
3342 .error_set_single,
3399 => return AbiSizeAdvanced{ .scalar = 2 },3343 => return AbiSizeAdvanced{ .scalar = 2 },
34003344
3401 .error_set => {
3402 const err_set_obj = ty.castTag(.error_set).?.data;
3403 const names = err_set_obj.names.keys();
3404 if (names.len <= 1) {
3405 return AbiSizeAdvanced{ .scalar = 0 };
3406 } else {
3407 return AbiSizeAdvanced{ .scalar = 2 };
3408 }
3409 },
3410 .error_set_merged => {
3411 const name_map = ty.castTag(.error_set_merged).?.data;
3412 const names = name_map.keys();
3413 if (names.len <= 1) {
3414 return AbiSizeAdvanced{ .scalar = 0 };
3415 } else {
3416 return AbiSizeAdvanced{ .scalar = 2 };
3417 }
3418 },
3419
3420 .i16, .u16 => return AbiSizeAdvanced{ .scalar = intAbiSize(16, target) },3345 .i16, .u16 => return AbiSizeAdvanced{ .scalar = intAbiSize(16, target) },
3421 .u29 => return AbiSizeAdvanced{ .scalar = intAbiSize(29, target) },3346 .u29 => return AbiSizeAdvanced{ .scalar = intAbiSize(29, target) },
3422 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },3347 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },
...@@ -3467,24 +3392,6 @@ pub const Type = extern union {...@@ -3467,24 +3392,6 @@ pub const Type = extern union {
3467 // This code needs to be kept in sync with the equivalent switch prong3392 // This code needs to be kept in sync with the equivalent switch prong
3468 // in abiAlignmentAdvanced.3393 // in abiAlignmentAdvanced.
3469 const data = ty.castTag(.error_union).?.data;3394 const data = ty.castTag(.error_union).?.data;
3470 // Here we need to care whether or not the error set is *empty* or whether
3471 // it only has *one possible value*. In the former case, it means there
3472 // cannot possibly be an error, meaning the ABI size is equivalent to the
3473 // payload ABI size. In the latter case, we need to account for the "tag"
3474 // because even if both the payload type and the error set type of an
3475 // error union have no runtime bits, an error union still has
3476 // 1 bit of data which is whether or not the value is an error.
3477 // Zig still uses the error code encoding at runtime, even when only 1 bit
3478 // would suffice. This prevents coercions from needing to branch.
3479 switch (data.error_set.errorSetCardinality()) {
3480 .zero => return abiSizeAdvanced(data.payload, target, strat),
3481 .one => {
3482 if (data.payload.isNoReturn()) {
3483 return AbiSizeAdvanced{ .scalar = 0 };
3484 }
3485 },
3486 .many => {},
3487 }
3488 const code_size = abiSize(Type.anyerror, target);3395 const code_size = abiSize(Type.anyerror, target);
3489 if (!data.payload.hasRuntimeBits()) {3396 if (!data.payload.hasRuntimeBits()) {
3490 // Same as anyerror.3397 // Same as anyerror.
...@@ -3727,11 +3634,7 @@ pub const Type = extern union {...@@ -3727,11 +3634,7 @@ pub const Type = extern union {
37273634
3728 .error_union => {3635 .error_union => {
3729 const payload = ty.castTag(.error_union).?.data;3636 const payload = ty.castTag(.error_union).?.data;
3730 if (!payload.error_set.hasRuntimeBits() and !payload.payload.hasRuntimeBits()) {3637 if (!payload.payload.hasRuntimeBits()) {
3731 return 0;
3732 } else if (!payload.error_set.hasRuntimeBits()) {
3733 return payload.payload.bitSizeAdvanced(target, sema_kit);
3734 } else if (!payload.payload.hasRuntimeBits()) {
3735 return payload.error_set.bitSizeAdvanced(target, sema_kit);3638 return payload.error_set.bitSizeAdvanced(target, sema_kit);
3736 }3639 }
3737 @panic("TODO bitSize error union");3640 @panic("TODO bitSize error union");
...@@ -4351,30 +4254,25 @@ pub const Type = extern union {...@@ -4351,30 +4254,25 @@ pub const Type = extern union {
4351 };4254 };
4352 }4255 }
43534256
4354 const ErrorSetCardinality = enum { zero, one, many };4257 /// Returns false for unresolved inferred error sets.
43554258 pub fn errorSetIsEmpty(ty: Type) bool {
4356 pub fn errorSetCardinality(ty: Type) ErrorSetCardinality {
4357 switch (ty.tag()) {4259 switch (ty.tag()) {
4358 .anyerror => return .many,4260 .anyerror => return false,
4359 .error_set_inferred => return .many,4261 .error_set_inferred => {
4360 .error_set_single => return .one,4262 const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
4263 // Can't know for sure.
4264 if (!inferred_error_set.is_resolved) return false;
4265 if (inferred_error_set.is_anyerror) return false;
4266 return inferred_error_set.errors.count() == 0;
4267 },
4268 .error_set_single => return false,
4361 .error_set => {4269 .error_set => {
4362 const err_set_obj = ty.castTag(.error_set).?.data;4270 const err_set_obj = ty.castTag(.error_set).?.data;
4363 const names = err_set_obj.names.keys();4271 return err_set_obj.names.count() == 0;
4364 switch (names.len) {
4365 0 => return .zero,
4366 1 => return .one,
4367 else => return .many,
4368 }
4369 },4272 },
4370 .error_set_merged => {4273 .error_set_merged => {
4371 const name_map = ty.castTag(.error_set_merged).?.data;4274 const name_map = ty.castTag(.error_set_merged).?.data;
4372 const names = name_map.keys();4275 return name_map.count() == 0;
4373 switch (names.len) {
4374 0 => return .zero,
4375 1 => return .one,
4376 else => return .many,
4377 }
4378 },4276 },
4379 else => unreachable,4277 else => unreachable,
4380 }4278 }
...@@ -4883,6 +4781,10 @@ pub const Type = extern union {...@@ -4883,6 +4781,10 @@ pub const Type = extern union {
4883 .bool,4781 .bool,
4884 .type,4782 .type,
4885 .anyerror,4783 .anyerror,
4784 .error_union,
4785 .error_set_single,
4786 .error_set,
4787 .error_set_merged,
4886 .fn_noreturn_no_args,4788 .fn_noreturn_no_args,
4887 .fn_void_no_args,4789 .fn_void_no_args,
4888 .fn_naked_noreturn_no_args,4790 .fn_naked_noreturn_no_args,
...@@ -4939,42 +4841,6 @@ pub const Type = extern union {...@@ -4939,42 +4841,6 @@ pub const Type = extern union {
4939 }4841 }
4940 },4842 },
49414843
4942 .error_union => {
4943 const error_ty = ty.errorUnionSet();
4944 switch (error_ty.errorSetCardinality()) {
4945 .zero => {
4946 const payload_ty = ty.errorUnionPayload();
4947 if (onePossibleValue(payload_ty)) |payload_val| {
4948 _ = payload_val;
4949 return Value.initTag(.the_only_possible_value);
4950 } else {
4951 return null;
4952 }
4953 },
4954 .one => {
4955 if (ty.errorUnionPayload().isNoReturn()) {
4956 const error_val = onePossibleValue(error_ty).?;
4957 return error_val;
4958 } else {
4959 return null;
4960 }
4961 },
4962 .many => return null,
4963 }
4964 },
4965
4966 .error_set_single => return Value.initTag(.the_only_possible_value),
4967 .error_set => {
4968 const err_set_obj = ty.castTag(.error_set).?.data;
4969 if (err_set_obj.names.count() > 1) return null;
4970 return Value.initTag(.the_only_possible_value);
4971 },
4972 .error_set_merged => {
4973 const name_map = ty.castTag(.error_set_merged).?.data;
4974 if (name_map.count() > 1) return null;
4975 return Value.initTag(.the_only_possible_value);
4976 },
4977
4978 .@"struct" => {4844 .@"struct" => {
4979 const s = ty.castTag(.@"struct").?.data;4845 const s = ty.castTag(.@"struct").?.data;
4980 assert(s.haveFieldTypes());4846 assert(s.haveFieldTypes());
src/value.zig+1
...@@ -1062,6 +1062,7 @@ pub const Value = extern union {...@@ -1062,6 +1062,7 @@ pub const Value = extern union {
1062 sema_kit: ?Module.WipAnalysis,1062 sema_kit: ?Module.WipAnalysis,
1063 ) Module.CompileError!BigIntConst {1063 ) Module.CompileError!BigIntConst {
1064 switch (val.tag()) {1064 switch (val.tag()) {
1065 .null_value,
1065 .zero,1066 .zero,
1066 .bool_false,1067 .bool_false,
1067 .the_only_possible_value, // i0, u01068 .the_only_possible_value, // i0, u0
test/behavior/basic.zig+23
...@@ -1086,3 +1086,26 @@ test "inline call of function with a switch inside the return statement" {...@@ -1086,3 +1086,26 @@ test "inline call of function with a switch inside the return statement" {
1086 };1086 };
1087 try expect(S.foo(1) == 1);1087 try expect(S.foo(1) == 1);
1088}1088}
1089
1090test "namespace lookup ignores decl causing the lookup" {
1091 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1092 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1093 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1094 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1095 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1096
1097 const S = struct {
1098 fn Mixin(comptime T: type) type {
1099 return struct {
1100 fn foo() void {
1101 const set = std.EnumSet(T.E).init(undefined);
1102 _ = set;
1103 }
1104 };
1105 }
1106
1107 const E = enum { a, b };
1108 usingnamespace Mixin(@This());
1109 };
1110 _ = S.foo();
1111}
test/behavior/cast.zig+1
...@@ -1426,6 +1426,7 @@ test "coerce undefined single-item pointer of array to error union of slice" {...@@ -1426,6 +1426,7 @@ test "coerce undefined single-item pointer of array to error union of slice" {
1426}1426}
14271427
1428test "pointer to empty struct literal to mutable slice" {1428test "pointer to empty struct literal to mutable slice" {
1429 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1429 var x: []i32 = &.{};1430 var x: []i32 = &.{};
1430 try expect(x.len == 0);1431 try expect(x.len == 0);
1431}1432}
test/behavior/error.zig-59
...@@ -453,65 +453,6 @@ test "optional error set is the same size as error set" {...@@ -453,65 +453,6 @@ test "optional error set is the same size as error set" {
453 comptime try expect(S.returnsOptErrSet() == null);453 comptime try expect(S.returnsOptErrSet() == null);
454}454}
455455
456test "optional error set with only one error is the same size as bool" {
457 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
459 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
460
461 const E = error{only};
462 comptime try expect(@sizeOf(?E) == @sizeOf(bool));
463 comptime try expect(@alignOf(?E) == @alignOf(bool));
464 const S = struct {
465 fn gimmeNull() ?E {
466 return null;
467 }
468 fn gimmeErr() ?E {
469 return error.only;
470 }
471 };
472 try expect(S.gimmeNull() == null);
473 try expect(error.only == S.gimmeErr().?);
474 comptime try expect(S.gimmeNull() == null);
475 comptime try expect(error.only == S.gimmeErr().?);
476}
477
478test "optional empty error set" {
479 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
480
481 comptime try expect(@sizeOf(error{}!void) == @sizeOf(void));
482 comptime try expect(@alignOf(error{}!void) == @alignOf(void));
483
484 var x: ?error{} = undefined;
485 if (x != null) {
486 @compileError("test failed");
487 }
488}
489
490test "empty error set plus zero-bit payload" {
491 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
492 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
493 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
494
495 comptime try expect(@sizeOf(error{}!void) == @sizeOf(void));
496 comptime try expect(@alignOf(error{}!void) == @alignOf(void));
497
498 var x: error{}!void = undefined;
499 if (x) |payload| {
500 if (payload != {}) {
501 @compileError("test failed");
502 }
503 } else |_| {
504 @compileError("test failed");
505 }
506 const S = struct {
507 fn empty() error{}!void {}
508 fn inferred() !void {
509 return empty();
510 }
511 };
512 try S.inferred();
513}
514
515test "nested catch" {456test "nested catch" {
516 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO457 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
517 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/typename.zig+25-36
...@@ -137,43 +137,8 @@ const A_Enum = enum {...@@ -137,43 +137,8 @@ const A_Enum = enum {
137137
138fn regular() void {}138fn regular() void {}
139139
140test "fn body decl" {
141 if (builtin.zig_backend == .stage1) {
142 // stage1 fails to return fully qualified namespaces.
143 return error.SkipZigTest;
144 }
145
146 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
147 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
150
151 try B.doTest();
152}
153
154const B = struct {140const B = struct {
155 fn doTest() !void {141 fn doTest() !void {}
156 const B_Struct = struct {};
157 const B_Union = union {
158 unused: u8,
159 };
160 const B_Enum = enum {
161 unused,
162 };
163
164 try expectEqualStringsIgnoreDigits(
165 "behavior.typename.B.doTest__struct_0",
166 @typeName(B_Struct),
167 );
168 try expectEqualStringsIgnoreDigits(
169 "behavior.typename.B.doTest__union_0",
170 @typeName(B_Union),
171 );
172 try expectEqualStringsIgnoreDigits(
173 "behavior.typename.B.doTest__enum_0",
174 @typeName(B_Enum),
175 );
176 }
177};142};
178143
179test "fn param" {144test "fn param" {
...@@ -246,3 +211,27 @@ pub fn expectEqualStringsIgnoreDigits(expected: []const u8, actual: []const u8)...@@ -246,3 +211,27 @@ pub fn expectEqualStringsIgnoreDigits(expected: []const u8, actual: []const u8)
246 }211 }
247 return expectEqualStrings(expected, actual_buf[0..actual_i]);212 return expectEqualStrings(expected, actual_buf[0..actual_i]);
248}213}
214
215test "local variable" {
216 if (builtin.zig_backend == .stage1) {
217 // stage1 fails to return fully qualified namespaces.
218 return error.SkipZigTest;
219 }
220
221 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
224 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
225
226 const Foo = struct { a: u32 };
227 const Bar = union { a: u32 };
228 const Baz = enum { a, b };
229 const Qux = enum { a, b };
230 const Quux = enum { a, b };
231
232 try expectEqualStrings("behavior.typename.test.local variable.Foo", @typeName(Foo));
233 try expectEqualStrings("behavior.typename.test.local variable.Bar", @typeName(Bar));
234 try expectEqualStrings("behavior.typename.test.local variable.Baz", @typeName(Baz));
235 try expectEqualStrings("behavior.typename.test.local variable.Qux", @typeName(Qux));
236 try expectEqualStrings("behavior.typename.test.local variable.Quux", @typeName(Quux));
237}
test/behavior/union.zig+18
...@@ -1183,3 +1183,21 @@ test "comptime equality of extern unions with same tag" {...@@ -1183,3 +1183,21 @@ test "comptime equality of extern unions with same tag" {
1183 const b = S.U{ .a = 1234 };1183 const b = S.U{ .a = 1234 };
1184 try expect(S.foo(a) == S.foo(b));1184 try expect(S.foo(a) == S.foo(b));
1185}1185}
1186
1187test "union tag is set when initiated as a temporary value at runtime" {
1188 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1190 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1191
1192 const U = union(enum) {
1193 a,
1194 b: u32,
1195 c,
1196
1197 fn doTheTest(u: @This()) !void {
1198 try expect(u == .b);
1199 }
1200 };
1201 var b: u32 = 1;
1202 try (U{ .b = b }).doTheTest();
1203}