| author | |
| committer | |
| log | ffa700ee58cd29dafe2bbdfe78a4bd4f7bab0674 |
| tree | affe8b6dc716051f32259ad171f93d7009855c0f |
| parent | 6e42d45dccf4ba6fa07082db1cb820897d36924f |
| parent | 0a9d6956e7cac96c870ad062b4125b0a0a3b0143 |
| signature |
Fix (nearly) all stage2 crashes when testing stdlib43 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-1112871321 | 60 | # * https://github.com/ziglang/zig/pull/11492#issuecomment-1112871321 |
| 61 | stage2/bin/zig build test-behavior -fqemu -fwasmtime | 61 | stage2/bin/zig build test-behavior -fqemu -fwasmtime |
| 62 | stage2/bin/zig test lib/std/std.zig --zig-lib-dir lib | ||
| 62 | 63 | ||
| 63 | $ZIG build test-behavior -fqemu -fwasmtime -Domit-stage2 | 64 | $ZIG build test-behavior -fqemu -fwasmtime -Domit-stage2 |
| 64 | $ZIG build test-compiler-rt -fqemu -fwasmtime | 65 | $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 | } |
| 1331 | 1331 | ||
| 1332 | test "IntegerBitSet" { | 1332 | test "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 | } |
| 1342 | 1343 | ||
| 1343 | test "ArrayBitSet" { | 1344 | test "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/9879 | 1347 | // 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 | } |
| 1356 | 1358 | ||
| 1357 | test "DynamicBitSetUnmanaged" { | 1359 | test "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 | } |
| 1396 | 1399 | ||
| 1397 | test "DynamicBitSet" { | 1400 | test "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"); |
| 5 | pub const zlib = @import("compress/zlib.zig"); | 5 | pub const zlib = @import("compress/zlib.zig"); |
| 6 | 6 | ||
| 7 | test { | 7 | test { |
| 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 { |
| 254 | 254 | ||
| 255 | // Inner writer wrapped in a HuffmanBitWriter | 255 | // 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, | ||
| 258 | 261 | ||
| 259 | sync: bool, // requesting flush | 262 | sync: bool, // requesting flush |
| 260 | best_speed_enc: *fast.DeflateFast, // Encoder for best_speed | 263 | 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 | } |
| 124 | 124 | ||
| 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(); |
| 131 | 128 | ||
| 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)); |
| 138 | 135 | ||
| 139 | try testSync(level, input); | 136 | if (builtin.zig_backend == .stage1) { |
| 137 | try testSync(level, input); | ||
| 138 | } | ||
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | fn testToFromWithLimit(input: []const u8, limit: [11]u32) !void { | 141 | fn 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 | } |
| 477 | 476 | ||
| 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(); |
| 484 | 480 | ||
| 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); |
| 488 | 484 | ||
| 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 | ); | ||
| 493 | 487 | ||
| 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 | } |
| 532 | 526 | ||
| 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(); |
| 539 | 530 | ||
| 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); |
| 543 | 534 | ||
| 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 | ); | ||
| 548 | 537 | ||
| 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 { |
| 334 | 334 | ||
| 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 | } |
| 480 | 483 | ||
| 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 | }; |
| 921 | 930 | ||
| 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 | }; |
| 960 | 970 | ||
| 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(); |
| 965 | 976 | ||
| ... | @@ -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 | ; |
| 1019 | 1030 | ||
| 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(); |
| 1023 | 1035 | ||
| ... | @@ -1082,7 +1094,8 @@ test "fuzzing" { | ... | @@ -1082,7 +1094,8 @@ test "fuzzing" { |
| 1082 | 1094 | ||
| 1083 | fn decompress(input: []const u8) !void { | 1095 | fn 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); |
| 80 | 80 | ||
| 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(); |
| 87 | 84 | ||
| 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, which | 120 | // 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); |
| 128 | 125 | ||
| 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); |
| 151 | 148 | ||
| 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 | } |
| 898 | 898 | ||
| 899 | test "phc format hasher" { | 899 | test "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"; |
| 902 | 903 | ||
| ... | @@ -912,6 +913,7 @@ test "phc format hasher" { | ... | @@ -912,6 +913,7 @@ test "phc format hasher" { |
| 912 | } | 913 | } |
| 913 | 914 | ||
| 914 | test "password hash and password verify" { | 915 | test "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"; |
| 917 | 919 |
lib/std/crypto/bcrypt.zig+1| ... | @@ -802,6 +802,7 @@ test "bcrypt crypt format" { | ... | @@ -802,6 +802,7 @@ test "bcrypt crypt format" { |
| 802 | } | 802 | } |
| 803 | 803 | ||
| 804 | test "bcrypt phc format" { | 804 | test "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 | } |
| 261 | 261 | ||
| 262 | test "phc format - encoding/decoding" { | 262 | test "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 | } |
| 684 | 684 | ||
| 685 | test "crypt format" { | 685 | test "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 | } |
| 2112 | 2112 | ||
| 2113 | test "escape non-printable" { | 2113 | test "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 | } |
| 2149 | 2148 | ||
| 2150 | test "filesize" { | 2149 | test "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 | } |
| 2193 | 2191 | ||
| 2194 | test "non-exhaustive enum" { | 2192 | test "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 | } |
| 2208 | 2210 | ||
| 2209 | test "float.scientific" { | 2211 | test "float.scientific" { |
| ... | @@ -2223,6 +2225,7 @@ test "float.scientific.precision" { | ... | @@ -2223,6 +2225,7 @@ test "float.scientific.precision" { |
| 2223 | } | 2225 | } |
| 2224 | 2226 | ||
| 2225 | test "float.special" { | 2227 | test "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 nan | 2231 | // and ARM thus normalizes it to positive nan |
| ... | @@ -2234,6 +2237,7 @@ test "float.special" { | ... | @@ -2234,6 +2237,7 @@ test "float.special" { |
| 2234 | } | 2237 | } |
| 2235 | 2238 | ||
| 2236 | test "float.hexadecimal.special" { | 2239 | test "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 nan | 2243 | // and ARM thus normalizes it to positive nan |
| ... | @@ -2359,6 +2363,10 @@ test "custom" { | ... | @@ -2359,6 +2363,10 @@ test "custom" { |
| 2359 | } | 2363 | } |
| 2360 | 2364 | ||
| 2361 | test "struct" { | 2365 | test "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 | }; |
| 2371 | 2379 | ||
| 2372 | try expectFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst}); | 2380 | try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst}); |
| 2373 | // Tuples | 2381 | // 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 | } |
| 2378 | 2386 | ||
| 2379 | test "union" { | 2387 | test "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 }; |
| 2398 | 2410 | ||
| 2399 | try expectFmt("TU{ .int = 123 }", "{}", .{tu_inst}); | 2411 | try expectFmt("fmt.test.union.TU{ .int = 123 }", "{}", .{tu_inst}); |
| 2400 | 2412 | ||
| 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@")); |
| 2404 | 2416 | ||
| 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 | } |
| 2408 | 2420 | ||
| 2409 | test "enum" { | 2421 | test "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" { |
| 2415 | 2431 | ||
| 2416 | const inst = E.Two; | 2432 | const inst = E.Two; |
| 2417 | 2433 | ||
| 2418 | try expectFmt("E.Two", "{}", .{inst}); | 2434 | try expectFmt("fmt.test.enum.E.Two", "{}", .{inst}); |
| 2419 | } | 2435 | } |
| 2420 | 2436 | ||
| 2421 | test "struct.self-referential" { | 2437 | test "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; |
| 2431 | 2451 | ||
| 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 | } |
| 2434 | 2454 | ||
| 2435 | test "struct.zero-size" { | 2455 | test "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 }; |
| 2446 | 2470 | ||
| 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 | } |
| 2449 | 2473 | ||
| 2450 | test "bytes.hex" { | 2474 | test "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 | } |
| 2481 | 2504 | ||
| 2482 | test "hexToBytes" { | 2505 | test "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 | } |
| 2513 | 2535 | ||
| 2514 | test "formatType max_depth" { | 2536 | test "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{ ... }")); |
| 2566 | 2592 | ||
| 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) }")); |
| 2570 | 2596 | ||
| 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) }")); |
| 2574 | 2600 | ||
| 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 | } |
| 2579 | 2605 | ||
| 2580 | test "positional" { | 2606 | test "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 | } |
| 115 | 115 | ||
| 116 | test "StreamSource (const buffer)" { | 116 | test "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) }; |
| 120 | 119 |
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 | } |
| 14 | 14 | ||
| 15 | test "math.copysign" { | 15 | test "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 | } |
| 11 | 11 | ||
| 12 | test "math.signbit" { | 12 | test "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 | } |
| 2081 | 2081 | ||
| 2082 | test "writeIntSlice" { | 2082 | test "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); |
| 286 | const PQgt = PriorityQueue(u32, void, greaterThan); | 286 | const PQgt = PriorityQueue(u32, void, greaterThan); |
| 287 | 287 | ||
| 288 | test "std.PriorityQueue: add and remove min heap" { | 288 | test "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(); |
| 291 | 292 | ||
| ... | @@ -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 | } |
| 305 | 306 | ||
| 306 | test "std.PriorityQueue: add and remove same min heap" { | 307 | test "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(); |
| 309 | 311 | ||
| ... | @@ -353,6 +355,7 @@ test "std.PriorityQueue: peek" { | ... | @@ -353,6 +355,7 @@ test "std.PriorityQueue: peek" { |
| 353 | } | 355 | } |
| 354 | 356 | ||
| 355 | test "std.PriorityQueue: sift up with odd indices" { | 357 | test "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 | } |
| 368 | 371 | ||
| 369 | test "std.PriorityQueue: addSlice" { | 372 | test "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 | } |
| 413 | 417 | ||
| 414 | test "std.PriorityQueue: add and remove max heap" { | 418 | test "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(); |
| 417 | 422 | ||
| ... | @@ -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 | } |
| 431 | 436 | ||
| 432 | test "std.PriorityQueue: add and remove same max heap" { | 437 | test "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(); |
| 435 | 441 | ||
| ... | @@ -470,6 +476,7 @@ test "std.PriorityQueue: iterator" { | ... | @@ -470,6 +476,7 @@ test "std.PriorityQueue: iterator" { |
| 470 | } | 476 | } |
| 471 | 477 | ||
| 472 | test "std.PriorityQueue: remove at index" { | 478 | test "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(); |
| 475 | 482 | ||
| ... | @@ -505,6 +512,7 @@ test "std.PriorityQueue: iterator while empty" { | ... | @@ -505,6 +512,7 @@ test "std.PriorityQueue: iterator while empty" { |
| 505 | } | 512 | } |
| 506 | 513 | ||
| 507 | test "std.PriorityQueue: shrinkAndFree" { | 514 | test "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(); |
| 510 | 518 | ||
| ... | @@ -528,6 +536,7 @@ test "std.PriorityQueue: shrinkAndFree" { | ... | @@ -528,6 +536,7 @@ test "std.PriorityQueue: shrinkAndFree" { |
| 528 | } | 536 | } |
| 529 | 537 | ||
| 530 | test "std.PriorityQueue: update min heap" { | 538 | test "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(); |
| 533 | 542 | ||
| ... | @@ -543,6 +552,7 @@ test "std.PriorityQueue: update min heap" { | ... | @@ -543,6 +552,7 @@ test "std.PriorityQueue: update min heap" { |
| 543 | } | 552 | } |
| 544 | 553 | ||
| 545 | test "std.PriorityQueue: update same min heap" { | 554 | test "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(); |
| 548 | 558 | ||
| ... | @@ -559,6 +569,7 @@ test "std.PriorityQueue: update same min heap" { | ... | @@ -559,6 +569,7 @@ test "std.PriorityQueue: update same min heap" { |
| 559 | } | 569 | } |
| 560 | 570 | ||
| 561 | test "std.PriorityQueue: update max heap" { | 571 | test "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(); |
| 564 | 575 | ||
| ... | @@ -574,6 +585,7 @@ test "std.PriorityQueue: update max heap" { | ... | @@ -574,6 +585,7 @@ test "std.PriorityQueue: update max heap" { |
| 574 | } | 585 | } |
| 575 | 586 | ||
| 576 | test "std.PriorityQueue: update same max heap" { | 587 | test "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(); |
| 579 | 591 | ||
| ... | @@ -590,6 +602,7 @@ test "std.PriorityQueue: update same max heap" { | ... | @@ -590,6 +602,7 @@ test "std.PriorityQueue: update same max heap" { |
| 590 | } | 602 | } |
| 591 | 603 | ||
| 592 | test "std.PriorityQueue: siftUp in remove" { | 604 | test "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(); |
| 595 | 608 | ||
| ... | @@ -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 { |
| 610 | const CPQlt = PriorityQueue(usize, []const u32, contextLessThan); | 623 | const CPQlt = PriorityQueue(usize, []const u32, contextLessThan); |
| 611 | 624 | ||
| 612 | test "std.PriorityQueue: add and remove min heap with contextful comparator" { | 625 | test "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 }; |
| 614 | 628 | ||
| 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 | }; |
| 215 | 215 | ||
| 216 | test "slim" { | 216 | test "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); |
| 219 | 220 | ||
| ... | @@ -227,6 +228,7 @@ test "slim" { | ... | @@ -227,6 +228,7 @@ test "slim" { |
| 227 | } | 228 | } |
| 228 | 229 | ||
| 229 | test "fat" { | 230 | test "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); |
| 232 | 234 | ||
| ... | @@ -239,6 +241,7 @@ test "fat" { | ... | @@ -239,6 +241,7 @@ test "fat" { |
| 239 | } | 241 | } |
| 240 | 242 | ||
| 241 | test "legacy" { | 243 | test "legacy" { |
| 244 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 242 | // Taken from Slackware 8.0, from 2001 | 245 | // 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 | } |
| 805 | 805 | ||
| 806 | test "fmtUtf16le" { | 806 | test "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 | }; |
| 14 | 14 | ||
| 15 | test { | 15 | test { |
| 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 | }; |
| 118 | 118 | ||
| 119 | test "reactor/linux: drive async tcp client/listener pair" { | 119 | test "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; |
| 121 | 122 | ||
| 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 | } |
| 383 | 383 | ||
| 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; | ||
| 2757 | 2760 | ||
| 2758 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); | 2761 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); |
| 2759 | 2762 | ||
| ... | @@ -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_scope | 2781 | // 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(); |
| 2781 | 2785 | ||
| 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); |
| 3791 | 3791 | ||
| 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 | } |
| 3797 | 3800 | ||
| 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: off | 914 | // 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( |
| 2188 | 2191 | ||
| 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 | } |
| 2196 | 2221 | ||
| ... | @@ -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 | } |
| 6182 | 6211 | ||
| 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( |
| 6558 | 6598 | ||
| 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() and | 6600 | 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( |
| 6644 | 6684 | ||
| 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() and | 6686 | 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 alignment | 11910 | 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: u32 | 11921 | // 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); | ||
| 13715 | 13761 | ||
| 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 | } |
| 13739 | 13786 | ||
| ... | @@ -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 slice | 19747 | // pointer to tuple to slice |
| 19701 | if (inst_ty.isSinglePointer() and | 19748 | if (inst_ty.isSinglePointer() and |
| 19702 | inst_ty.childType().isTuple() and | 19749 | 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); |
| 23576 | 23634 | ||
| 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; |
| 23580 | 23638 | ||
| 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 | }, |
| 24483 | 24545 | ||
| 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(".{ "); |
| 195 | 229 | ||
| 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 | } | ||
| 294 | 336 | ||
| 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 | }, |
| 387 | 440 | ||
| 388 | // TODO these should not appear in this function | 441 | // 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 | }; |
| 3160 | 3162 | ||
| 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 { |
| 2277 | fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { | 2277 | fn 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 { |
| 2311 | fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { | 2311 | fn 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(); |
| 3592 | 3592 | ||
| 3593 | if (error_type.errorSetCardinality() == .zero) { | 3593 | if (error_type.errorSetIsEmpty()) { |
| 3594 | return MCValue{ .immediate = 0 }; // always false | 3594 | return MCValue{ .immediate = 0 }; // always false |
| 3595 | } | 3595 | } |
| 3596 | 3596 | ||
| ... | @@ -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(); |
| 4689 | 4689 | ||
| 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(); |
| 4696 | 4691 | ||
| 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 { |
| 1773 | fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { | 1773 | fn 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 { |
| 1810 | fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { | 1810 | fn 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); |
| 3924 | 3924 | ||
| 3925 | if (error_type.errorSetCardinality() == .zero) { | 3925 | if (error_type.errorSetIsEmpty()) { |
| 3926 | return MCValue{ .immediate = 0 }; // always false | 3926 | return MCValue{ .immediate = 0 }; // always false |
| 3927 | } | 3927 | } |
| 3928 | 3928 | ||
| ... | @@ -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(); |
| 5378 | 5372 | ||
| 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 { |
| 1817 | fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void { | 1813 | fn 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(); |
| 2931 | 2919 | ||
| 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(); |
| 2964 | 2952 | ||
| 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 = {} }; |
| 2970 | 2954 | ||
| 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(); |
| 2986 | 2970 | ||
| 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 | } |
| 2990 | 2974 | ||
| ... | @@ -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); |
| 3004 | 2988 | ||
| 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 | } |
| 4635 | 4615 | ||
| 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(); |
| 4642 | 4618 | ||
| 4643 | // Block we can jump out of when error is not set | 4619 | 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 |
| 4645 | 4621 | 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(); | ||
| 4659 | 4637 | ||
| 4660 | // if we reach here it means error was not set, and we want the payload | 4638 | // 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); |
| 1807 | 1807 | ||
| 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 | } |
| 1812 | 1812 | ||
| ... | @@ -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(); | ||
| 1861 | 1860 | ||
| 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 | } |
| 1992 | 1986 | ||
| 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); |
| 1997 | 1990 | ||
| 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 |
| 4651 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { | 4640 | fn 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(); |
| 4653 | 4642 | ||
| 4654 | if (err_type.errorSetCardinality() == .zero) { | 4643 | if (err_type.errorSetIsEmpty()) { |
| 4655 | return MCValue{ .immediate = 0 }; // always false | 4644 | return MCValue{ .immediate = 0 }; // always false |
| 4656 | } | 4645 | } |
| 4657 | 4646 | ||
| ... | @@ -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(); |
| 6919 | 6902 | ||
| 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(); |
| 718 | 709 | ||
| 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(); |
| 754 | 754 | ||
| 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(); |
| 1386 | 1379 | ||
| 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(); |
| 2903 | 2887 | ||
| 2904 | const writer = f.object.writer(); | 2888 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 2905 | 2889 | 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 | } | ||
| 2927 | 2910 | ||
| 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 | } | ||
| 2930 | 2914 | ||
| 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 { |
| 3466 | 3450 | ||
| 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; |
| 3509 | 3493 | ||
| 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(); |
| 3577 | 3557 | ||
| 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); |
| 3624 | 3599 | ||
| 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( |
| 3652 | 3624 | ||
| 3653 | try writer.writeAll(" = "); | 3625 | try writer.writeAll(" = "); |
| 3654 | 3626 | ||
| 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 | } |
| 601 | 601 | ||
| 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 error | 611 | // 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 { |
| 606 | 613 | ||
| 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 | } |
| 612 | 624 | ||
| 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 | else | 627 | 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(); |
| 3225 | 3201 | ||
| 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 | } |
| 4791 | 4767 | ||
| 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 | }; | ||
| 4818 | 4790 | ||
| 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); |
| 4822 | 4794 | ||
| 4823 | fg.builder.positionBuilderAtEnd(return_block); | 4795 | fg.builder.positionBuilderAtEnd(return_block); |
| 4824 | try fg.genBody(body); | 4796 | try fg.genBody(body); |
| 4825 | 4797 | ||
| 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; |
| 4829 | 4802 | ||
| ... | @@ -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(); |
| 5662 | 5635 | ||
| 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 == 0 | 5639 | .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 { |
| 5783 | 5756 | ||
| 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(); |
| 5853 | 5819 | ||
| 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 { |
| 390 | 390 | ||
| 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 | }; |
| 394 | 397 | ||
| 395 | pub const lookupIntrinsicID = LLVMLookupIntrinsicID; | 398 | pub 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; |
| 4 | 4 | ||
| 5 | const Module = @import("Module.zig"); | 5 | const Module = @import("Module.zig"); |
| 6 | const Value = @import("value.zig").Value; | 6 | const Value = @import("value.zig").Value; |
| 7 | const Type = @import("type.zig").Type; | ||
| 7 | const Air = @import("Air.zig"); | 8 | const Air = @import("Air.zig"); |
| 8 | const Liveness = @import("Liveness.zig"); | 9 | const Liveness = @import("Liveness.zig"); |
| 9 | 10 | ||
| ... | @@ -304,14 +305,27 @@ const Writer = struct { | ... | @@ -304,14 +305,27 @@ const Writer = struct { |
| 304 | // no-op, no argument to write | 305 | // no-op, no argument to write |
| 305 | } | 306 | } |
| 306 | 307 | ||
| 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 | } |
| 311 | 324 | ||
| 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 | } |
| 317 | 331 | ||
| ... | @@ -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]; |
| 322 | 336 | ||
| 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]); |
| 337 | 352 | ||
| 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; |
| 409 | 425 | ||
| 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 | } |
| 516 | 535 | ||
| 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; |
| 524 | 543 | ||
| 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); |
| 527 | 546 | ||
| 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]; |
| 648 | 667 | ||
| 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, |
| 2370 | 2374 | ||
| 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, |
| 2394 | 2397 | ||
| 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 as | 2398 | // 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 | }, |
| 2445 | 2437 | ||
| 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 }, |
| 2930 | 2906 | ||
| 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), |
| 2951 | 2908 | ||
| 2952 | // TODO audit this - is there any more complicated logic to determine | 2909 | // 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 { |
| 2971 | 2928 | ||
| 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 prong | 2951 | // 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 }, |
| 3123 | 3065 | ||
| 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 }, |
| 3242 | 3183 | ||
| 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 }, |
| 3400 | 3344 | ||
| 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 prong | 3392 | // 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 { |
| 3727 | 3634 | ||
| 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 | } |
| 4353 | 4256 | ||
| 4354 | const ErrorSetCardinality = enum { zero, one, many }; | 4257 | /// Returns false for unresolved inferred error sets. |
| 4355 | 4258 | 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 | }, |
| 4941 | 4843 | ||
| 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, u0 | 1068 | .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 | |||
| 1090 | test "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 | } |
| 1427 | 1427 | ||
| 1428 | test "pointer to empty struct literal to mutable slice" { | 1428 | test "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 | } |
| 455 | 455 | ||
| 456 | test "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 | |||
| 478 | test "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 | |||
| 490 | test "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 | |||
| 515 | test "nested catch" { | 456 | test "nested catch" { |
| 516 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 457 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 517 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 458 | 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 { |
| 137 | 137 | ||
| 138 | fn regular() void {} | 138 | fn regular() void {} |
| 139 | 139 | ||
| 140 | test "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 | |||
| 154 | const B = struct { | 140 | const 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 | }; |
| 178 | 143 | ||
| 179 | test "fn param" { | 144 | test "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 | |||
| 215 | test "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 | |||
| 1187 | test "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 | } |