authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-04 16:29:26-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-04 16:29:26-04:00
log43db697b46e362e5991005f6c7b8b16ddc9bddbb
treee53320c89cff35f60a1e11e57a0c938f0b793021
parente498fb155051f548071da1a13098b8793f527275
parent50a6b0f3acb2a17f74d57301dbf3d4b13e30953b
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11789 from Vexu/stage2

Stage2 fixes towards `zig2 build test-std` working

23 files changed, 363 insertions(+), 177 deletions(-)

lib/compiler_rt/log2.zig+2-1
...@@ -147,7 +147,8 @@ pub fn __log2x(a: f80) callconv(.C) f80 {...@@ -147,7 +147,8 @@ pub fn __log2x(a: f80) callconv(.C) f80 {
147}147}
148148
149pub fn log2q(a: f128) callconv(.C) f128 {149pub fn log2q(a: f128) callconv(.C) f128 {
150 return math.log2(a);150 // TODO: more correct implementation
151 return log2(@floatCast(f64, a));
151}152}
152153
153pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble {154pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble {
lib/std/compress.zig+1
...@@ -5,6 +5,7 @@ pub const gzip = @import("compress/gzip.zig");...@@ -5,6 +5,7 @@ pub const gzip = @import("compress/gzip.zig");
5pub const zlib = @import("compress/zlib.zig");5pub const zlib = @import("compress/zlib.zig");
66
7test {7test {
8 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
8 _ = deflate;9 _ = deflate;
9 _ = gzip;10 _ = gzip;
10 _ = zlib;11 _ = zlib;
lib/std/crypto/25519/scalar.zig+8-4
...@@ -34,12 +34,14 @@ pub fn rejectNonCanonical(s: CompressedScalar) NonCanonicalError!void {...@@ -34,12 +34,14 @@ pub fn rejectNonCanonical(s: CompressedScalar) NonCanonicalError!void {
3434
35/// Reduce a scalar to the field size.35/// Reduce a scalar to the field size.
36pub fn reduce(s: CompressedScalar) CompressedScalar {36pub fn reduce(s: CompressedScalar) CompressedScalar {
37 return Scalar.fromBytes(s).toBytes();37 var scalar = Scalar.fromBytes(s);
38 return scalar.toBytes();
38}39}
3940
40/// Reduce a 64-bytes scalar to the field size.41/// Reduce a 64-bytes scalar to the field size.
41pub fn reduce64(s: [64]u8) CompressedScalar {42pub fn reduce64(s: [64]u8) CompressedScalar {
42 return ScalarDouble.fromBytes64(s).toBytes();43 var scalar = ScalarDouble.fromBytes64(s);
44 return scalar.toBytes();
43}45}
4446
45/// Perform the X25519 "clamping" operation.47/// Perform the X25519 "clamping" operation.
...@@ -106,12 +108,14 @@ pub const Scalar = struct {...@@ -106,12 +108,14 @@ pub const Scalar = struct {
106108
107 /// Unpack a 32-byte representation of a scalar109 /// Unpack a 32-byte representation of a scalar
108 pub fn fromBytes(bytes: CompressedScalar) Scalar {110 pub fn fromBytes(bytes: CompressedScalar) Scalar {
109 return ScalarDouble.fromBytes32(bytes).reduce(5);111 var scalar = ScalarDouble.fromBytes32(bytes);
112 return scalar.reduce(5);
110 }113 }
111114
112 /// Unpack a 64-byte representation of a scalar115 /// Unpack a 64-byte representation of a scalar
113 pub fn fromBytes64(bytes: [64]u8) Scalar {116 pub fn fromBytes64(bytes: [64]u8) Scalar {
114 return ScalarDouble.fromBytes64(bytes).reduce(5);117 var scalar = ScalarDouble.fromBytes64(bytes);
118 return scalar.reduce(5);
115 }119 }
116120
117 /// Pack a scalar into bytes121 /// Pack a scalar into bytes
lib/std/crypto/blake3.zig+6-3
...@@ -679,9 +679,12 @@ fn testBlake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) !void {...@@ -679,9 +679,12 @@ fn testBlake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) !void {
679}679}
680680
681test "BLAKE3 reference test cases" {681test "BLAKE3 reference test cases" {
682 var hash = &Blake3.init(.{});682 var hash_state = Blake3.init(.{});
683 var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* });683 const hash = &hash_state;
684 var derive_key = &Blake3.initKdf(reference_test.context_string, .{});684 var keyed_hash_state = Blake3.init(.{ .key = reference_test.key.* });
685 const keyed_hash = &keyed_hash_state;
686 var derive_key_state = Blake3.initKdf(reference_test.context_string, .{});
687 const derive_key = &derive_key_state;
685688
686 for (reference_test.cases) |t| {689 for (reference_test.cases) |t| {
687 try testBlake3(hash, t.input_len, t.hash.*);690 try testBlake3(hash, t.input_len, t.hash.*);
lib/std/crypto/sha3.zig+3-5
...@@ -128,18 +128,16 @@ fn keccakF(comptime F: usize, d: *[F / 8]u8) void {...@@ -128,18 +128,16 @@ fn keccakF(comptime F: usize, d: *[F / 8]u8) void {
128 r.* = mem.readIntLittle(u64, d[8 * i ..][0..8]);128 r.* = mem.readIntLittle(u64, d[8 * i ..][0..8]);
129 }129 }
130130
131 comptime var x: usize = 0;
132 comptime var y: usize = 0;
133 for (RC[0..no_rounds]) |round| {131 for (RC[0..no_rounds]) |round| {
134 // theta132 // theta
135 x = 0;133 comptime var x: usize = 0;
136 inline while (x < 5) : (x += 1) {134 inline while (x < 5) : (x += 1) {
137 c[x] = s[x] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20];135 c[x] = s[x] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20];
138 }136 }
139 x = 0;137 x = 0;
140 inline while (x < 5) : (x += 1) {138 inline while (x < 5) : (x += 1) {
141 t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], @as(usize, 1));139 t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], @as(usize, 1));
142 y = 0;140 comptime var y: usize = 0;
143 inline while (y < 5) : (y += 1) {141 inline while (y < 5) : (y += 1) {
144 s[x + y * 5] ^= t[0];142 s[x + y * 5] ^= t[0];
145 }143 }
...@@ -155,7 +153,7 @@ fn keccakF(comptime F: usize, d: *[F / 8]u8) void {...@@ -155,7 +153,7 @@ fn keccakF(comptime F: usize, d: *[F / 8]u8) void {
155 }153 }
156154
157 // chi155 // chi
158 y = 0;156 comptime var y: usize = 0;
159 inline while (y < 5) : (y += 1) {157 inline while (y < 5) : (y += 1) {
160 x = 0;158 x = 0;
161 inline while (x < 5) : (x += 1) {159 inline while (x < 5) : (x += 1) {
lib/std/event/batch.zig+1
...@@ -109,6 +109,7 @@ pub fn Batch(...@@ -109,6 +109,7 @@ pub fn Batch(
109}109}
110110
111test "std.event.Batch" {111test "std.event.Batch" {
112 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
112 var count: usize = 0;113 var count: usize = 0;
113 var batch = Batch(void, 2, .auto_async).init();114 var batch = Batch(void, 2, .auto_async).init();
114 batch.add(&async sleepALittle(&count));115 batch.add(&async sleepALittle(&count));
lib/std/fmt.zig+5
...@@ -2111,6 +2111,7 @@ test "slice" {...@@ -2111,6 +2111,7 @@ test "slice" {
2111}2111}
21122112
2113test "escape non-printable" {2113test "escape non-printable" {
2114 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2114 try expectFmt("abc", "{s}", .{fmtSliceEscapeLower("abc")});2115 try expectFmt("abc", "{s}", .{fmtSliceEscapeLower("abc")});
2115 try expectFmt("ab\\xffc", "{s}", .{fmtSliceEscapeLower("ab\xffc")});2116 try expectFmt("ab\\xffc", "{s}", .{fmtSliceEscapeLower("ab\xffc")});
2116 try expectFmt("ab\\xFFc", "{s}", .{fmtSliceEscapeUpper("ab\xffc")});2117 try expectFmt("ab\\xFFc", "{s}", .{fmtSliceEscapeUpper("ab\xffc")});
...@@ -2122,6 +2123,7 @@ test "pointer" {...@@ -2122,6 +2123,7 @@ test "pointer" {
2122 try expectFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});2123 try expectFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});
2123 try expectFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});2124 try expectFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});
2124 }2125 }
2126 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2125 {2127 {
2126 const value = @intToPtr(fn () void, 0xdeadbeef);2128 const value = @intToPtr(fn () void, 0xdeadbeef);
2127 try expectFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});2129 try expectFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
...@@ -2146,6 +2148,7 @@ test "cstr" {...@@ -2146,6 +2148,7 @@ test "cstr" {
2146}2148}
21472149
2148test "filesize" {2150test "filesize" {
2151 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2149 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeDec(42)});2152 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeDec(42)});
2150 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeBin(42)});2153 try expectFmt("file size: 42B\n", "file size: {}\n", .{fmtIntSizeBin(42)});
2151 try expectFmt("file size: 63MB\n", "file size: {}\n", .{fmtIntSizeDec(63 * 1000 * 1000)});2154 try expectFmt("file size: 63MB\n", "file size: {}\n", .{fmtIntSizeDec(63 * 1000 * 1000)});
...@@ -2445,6 +2448,7 @@ test "struct.zero-size" {...@@ -2445,6 +2448,7 @@ test "struct.zero-size" {
2445}2448}
24462449
2447test "bytes.hex" {2450test "bytes.hex" {
2451 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2448 const some_bytes = "\xCA\xFE\xBA\xBE";2452 const some_bytes = "\xCA\xFE\xBA\xBE";
2449 try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(some_bytes)});2453 try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(some_bytes)});
2450 try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{fmtSliceHexUpper(some_bytes)});2454 try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{fmtSliceHexUpper(some_bytes)});
...@@ -2476,6 +2480,7 @@ pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {...@@ -2476,6 +2480,7 @@ pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {
2476}2480}
24772481
2478test "hexToBytes" {2482test "hexToBytes" {
2483 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
2479 var buf: [32]u8 = undefined;2484 var buf: [32]u8 = undefined;
2480 try expectFmt("90" ** 32, "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "90" ** 32))});2485 try expectFmt("90" ** 32, "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "90" ** 32))});
2481 try expectFmt("ABCD", "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "ABCD"))});2486 try expectFmt("ABCD", "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "ABCD"))});
lib/std/heap.zig+2-1
...@@ -1210,7 +1210,8 @@ pub fn testAllocatorAlignedShrink(base_allocator: mem.Allocator) !void {...@@ -1210,7 +1210,8 @@ pub fn testAllocatorAlignedShrink(base_allocator: mem.Allocator) !void {
1210 const allocator = validationAllocator.allocator();1210 const allocator = validationAllocator.allocator();
12111211
1212 var debug_buffer: [1000]u8 = undefined;1212 var debug_buffer: [1000]u8 = undefined;
1213 const debug_allocator = FixedBufferAllocator.init(&debug_buffer).allocator();1213 var fib = FixedBufferAllocator.init(&debug_buffer);
1214 const debug_allocator = fib.allocator();
12141215
1215 const alloc_size = mem.page_size * 2 + 50;1216 const alloc_size = mem.page_size * 2 + 50;
1216 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);1217 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);
lib/std/heap/log_to_writer_allocator.zig+2-1
...@@ -91,7 +91,8 @@ test "LogToWriterAllocator" {...@@ -91,7 +91,8 @@ test "LogToWriterAllocator" {
9191
92 var allocator_buf: [10]u8 = undefined;92 var allocator_buf: [10]u8 = undefined;
93 var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));93 var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));
94 const allocator = logToWriterAllocator(fixedBufferAllocator.allocator(), fbs.writer()).allocator();94 var allocator_state = logToWriterAllocator(fixedBufferAllocator.allocator(), fbs.writer());
95 const allocator = allocator_state.allocator();
9596
96 var a = try allocator.alloc(u8, 10);97 var a = try allocator.alloc(u8, 10);
97 a = allocator.shrink(a, 5);98 a = allocator.shrink(a, 5);
lib/std/io/reader.zig+64-32
...@@ -344,7 +344,8 @@ pub fn Reader(...@@ -344,7 +344,8 @@ pub fn Reader(
344344
345test "Reader" {345test "Reader" {
346 var buf = "a\x02".*;346 var buf = "a\x02".*;
347 const reader = std.io.fixedBufferStream(&buf).reader();347 var fis = std.io.fixedBufferStream(&buf);
348 const reader = fis.reader();
348 try testing.expect((try reader.readByte()) == 'a');349 try testing.expect((try reader.readByte()) == 'a');
349 try testing.expect((try reader.readEnum(enum(u8) {350 try testing.expect((try reader.readEnum(enum(u8) {
350 a = 0,351 a = 0,
...@@ -356,13 +357,15 @@ test "Reader" {...@@ -356,13 +357,15 @@ test "Reader" {
356}357}
357358
358test "Reader.isBytes" {359test "Reader.isBytes" {
359 const reader = std.io.fixedBufferStream("foobar").reader();360 var fis = std.io.fixedBufferStream("foobar");
361 const reader = fis.reader();
360 try testing.expectEqual(true, try reader.isBytes("foo"));362 try testing.expectEqual(true, try reader.isBytes("foo"));
361 try testing.expectEqual(false, try reader.isBytes("qux"));363 try testing.expectEqual(false, try reader.isBytes("qux"));
362}364}
363365
364test "Reader.skipBytes" {366test "Reader.skipBytes" {
365 const reader = std.io.fixedBufferStream("foobar").reader();367 var fis = std.io.fixedBufferStream("foobar");
368 const reader = fis.reader();
366 try reader.skipBytes(3, .{});369 try reader.skipBytes(3, .{});
367 try testing.expect(try reader.isBytes("bar"));370 try testing.expect(try reader.isBytes("bar"));
368 try reader.skipBytes(0, .{});371 try reader.skipBytes(0, .{});
...@@ -374,7 +377,8 @@ test "Reader.readUntilDelimiterArrayList returns ArrayLists with bytes read unti...@@ -374,7 +377,8 @@ test "Reader.readUntilDelimiterArrayList returns ArrayLists with bytes read unti
374 var list = std.ArrayList(u8).init(a);377 var list = std.ArrayList(u8).init(a);
375 defer list.deinit();378 defer list.deinit();
376379
377 const reader = std.io.fixedBufferStream("0000\n1234\n").reader();380 var fis = std.io.fixedBufferStream("0000\n1234\n");
381 const reader = fis.reader();
378382
379 try reader.readUntilDelimiterArrayList(&list, '\n', 5);383 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
380 try std.testing.expectEqualStrings("0000", list.items);384 try std.testing.expectEqualStrings("0000", list.items);
...@@ -388,7 +392,8 @@ test "Reader.readUntilDelimiterArrayList returns an empty ArrayList" {...@@ -388,7 +392,8 @@ test "Reader.readUntilDelimiterArrayList returns an empty ArrayList" {
388 var list = std.ArrayList(u8).init(a);392 var list = std.ArrayList(u8).init(a);
389 defer list.deinit();393 defer list.deinit();
390394
391 const reader = std.io.fixedBufferStream("\n").reader();395 var fis = std.io.fixedBufferStream("\n");
396 const reader = fis.reader();
392397
393 try reader.readUntilDelimiterArrayList(&list, '\n', 5);398 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
394 try std.testing.expectEqualStrings("", list.items);399 try std.testing.expectEqualStrings("", list.items);
...@@ -399,7 +404,8 @@ test "Reader.readUntilDelimiterArrayList returns StreamTooLong, then an ArrayLis...@@ -399,7 +404,8 @@ test "Reader.readUntilDelimiterArrayList returns StreamTooLong, then an ArrayLis
399 var list = std.ArrayList(u8).init(a);404 var list = std.ArrayList(u8).init(a);
400 defer list.deinit();405 defer list.deinit();
401406
402 const reader = std.io.fixedBufferStream("1234567\n").reader();407 var fis = std.io.fixedBufferStream("1234567\n");
408 const reader = fis.reader();
403409
404 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterArrayList(&list, '\n', 5));410 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterArrayList(&list, '\n', 5));
405 try std.testing.expectEqualStrings("12345", list.items);411 try std.testing.expectEqualStrings("12345", list.items);
...@@ -412,7 +418,8 @@ test "Reader.readUntilDelimiterArrayList returns EndOfStream" {...@@ -412,7 +418,8 @@ test "Reader.readUntilDelimiterArrayList returns EndOfStream" {
412 var list = std.ArrayList(u8).init(a);418 var list = std.ArrayList(u8).init(a);
413 defer list.deinit();419 defer list.deinit();
414420
415 const reader = std.io.fixedBufferStream("1234").reader();421 var fis = std.io.fixedBufferStream("1234");
422 const reader = fis.reader();
416423
417 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));424 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));
418 try std.testing.expectEqualStrings("1234", list.items);425 try std.testing.expectEqualStrings("1234", list.items);
...@@ -421,7 +428,8 @@ test "Reader.readUntilDelimiterArrayList returns EndOfStream" {...@@ -421,7 +428,8 @@ test "Reader.readUntilDelimiterArrayList returns EndOfStream" {
421test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {428test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
422 const a = std.testing.allocator;429 const a = std.testing.allocator;
423430
424 const reader = std.io.fixedBufferStream("0000\n1234\n").reader();431 var fis = std.io.fixedBufferStream("0000\n1234\n");
432 const reader = fis.reader();
425433
426 {434 {
427 var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);435 var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
...@@ -441,7 +449,8 @@ test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until th...@@ -441,7 +449,8 @@ test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until th
441test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {449test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {
442 const a = std.testing.allocator;450 const a = std.testing.allocator;
443451
444 const reader = std.io.fixedBufferStream("\n").reader();452 var fis = std.io.fixedBufferStream("\n");
453 const reader = fis.reader();
445454
446 {455 {
447 var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);456 var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
...@@ -453,7 +462,8 @@ test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {...@@ -453,7 +462,8 @@ test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {
453test "Reader.readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {462test "Reader.readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
454 const a = std.testing.allocator;463 const a = std.testing.allocator;
455464
456 const reader = std.io.fixedBufferStream("1234567\n").reader();465 var fis = std.io.fixedBufferStream("1234567\n");
466 const reader = fis.reader();
457467
458 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterAlloc(a, '\n', 5));468 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterAlloc(a, '\n', 5));
459469
...@@ -465,67 +475,77 @@ test "Reader.readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList wi...@@ -465,67 +475,77 @@ test "Reader.readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList wi
465test "Reader.readUntilDelimiterAlloc returns EndOfStream" {475test "Reader.readUntilDelimiterAlloc returns EndOfStream" {
466 const a = std.testing.allocator;476 const a = std.testing.allocator;
467477
468 const reader = std.io.fixedBufferStream("1234").reader();478 var fis = std.io.fixedBufferStream("1234");
479 const reader = fis.reader();
469480
470 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));481 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));
471}482}
472483
473test "Reader.readUntilDelimiter returns bytes read until the delimiter" {484test "Reader.readUntilDelimiter returns bytes read until the delimiter" {
474 var buf: [5]u8 = undefined;485 var buf: [5]u8 = undefined;
475 const reader = std.io.fixedBufferStream("0000\n1234\n").reader();486 var fis = std.io.fixedBufferStream("0000\n1234\n");
487 const reader = fis.reader();
476 try std.testing.expectEqualStrings("0000", try reader.readUntilDelimiter(&buf, '\n'));488 try std.testing.expectEqualStrings("0000", try reader.readUntilDelimiter(&buf, '\n'));
477 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));489 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
478}490}
479491
480test "Reader.readUntilDelimiter returns an empty string" {492test "Reader.readUntilDelimiter returns an empty string" {
481 var buf: [5]u8 = undefined;493 var buf: [5]u8 = undefined;
482 const reader = std.io.fixedBufferStream("\n").reader();494 var fis = std.io.fixedBufferStream("\n");
495 const reader = fis.reader();
483 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));496 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
484}497}
485498
486test "Reader.readUntilDelimiter returns StreamTooLong, then an empty string" {499test "Reader.readUntilDelimiter returns StreamTooLong, then an empty string" {
487 var buf: [5]u8 = undefined;500 var buf: [5]u8 = undefined;
488 const reader = std.io.fixedBufferStream("12345\n").reader();501 var fis = std.io.fixedBufferStream("12345\n");
502 const reader = fis.reader();
489 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));503 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
490 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));504 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
491}505}
492506
493test "Reader.readUntilDelimiter returns StreamTooLong, then bytes read until the delimiter" {507test "Reader.readUntilDelimiter returns StreamTooLong, then bytes read until the delimiter" {
494 var buf: [5]u8 = undefined;508 var buf: [5]u8 = undefined;
495 const reader = std.io.fixedBufferStream("1234567\n").reader();509 var fis = std.io.fixedBufferStream("1234567\n");
510 const reader = fis.reader();
496 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));511 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
497 try std.testing.expectEqualStrings("67", try reader.readUntilDelimiter(&buf, '\n'));512 try std.testing.expectEqualStrings("67", try reader.readUntilDelimiter(&buf, '\n'));
498}513}
499514
500test "Reader.readUntilDelimiter returns EndOfStream" {515test "Reader.readUntilDelimiter returns EndOfStream" {
501 var buf: [5]u8 = undefined;516 var buf: [5]u8 = undefined;
502 const reader = std.io.fixedBufferStream("").reader();517 var fis = std.io.fixedBufferStream("");
518 const reader = fis.reader();
503 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));519 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
504}520}
505521
506test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {522test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {
507 var buf: [5]u8 = undefined;523 var buf: [5]u8 = undefined;
508 const reader = std.io.fixedBufferStream("1234\n").reader();524 var fis = std.io.fixedBufferStream("1234\n");
525 const reader = fis.reader();
509 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));526 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
510 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));527 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
511}528}
512529
513test "Reader.readUntilDelimiter returns EndOfStream" {530test "Reader.readUntilDelimiter returns EndOfStream" {
514 var buf: [5]u8 = undefined;531 var buf: [5]u8 = undefined;
515 const reader = std.io.fixedBufferStream("1234").reader();532 var fis = std.io.fixedBufferStream("1234");
533 const reader = fis.reader();
516 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));534 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
517}535}
518536
519test "Reader.readUntilDelimiter returns StreamTooLong, then EndOfStream" {537test "Reader.readUntilDelimiter returns StreamTooLong, then EndOfStream" {
520 var buf: [5]u8 = undefined;538 var buf: [5]u8 = undefined;
521 const reader = std.io.fixedBufferStream("12345").reader();539 var fis = std.io.fixedBufferStream("12345");
540 const reader = fis.reader();
522 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));541 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
523 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));542 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
524}543}
525544
526test "Reader.readUntilDelimiter writes all bytes read to the output buffer" {545test "Reader.readUntilDelimiter writes all bytes read to the output buffer" {
527 var buf: [5]u8 = undefined;546 var buf: [5]u8 = undefined;
528 const reader = std.io.fixedBufferStream("0000\n12345").reader();547 var fis = std.io.fixedBufferStream("0000\n12345");
548 const reader = fis.reader();
529 _ = try reader.readUntilDelimiter(&buf, '\n');549 _ = try reader.readUntilDelimiter(&buf, '\n');
530 try std.testing.expectEqualStrings("0000\n", &buf);550 try std.testing.expectEqualStrings("0000\n", &buf);
531 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));551 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
...@@ -535,7 +555,8 @@ test "Reader.readUntilDelimiter writes all bytes read to the output buffer" {...@@ -535,7 +555,8 @@ test "Reader.readUntilDelimiter writes all bytes read to the output buffer" {
535test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {555test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
536 const a = std.testing.allocator;556 const a = std.testing.allocator;
537557
538 const reader = std.io.fixedBufferStream("0000\n1234\n").reader();558 var fis = std.io.fixedBufferStream("0000\n1234\n");
559 const reader = fis.reader();
539560
540 {561 {
541 var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;562 var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
...@@ -555,7 +576,8 @@ test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read unt...@@ -555,7 +576,8 @@ test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read unt
555test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {576test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {
556 const a = std.testing.allocator;577 const a = std.testing.allocator;
557578
558 const reader = std.io.fixedBufferStream("\n").reader();579 var fis = std.io.fixedBufferStream("\n");
580 const reader = fis.reader();
559581
560 {582 {
561 var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;583 var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
...@@ -567,7 +589,8 @@ test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {...@@ -567,7 +589,8 @@ test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {
567test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {589test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
568 const a = std.testing.allocator;590 const a = std.testing.allocator;
569591
570 const reader = std.io.fixedBufferStream("1234567\n").reader();592 var fis = std.io.fixedBufferStream("1234567\n");
593 const reader = fis.reader();
571594
572 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEofAlloc(a, '\n', 5));595 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEofAlloc(a, '\n', 5));
573596
...@@ -578,60 +601,69 @@ test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayLi...@@ -578,60 +601,69 @@ test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayLi
578601
579test "Reader.readUntilDelimiterOrEof returns bytes read until the delimiter" {602test "Reader.readUntilDelimiterOrEof returns bytes read until the delimiter" {
580 var buf: [5]u8 = undefined;603 var buf: [5]u8 = undefined;
581 const reader = std.io.fixedBufferStream("0000\n1234\n").reader();604 var fis = std.io.fixedBufferStream("0000\n1234\n");
605 const reader = fis.reader();
582 try std.testing.expectEqualStrings("0000", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);606 try std.testing.expectEqualStrings("0000", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
583 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);607 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
584}608}
585609
586test "Reader.readUntilDelimiterOrEof returns an empty string" {610test "Reader.readUntilDelimiterOrEof returns an empty string" {
587 var buf: [5]u8 = undefined;611 var buf: [5]u8 = undefined;
588 const reader = std.io.fixedBufferStream("\n").reader();612 var fis = std.io.fixedBufferStream("\n");
613 const reader = fis.reader();
589 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);614 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
590}615}
591616
592test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then an empty string" {617test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then an empty string" {
593 var buf: [5]u8 = undefined;618 var buf: [5]u8 = undefined;
594 const reader = std.io.fixedBufferStream("12345\n").reader();619 var fis = std.io.fixedBufferStream("12345\n");
620 const reader = fis.reader();
595 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));621 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
596 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);622 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
597}623}
598624
599test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until the delimiter" {625test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until the delimiter" {
600 var buf: [5]u8 = undefined;626 var buf: [5]u8 = undefined;
601 const reader = std.io.fixedBufferStream("1234567\n").reader();627 var fis = std.io.fixedBufferStream("1234567\n");
628 const reader = fis.reader();
602 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));629 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
603 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);630 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
604}631}
605632
606test "Reader.readUntilDelimiterOrEof returns null" {633test "Reader.readUntilDelimiterOrEof returns null" {
607 var buf: [5]u8 = undefined;634 var buf: [5]u8 = undefined;
608 const reader = std.io.fixedBufferStream("").reader();635 var fis = std.io.fixedBufferStream("");
636 const reader = fis.reader();
609 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);637 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
610}638}
611639
612test "Reader.readUntilDelimiterOrEof returns bytes read until delimiter, then null" {640test "Reader.readUntilDelimiterOrEof returns bytes read until delimiter, then null" {
613 var buf: [5]u8 = undefined;641 var buf: [5]u8 = undefined;
614 const reader = std.io.fixedBufferStream("1234\n").reader();642 var fis = std.io.fixedBufferStream("1234\n");
643 const reader = fis.reader();
615 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);644 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
616 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);645 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
617}646}
618647
619test "Reader.readUntilDelimiterOrEof returns bytes read until end-of-stream" {648test "Reader.readUntilDelimiterOrEof returns bytes read until end-of-stream" {
620 var buf: [5]u8 = undefined;649 var buf: [5]u8 = undefined;
621 const reader = std.io.fixedBufferStream("1234").reader();650 var fis = std.io.fixedBufferStream("1234");
651 const reader = fis.reader();
622 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);652 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
623}653}
624654
625test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until end-of-stream" {655test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until end-of-stream" {
626 var buf: [5]u8 = undefined;656 var buf: [5]u8 = undefined;
627 const reader = std.io.fixedBufferStream("1234567").reader();657 var fis = std.io.fixedBufferStream("1234567");
658 const reader = fis.reader();
628 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));659 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
629 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);660 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
630}661}
631662
632test "Reader.readUntilDelimiterOrEof writes all bytes read to the output buffer" {663test "Reader.readUntilDelimiterOrEof writes all bytes read to the output buffer" {
633 var buf: [5]u8 = undefined;664 var buf: [5]u8 = undefined;
634 const reader = std.io.fixedBufferStream("0000\n12345").reader();665 var fis = std.io.fixedBufferStream("0000\n12345");
666 const reader = fis.reader();
635 _ = try reader.readUntilDelimiterOrEof(&buf, '\n');667 _ = try reader.readUntilDelimiterOrEof(&buf, '\n');
636 try std.testing.expectEqualStrings("0000\n", &buf);668 try std.testing.expectEqualStrings("0000\n", &buf);
637 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));669 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
lib/std/json.zig+136-85
...@@ -1506,42 +1506,46 @@ fn skipValue(tokens: *TokenStream) SkipValueError!void {...@@ -1506,42 +1506,46 @@ fn skipValue(tokens: *TokenStream) SkipValueError!void {
1506}1506}
15071507
1508test "skipValue" {1508test "skipValue" {
1509 try skipValue(&TokenStream.init("false"));1509 var ts = TokenStream.init("false");
1510 try skipValue(&TokenStream.init("true"));1510 try skipValue(&ts);
1511 try skipValue(&TokenStream.init("null"));1511 ts = TokenStream.init("true");
1512 try skipValue(&TokenStream.init("42"));1512 try skipValue(&ts);
1513 try skipValue(&TokenStream.init("42.0"));1513 ts = TokenStream.init("null");
1514 try skipValue(&TokenStream.init("\"foo\""));1514 try skipValue(&ts);
1515 try skipValue(&TokenStream.init("[101, 111, 121]"));1515 ts = TokenStream.init("42");
1516 try skipValue(&TokenStream.init("{}"));1516 try skipValue(&ts);
1517 try skipValue(&TokenStream.init("{\"foo\": \"bar\"}"));1517 ts = TokenStream.init("42.0");
1518 try skipValue(&ts);
1519 ts = TokenStream.init("\"foo\"");
1520 try skipValue(&ts);
1521 ts = TokenStream.init("[101, 111, 121]");
1522 try skipValue(&ts);
1523 ts = TokenStream.init("{}");
1524 try skipValue(&ts);
1525 ts = TokenStream.init("{\"foo\": \"bar\"}");
1526 try skipValue(&ts);
15181527
1519 { // An absurd number of nestings1528 { // An absurd number of nestings
1520 const nestings = StreamingParser.default_max_nestings + 1;1529 const nestings = StreamingParser.default_max_nestings + 1;
15211530
1522 try testing.expectError(1531 ts = TokenStream.init("[" ** nestings ++ "]" ** nestings);
1523 error.TooManyNestedItems,1532 try testing.expectError(error.TooManyNestedItems, skipValue(&ts));
1524 skipValue(&TokenStream.init("[" ** nestings ++ "]" ** nestings)),
1525 );
1526 }1533 }
15271534
1528 { // Would a number token cause problems in a deeply-nested array?1535 { // Would a number token cause problems in a deeply-nested array?
1529 const nestings = StreamingParser.default_max_nestings;1536 const nestings = StreamingParser.default_max_nestings;
1530 const deeply_nested_array = "[" ** nestings ++ "0.118, 999, 881.99, 911.9, 725, 3" ++ "]" ** nestings;1537 const deeply_nested_array = "[" ** nestings ++ "0.118, 999, 881.99, 911.9, 725, 3" ++ "]" ** nestings;
15311538
1532 try skipValue(&TokenStream.init(deeply_nested_array));1539 ts = TokenStream.init(deeply_nested_array);
1540 try skipValue(&ts);
15331541
1534 try testing.expectError(1542 ts = TokenStream.init("[" ++ deeply_nested_array ++ "]");
1535 error.TooManyNestedItems,1543 try testing.expectError(error.TooManyNestedItems, skipValue(&ts));
1536 skipValue(&TokenStream.init("[" ++ deeply_nested_array ++ "]")),
1537 );
1538 }1544 }
15391545
1540 // Mismatched brace/square bracket1546 // Mismatched brace/square bracket
1541 try testing.expectError(1547 ts = TokenStream.init("[102, 111, 111}");
1542 error.UnexpectedClosingBrace,1548 try testing.expectError(error.UnexpectedClosingBrace, skipValue(&ts));
1543 skipValue(&TokenStream.init("[102, 111, 111}")),
1544 );
15451549
1546 { // should fail if no value found (e.g. immediate close of object)1550 { // should fail if no value found (e.g. immediate close of object)
1547 var empty_object = TokenStream.init("{}");1551 var empty_object = TokenStream.init("{}");
...@@ -1980,18 +1984,29 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {...@@ -1980,18 +1984,29 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
1980}1984}
19811985
1982test "parse" {1986test "parse" {
1983 try testing.expectEqual(false, try parse(bool, &TokenStream.init("false"), ParseOptions{}));1987 var ts = TokenStream.init("false");
1984 try testing.expectEqual(true, try parse(bool, &TokenStream.init("true"), ParseOptions{}));1988 try testing.expectEqual(false, try parse(bool, &ts, ParseOptions{}));
1985 try testing.expectEqual(@as(u1, 1), try parse(u1, &TokenStream.init("1"), ParseOptions{}));1989 ts = TokenStream.init("true");
1986 try testing.expectError(error.Overflow, parse(u1, &TokenStream.init("50"), ParseOptions{}));1990 try testing.expectEqual(true, try parse(bool, &ts, ParseOptions{}));
1987 try testing.expectEqual(@as(u64, 42), try parse(u64, &TokenStream.init("42"), ParseOptions{}));1991 ts = TokenStream.init("1");
1988 try testing.expectEqual(@as(f64, 42), try parse(f64, &TokenStream.init("42.0"), ParseOptions{}));1992 try testing.expectEqual(@as(u1, 1), try parse(u1, &ts, ParseOptions{}));
1989 try testing.expectEqual(@as(?bool, null), try parse(?bool, &TokenStream.init("null"), ParseOptions{}));1993 ts = TokenStream.init("50");
1990 try testing.expectEqual(@as(?bool, true), try parse(?bool, &TokenStream.init("true"), ParseOptions{}));1994 try testing.expectError(error.Overflow, parse(u1, &ts, ParseOptions{}));
19911995 ts = TokenStream.init("42");
1992 try testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("\"foo\""), ParseOptions{}));1996 try testing.expectEqual(@as(u64, 42), try parse(u64, &ts, ParseOptions{}));
1993 try testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("[102, 111, 111]"), ParseOptions{}));1997 ts = TokenStream.init("42.0");
1994 try testing.expectEqual(@as([0]u8, undefined), try parse([0]u8, &TokenStream.init("[]"), ParseOptions{}));1998 try testing.expectEqual(@as(f64, 42), try parse(f64, &ts, ParseOptions{}));
1999 ts = TokenStream.init("null");
2000 try testing.expectEqual(@as(?bool, null), try parse(?bool, &ts, ParseOptions{}));
2001 ts = TokenStream.init("true");
2002 try testing.expectEqual(@as(?bool, true), try parse(?bool, &ts, ParseOptions{}));
2003
2004 ts = TokenStream.init("\"foo\"");
2005 try testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &ts, ParseOptions{}));
2006 ts = TokenStream.init("[102, 111, 111]");
2007 try testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &ts, ParseOptions{}));
2008 ts = TokenStream.init("[]");
2009 try testing.expectEqual(@as([0]u8, undefined), try parse([0]u8, &ts, ParseOptions{}));
1995}2010}
19962011
1997test "parse into enum" {2012test "parse into enum" {
...@@ -2000,36 +2015,48 @@ test "parse into enum" {...@@ -2000,36 +2015,48 @@ test "parse into enum" {
2000 Bar,2015 Bar,
2001 @"with\\escape",2016 @"with\\escape",
2002 };2017 };
2003 try testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("\"Foo\""), ParseOptions{}));2018 var ts = TokenStream.init("\"Foo\"");
2004 try testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("42"), ParseOptions{}));2019 try testing.expectEqual(@as(T, .Foo), try parse(T, &ts, ParseOptions{}));
2005 try testing.expectEqual(@as(T, .@"with\\escape"), try parse(T, &TokenStream.init("\"with\\\\escape\""), ParseOptions{}));2020 ts = TokenStream.init("42");
2006 try testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("5"), ParseOptions{}));2021 try testing.expectEqual(@as(T, .Foo), try parse(T, &ts, ParseOptions{}));
2007 try testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("\"Qux\""), ParseOptions{}));2022 ts = TokenStream.init("\"with\\\\escape\"");
2023 try testing.expectEqual(@as(T, .@"with\\escape"), try parse(T, &ts, ParseOptions{}));
2024 ts = TokenStream.init("5");
2025 try testing.expectError(error.InvalidEnumTag, parse(T, &ts, ParseOptions{}));
2026 ts = TokenStream.init("\"Qux\"");
2027 try testing.expectError(error.InvalidEnumTag, parse(T, &ts, ParseOptions{}));
2008}2028}
20092029
2010test "parse with trailing data" {2030test "parse with trailing data" {
2011 try testing.expectEqual(false, try parse(bool, &TokenStream.init("falsed"), ParseOptions{ .allow_trailing_data = true }));2031 var ts = TokenStream.init("falsed");
2012 try testing.expectError(error.InvalidTopLevelTrailing, parse(bool, &TokenStream.init("falsed"), ParseOptions{ .allow_trailing_data = false }));2032 try testing.expectEqual(false, try parse(bool, &ts, ParseOptions{ .allow_trailing_data = true }));
2033 ts = TokenStream.init("falsed");
2034 try testing.expectError(error.InvalidTopLevelTrailing, parse(bool, &ts, ParseOptions{ .allow_trailing_data = false }));
2013 // trailing whitespace is okay2035 // trailing whitespace is okay
2014 try testing.expectEqual(false, try parse(bool, &TokenStream.init("false \n"), ParseOptions{ .allow_trailing_data = false }));2036 ts = TokenStream.init("false \n");
2037 try testing.expectEqual(false, try parse(bool, &ts, ParseOptions{ .allow_trailing_data = false }));
2015}2038}
20162039
2017test "parse into that allocates a slice" {2040test "parse into that allocates a slice" {
2018 try testing.expectError(error.AllocatorRequired, parse([]u8, &TokenStream.init("\"foo\""), ParseOptions{}));2041 var ts = TokenStream.init("\"foo\"");
2042 try testing.expectError(error.AllocatorRequired, parse([]u8, &ts, ParseOptions{}));
20192043
2020 const options = ParseOptions{ .allocator = testing.allocator };2044 const options = ParseOptions{ .allocator = testing.allocator };
2021 {2045 {
2022 const r = try parse([]u8, &TokenStream.init("\"foo\""), options);2046 ts = TokenStream.init("\"foo\"");
2047 const r = try parse([]u8, &ts, options);
2023 defer parseFree([]u8, r, options);2048 defer parseFree([]u8, r, options);
2024 try testing.expectEqualSlices(u8, "foo", r);2049 try testing.expectEqualSlices(u8, "foo", r);
2025 }2050 }
2026 {2051 {
2027 const r = try parse([]u8, &TokenStream.init("[102, 111, 111]"), options);2052 ts = TokenStream.init("[102, 111, 111]");
2053 const r = try parse([]u8, &ts, options);
2028 defer parseFree([]u8, r, options);2054 defer parseFree([]u8, r, options);
2029 try testing.expectEqualSlices(u8, "foo", r);2055 try testing.expectEqualSlices(u8, "foo", r);
2030 }2056 }
2031 {2057 {
2032 const r = try parse([]u8, &TokenStream.init("\"with\\\\escape\""), options);2058 ts = TokenStream.init("\"with\\\\escape\"");
2059 const r = try parse([]u8, &ts, options);
2033 defer parseFree([]u8, r, options);2060 defer parseFree([]u8, r, options);
2034 try testing.expectEqualSlices(u8, "with\\escape", r);2061 try testing.expectEqualSlices(u8, "with\\escape", r);
2035 }2062 }
...@@ -2042,7 +2069,8 @@ test "parse into tagged union" {...@@ -2042,7 +2069,8 @@ test "parse into tagged union" {
2042 float: f64,2069 float: f64,
2043 string: []const u8,2070 string: []const u8,
2044 };2071 };
2045 try testing.expectEqual(T{ .float = 1.5 }, try parse(T, &TokenStream.init("1.5"), ParseOptions{}));2072 var ts = TokenStream.init("1.5");
2073 try testing.expectEqual(T{ .float = 1.5 }, try parse(T, &ts, ParseOptions{}));
2046 }2074 }
20472075
2048 { // failing allocations should be bubbled up instantly without trying next member2076 { // failing allocations should be bubbled up instantly without trying next member
...@@ -2053,7 +2081,8 @@ test "parse into tagged union" {...@@ -2053,7 +2081,8 @@ test "parse into tagged union" {
2053 string: []const u8,2081 string: []const u8,
2054 array: [3]u8,2082 array: [3]u8,
2055 };2083 };
2056 try testing.expectError(error.OutOfMemory, parse(T, &TokenStream.init("[1,2,3]"), options));2084 var ts = TokenStream.init("[1,2,3]");
2085 try testing.expectError(error.OutOfMemory, parse(T, &ts, options));
2057 }2086 }
20582087
2059 {2088 {
...@@ -2062,7 +2091,8 @@ test "parse into tagged union" {...@@ -2062,7 +2091,8 @@ test "parse into tagged union" {
2062 x: u8,2091 x: u8,
2063 y: u8,2092 y: u8,
2064 };2093 };
2065 try testing.expectEqual(T{ .x = 42 }, try parse(T, &TokenStream.init("42"), ParseOptions{}));2094 var ts = TokenStream.init("42");
2095 try testing.expectEqual(T{ .x = 42 }, try parse(T, &ts, ParseOptions{}));
2066 }2096 }
20672097
2068 { // needs to back out when first union member doesn't match2098 { // needs to back out when first union member doesn't match
...@@ -2070,7 +2100,8 @@ test "parse into tagged union" {...@@ -2070,7 +2100,8 @@ test "parse into tagged union" {
2070 A: struct { x: u32 },2100 A: struct { x: u32 },
2071 B: struct { y: u32 },2101 B: struct { y: u32 },
2072 };2102 };
2073 try testing.expectEqual(T{ .B = .{ .y = 42 } }, try parse(T, &TokenStream.init("{\"y\":42}"), ParseOptions{}));2103 var ts = TokenStream.init("{\"y\":42}");
2104 try testing.expectEqual(T{ .B = .{ .y = 42 } }, try parse(T, &ts, ParseOptions{}));
2074 }2105 }
2075}2106}
20762107
...@@ -2080,7 +2111,8 @@ test "parse union bubbles up AllocatorRequired" {...@@ -2080,7 +2111,8 @@ test "parse union bubbles up AllocatorRequired" {
2080 string: []const u8,2111 string: []const u8,
2081 int: i32,2112 int: i32,
2082 };2113 };
2083 try testing.expectError(error.AllocatorRequired, parse(T, &TokenStream.init("42"), ParseOptions{}));2114 var ts = TokenStream.init("42");
2115 try testing.expectError(error.AllocatorRequired, parse(T, &ts, ParseOptions{}));
2084 }2116 }
20852117
2086 { // string member not first in union (and matching)2118 { // string member not first in union (and matching)
...@@ -2089,7 +2121,8 @@ test "parse union bubbles up AllocatorRequired" {...@@ -2089,7 +2121,8 @@ test "parse union bubbles up AllocatorRequired" {
2089 float: f64,2121 float: f64,
2090 string: []const u8,2122 string: []const u8,
2091 };2123 };
2092 try testing.expectError(error.AllocatorRequired, parse(T, &TokenStream.init("\"foo\""), ParseOptions{}));2124 var ts = TokenStream.init("\"foo\"");
2125 try testing.expectError(error.AllocatorRequired, parse(T, &ts, ParseOptions{}));
2093 }2126 }
2094}2127}
20952128
...@@ -2102,7 +2135,8 @@ test "parseFree descends into tagged union" {...@@ -2102,7 +2135,8 @@ test "parseFree descends into tagged union" {
2102 string: []const u8,2135 string: []const u8,
2103 };2136 };
2104 // use a string with unicode escape so we know result can't be a reference to global constant2137 // use a string with unicode escape so we know result can't be a reference to global constant
2105 const r = try parse(T, &TokenStream.init("\"with\\u0105unicode\""), options);2138 var ts = TokenStream.init("\"with\\u0105unicode\"");
2139 const r = try parse(T, &ts, options);
2106 try testing.expectEqual(std.meta.Tag(T).string, @as(std.meta.Tag(T), r));2140 try testing.expectEqual(std.meta.Tag(T).string, @as(std.meta.Tag(T), r));
2107 try testing.expectEqualSlices(u8, "withąunicode", r.string);2141 try testing.expectEqualSlices(u8, "withąunicode", r.string);
2108 try testing.expectEqual(@as(usize, 0), fail_alloc.deallocations);2142 try testing.expectEqual(@as(usize, 0), fail_alloc.deallocations);
...@@ -2116,12 +2150,13 @@ test "parse with comptime field" {...@@ -2116,12 +2150,13 @@ test "parse with comptime field" {
2116 comptime a: i32 = 0,2150 comptime a: i32 = 0,
2117 b: bool,2151 b: bool,
2118 };2152 };
2119 try testing.expectEqual(T{ .a = 0, .b = true }, try parse(T, &TokenStream.init(2153 var ts = TokenStream.init(
2120 \\{2154 \\{
2121 \\ "a": 0,2155 \\ "a": 0,
2122 \\ "b": true2156 \\ "b": true
2123 \\}2157 \\}
2124 ), ParseOptions{}));2158 );
2159 try testing.expectEqual(T{ .a = 0, .b = true }, try parse(T, &ts, ParseOptions{}));
2125 }2160 }
21262161
2127 { // string comptime values currently require an allocator2162 { // string comptime values currently require an allocator
...@@ -2140,12 +2175,13 @@ test "parse with comptime field" {...@@ -2140,12 +2175,13 @@ test "parse with comptime field" {
2140 .allocator = std.testing.allocator,2175 .allocator = std.testing.allocator,
2141 };2176 };
21422177
2143 const r = try parse(T, &TokenStream.init(2178 var ts = TokenStream.init(
2144 \\{2179 \\{
2145 \\ "kind": "float",2180 \\ "kind": "float",
2146 \\ "b": 1.02181 \\ "b": 1.0
2147 \\}2182 \\}
2148 ), options);2183 );
2184 const r = try parse(T, &ts, options);
21492185
2150 // check that parseFree doesn't try to free comptime fields2186 // check that parseFree doesn't try to free comptime fields
2151 parseFree(T, r, options);2187 parseFree(T, r, options);
...@@ -2154,7 +2190,8 @@ test "parse with comptime field" {...@@ -2154,7 +2190,8 @@ test "parse with comptime field" {
21542190
2155test "parse into struct with no fields" {2191test "parse into struct with no fields" {
2156 const T = struct {};2192 const T = struct {};
2157 try testing.expectEqual(T{}, try parse(T, &TokenStream.init("{}"), ParseOptions{}));2193 var ts = TokenStream.init("{}");
2194 try testing.expectEqual(T{}, try parse(T, &ts, ParseOptions{}));
2158}2195}
21592196
2160test "parse into struct with misc fields" {2197test "parse into struct with misc fields" {
...@@ -2186,7 +2223,7 @@ test "parse into struct with misc fields" {...@@ -2186,7 +2223,7 @@ test "parse into struct with misc fields" {
2186 string: []const u8,2223 string: []const u8,
2187 };2224 };
2188 };2225 };
2189 const r = try parse(T, &TokenStream.init(2226 var ts = TokenStream.init(
2190 \\{2227 \\{
2191 \\ "int": 420,2228 \\ "int": 420,
2192 \\ "float": 3.14,2229 \\ "float": 3.14,
...@@ -2208,7 +2245,8 @@ test "parse into struct with misc fields" {...@@ -2208,7 +2245,8 @@ test "parse into struct with misc fields" {
2208 \\ ],2245 \\ ],
2209 \\ "a_union": 1000002246 \\ "a_union": 100000
2210 \\}2247 \\}
2211 ), options);2248 );
2249 const r = try parse(T, &ts, options);
2212 defer parseFree(T, r, options);2250 defer parseFree(T, r, options);
2213 try testing.expectEqual(@as(i64, 420), r.int);2251 try testing.expectEqual(@as(i64, 420), r.int);
2214 try testing.expectEqual(@as(f64, 3.14), r.float);2252 try testing.expectEqual(@as(f64, 3.14), r.float);
...@@ -2239,14 +2277,15 @@ test "parse into struct with strings and arrays with sentinels" {...@@ -2239,14 +2277,15 @@ test "parse into struct with strings and arrays with sentinels" {
2239 data: [:99]const i32,2277 data: [:99]const i32,
2240 simple_data: []const i32,2278 simple_data: []const i32,
2241 };2279 };
2242 const r = try parse(T, &TokenStream.init(2280 var ts = TokenStream.init(
2243 \\{2281 \\{
2244 \\ "language": "zig",2282 \\ "language": "zig",
2245 \\ "language_without_sentinel": "zig again!",2283 \\ "language_without_sentinel": "zig again!",
2246 \\ "data": [1, 2, 3],2284 \\ "data": [1, 2, 3],
2247 \\ "simple_data": [4, 5, 6]2285 \\ "simple_data": [4, 5, 6]
2248 \\}2286 \\}
2249 ), options);2287 );
2288 const r = try parse(T, &ts, options);
2250 defer parseFree(T, r, options);2289 defer parseFree(T, r, options);
22512290
2252 try testing.expectEqualSentinel(u8, 0, "zig", r.language);2291 try testing.expectEqualSentinel(u8, 0, "zig", r.language);
...@@ -2275,19 +2314,25 @@ test "parse into struct with duplicate field" {...@@ -2275,19 +2314,25 @@ test "parse into struct with duplicate field" {
22752314
2276 const T1 = struct { a: *u64 };2315 const T1 = struct { a: *u64 };
2277 // both .UseFirst and .UseLast should fail because second "a" value isn't a u642316 // both .UseFirst and .UseLast should fail because second "a" value isn't a u64
2278 try testing.expectError(error.InvalidNumber, parse(T1, &TokenStream.init(str), options_first));2317 var ts = TokenStream.init(str);
2279 try testing.expectError(error.InvalidNumber, parse(T1, &TokenStream.init(str), options_last));2318 try testing.expectError(error.InvalidNumber, parse(T1, &ts, options_first));
2319 ts = TokenStream.init(str);
2320 try testing.expectError(error.InvalidNumber, parse(T1, &ts, options_last));
22802321
2281 const T2 = struct { a: f64 };2322 const T2 = struct { a: f64 };
2282 try testing.expectEqual(T2{ .a = 1.0 }, try parse(T2, &TokenStream.init(str), options_first));2323 ts = TokenStream.init(str);
2283 try testing.expectEqual(T2{ .a = 0.25 }, try parse(T2, &TokenStream.init(str), options_last));2324 try testing.expectEqual(T2{ .a = 1.0 }, try parse(T2, &ts, options_first));
2325 ts = TokenStream.init(str);
2326 try testing.expectEqual(T2{ .a = 0.25 }, try parse(T2, &ts, options_last));
22842327
2285 const T3 = struct { comptime a: f64 = 1.0 };2328 const T3 = struct { comptime a: f64 = 1.0 };
2286 // .UseFirst should succeed because second "a" value is unconditionally ignored (even though != 1.0)2329 // .UseFirst should succeed because second "a" value is unconditionally ignored (even though != 1.0)
2287 const t3 = T3{ .a = 1.0 };2330 const t3 = T3{ .a = 1.0 };
2288 try testing.expectEqual(t3, try parse(T3, &TokenStream.init(str), options_first));2331 ts = TokenStream.init(str);
2332 try testing.expectEqual(t3, try parse(T3, &ts, options_first));
2289 // .UseLast should fail because second "a" value is 0.25 which is not equal to default value of 1.02333 // .UseLast should fail because second "a" value is 0.25 which is not equal to default value of 1.0
2290 try testing.expectError(error.UnexpectedValue, parse(T3, &TokenStream.init(str), options_last));2334 ts = TokenStream.init(str);
2335 try testing.expectError(error.UnexpectedValue, parse(T3, &ts, options_last));
2291}2336}
22922337
2293test "parse into struct ignoring unknown fields" {2338test "parse into struct ignoring unknown fields" {
...@@ -2301,7 +2346,7 @@ test "parse into struct ignoring unknown fields" {...@@ -2301,7 +2346,7 @@ test "parse into struct ignoring unknown fields" {
2301 .ignore_unknown_fields = true,2346 .ignore_unknown_fields = true,
2302 };2347 };
23032348
2304 const r = try parse(T, &std.json.TokenStream.init(2349 var ts = TokenStream.init(
2305 \\{2350 \\{
2306 \\ "int": 420,2351 \\ "int": 420,
2307 \\ "float": 3.14,2352 \\ "float": 3.14,
...@@ -2323,7 +2368,8 @@ test "parse into struct ignoring unknown fields" {...@@ -2323,7 +2368,8 @@ test "parse into struct ignoring unknown fields" {
2323 \\ "a_union": 100000,2368 \\ "a_union": 100000,
2324 \\ "language": "zig"2369 \\ "language": "zig"
2325 \\}2370 \\}
2326 ), ops);2371 );
2372 const r = try parse(T, &ts, ops);
2327 defer parseFree(T, r, ops);2373 defer parseFree(T, r, ops);
23282374
2329 try testing.expectEqual(@as(i64, 420), r.int);2375 try testing.expectEqual(@as(i64, 420), r.int);
...@@ -2341,7 +2387,8 @@ test "parse into recursive union definition" {...@@ -2341,7 +2387,8 @@ test "parse into recursive union definition" {
2341 };2387 };
2342 const ops = ParseOptions{ .allocator = testing.allocator };2388 const ops = ParseOptions{ .allocator = testing.allocator };
23432389
2344 const r = try parse(T, &std.json.TokenStream.init("{\"values\":[58]}"), ops);2390 var ts = TokenStream.init("{\"values\":[58]}");
2391 const r = try parse(T, &ts, ops);
2345 defer parseFree(T, r, ops);2392 defer parseFree(T, r, ops);
23462393
2347 try testing.expectEqual(@as(i64, 58), r.values.array[0].integer);2394 try testing.expectEqual(@as(i64, 58), r.values.array[0].integer);
...@@ -2363,7 +2410,8 @@ test "parse into double recursive union definition" {...@@ -2363,7 +2410,8 @@ test "parse into double recursive union definition" {
2363 };2410 };
2364 const ops = ParseOptions{ .allocator = testing.allocator };2411 const ops = ParseOptions{ .allocator = testing.allocator };
23652412
2366 const r = try parse(T, &std.json.TokenStream.init("{\"values\":[[58]]}"), ops);2413 var ts = TokenStream.init("{\"values\":[[58]]}");
2414 const r = try parse(T, &ts, ops);
2367 defer parseFree(T, r, ops);2415 defer parseFree(T, r, ops);
23682416
2369 try testing.expectEqual(@as(i64, 58), r.values.array[0].array[0].integer);2417 try testing.expectEqual(@as(i64, 58), r.values.array[0].array[0].integer);
...@@ -2806,10 +2854,13 @@ test "integer after float has proper type" {...@@ -2806,10 +2854,13 @@ test "integer after float has proper type" {
28062854
2807test "parse exponential into int" {2855test "parse exponential into int" {
2808 const T = struct { int: i64 };2856 const T = struct { int: i64 };
2809 const r = try parse(T, &TokenStream.init("{ \"int\": 4.2e2 }"), ParseOptions{});2857 var ts = TokenStream.init("{ \"int\": 4.2e2 }");
2858 const r = try parse(T, &ts, ParseOptions{});
2810 try testing.expectEqual(@as(i64, 420), r.int);2859 try testing.expectEqual(@as(i64, 420), r.int);
2811 try testing.expectError(error.InvalidNumber, parse(T, &TokenStream.init("{ \"int\": 0.042e2 }"), ParseOptions{}));2860 ts = TokenStream.init("{ \"int\": 0.042e2 }");
2812 try testing.expectError(error.Overflow, parse(T, &TokenStream.init("{ \"int\": 18446744073709551616.0 }"), ParseOptions{}));2861 try testing.expectError(error.InvalidNumber, parse(T, &ts, ParseOptions{}));
2862 ts = TokenStream.init("{ \"int\": 18446744073709551616.0 }");
2863 try testing.expectError(error.Overflow, parse(T, &ts, ParseOptions{}));
2813}2864}
28142865
2815test "escaped characters" {2866test "escaped characters" {
...@@ -2858,10 +2909,12 @@ test "string copy option" {...@@ -2858,10 +2909,12 @@ test "string copy option" {
2858 defer arena_allocator.deinit();2909 defer arena_allocator.deinit();
2859 const allocator = arena_allocator.allocator();2910 const allocator = arena_allocator.allocator();
28602911
2861 const tree_nocopy = try Parser.init(allocator, false).parse(input);2912 var parser = Parser.init(allocator, false);
2913 const tree_nocopy = try parser.parse(input);
2862 const obj_nocopy = tree_nocopy.root.Object;2914 const obj_nocopy = tree_nocopy.root.Object;
28632915
2864 const tree_copy = try Parser.init(allocator, true).parse(input);2916 parser = Parser.init(allocator, true);
2917 const tree_copy = try parser.parse(input);
2865 const obj_copy = tree_copy.root.Object;2918 const obj_copy = tree_copy.root.Object;
28662919
2867 for ([_][]const u8{ "noescape", "simple", "unicode", "surrogatepair" }) |field_name| {2920 for ([_][]const u8{ "noescape", "simple", "unicode", "surrogatepair" }) |field_name| {
...@@ -3376,14 +3429,12 @@ test "stringify null optional fields" {...@@ -3376,14 +3429,12 @@ test "stringify null optional fields" {
3376 StringifyOptions{ .emit_null_optional_fields = false },3429 StringifyOptions{ .emit_null_optional_fields = false },
3377 );3430 );
33783431
3379 try std.testing.expect(try parsesTo(3432 var ts = TokenStream.init(
3380 MyStruct,3433 \\{"required":"something","another_required":"something else"}
3381 MyStruct{},3434 );
3382 &TokenStream.init(3435 try std.testing.expect(try parsesTo(MyStruct, MyStruct{}, &ts, .{
3383 \\{"required":"something","another_required":"something else"}3436 .allocator = std.testing.allocator,
3384 ),3437 }));
3385 .{ .allocator = std.testing.allocator },
3386 ));
3387}3438}
33883439
3389// Same as `stringify` but accepts an Allocator and stores result in dynamically allocated memory instead of using a Writer.3440// Same as `stringify` but accepts an Allocator and stores result in dynamically allocated memory instead of using a Writer.
lib/std/meta.zig+4-1
...@@ -311,7 +311,10 @@ pub fn assumeSentinel(p: anytype, comptime sentinel_val: Elem(@TypeOf(p))) Senti...@@ -311,7 +311,10 @@ pub fn assumeSentinel(p: anytype, comptime sentinel_val: Elem(@TypeOf(p))) Senti
311 const ReturnType = Sentinel(T, sentinel_val);311 const ReturnType = Sentinel(T, sentinel_val);
312 switch (@typeInfo(T)) {312 switch (@typeInfo(T)) {
313 .Pointer => |info| switch (info.size) {313 .Pointer => |info| switch (info.size) {
314 .Slice => return @bitCast(ReturnType, p),314 .Slice => if (@import("builtin").zig_backend == .stage1)
315 return @bitCast(ReturnType, p)
316 else
317 return @ptrCast(ReturnType, p),
315 .Many, .One => return @ptrCast(ReturnType, p),318 .Many, .One => return @ptrCast(ReturnType, p),
316 .C => {},319 .C => {},
317 },320 },
lib/std/net.zig+7-5
...@@ -1141,18 +1141,20 @@ fn linuxLookupNameFromHosts(...@@ -1141,18 +1141,20 @@ fn linuxLookupNameFromHosts(
1141 };1141 };
1142 defer file.close();1142 defer file.close();
11431143
1144 const stream = std.io.bufferedReader(file.reader()).reader();1144 var buffered_reader = std.io.bufferedReader(file.reader());
1145 const reader = buffered_reader.reader();
1145 var line_buf: [512]u8 = undefined;1146 var line_buf: [512]u8 = undefined;
1146 while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {1147 while (reader.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {
1147 error.StreamTooLong => blk: {1148 error.StreamTooLong => blk: {
1148 // Skip to the delimiter in the stream, to fix parsing1149 // Skip to the delimiter in the reader, to fix parsing
1149 try stream.skipUntilDelimiterOrEof('\n');1150 try reader.skipUntilDelimiterOrEof('\n');
1150 // Use the truncated line. A truncated comment or hostname will be handled correctly.1151 // Use the truncated line. A truncated comment or hostname will be handled correctly.
1151 break :blk &line_buf;1152 break :blk &line_buf;
1152 },1153 },
1153 else => |e| return e,1154 else => |e| return e,
1154 }) |line| {1155 }) |line| {
1155 const no_comment_line = mem.split(u8, line, "#").next().?;1156 var split_it = mem.split(u8, line, "#");
1157 const no_comment_line = split_it.next().?;
11561158
1157 var line_it = mem.tokenize(u8, no_comment_line, " \t");1159 var line_it = mem.tokenize(u8, no_comment_line, " \t");
1158 const ip_text = line_it.next() orelse continue;1160 const ip_text = line_it.next() orelse continue;
lib/std/segmented_list.zig+4-1
...@@ -391,7 +391,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -391,7 +391,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
391}391}
392392
393test "SegmentedList basic usage" {393test "SegmentedList basic usage" {
394 try testSegmentedList(0);394 if (@import("builtin").zig_backend == .stage1) {
395 // https://github.com/ziglang/zig/issues/11787
396 try testSegmentedList(0);
397 }
395 try testSegmentedList(1);398 try testSegmentedList(1);
396 try testSegmentedList(2);399 try testSegmentedList(2);
397 try testSegmentedList(4);400 try testSegmentedList(4);
lib/std/unicode.zig+1
...@@ -804,6 +804,7 @@ pub fn fmtUtf16le(utf16le: []const u16) std.fmt.Formatter(formatUtf16le) {...@@ -804,6 +804,7 @@ pub fn fmtUtf16le(utf16le: []const u16) std.fmt.Formatter(formatUtf16le) {
804}804}
805805
806test "fmtUtf16le" {806test "fmtUtf16le" {
807 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
807 const expectFmt = std.testing.expectFmt;808 const expectFmt = std.testing.expectFmt;
808 try expectFmt("", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral(""))});809 try expectFmt("", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral(""))});
809 try expectFmt("foo", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral("foo"))});810 try expectFmt("foo", "{}", .{fmtUtf16le(utf8ToUtf16LeStringLiteral("foo"))});
lib/std/x.zig+1
...@@ -13,6 +13,7 @@ pub const net = struct {...@@ -13,6 +13,7 @@ pub const net = struct {
13};13};
1414
15test {15test {
16 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
16 inline for (.{ os, net }) |module| {17 inline for (.{ os, net }) |module| {
17 std.testing.refAllDecls(module);18 std.testing.refAllDecls(module);
18 }19 }
lib/std/zig/c_translation.zig+29-7
...@@ -8,10 +8,19 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -8,10 +8,19 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
8 // this function should behave like transCCast in translate-c, except it's for macros8 // this function should behave like transCCast in translate-c, except it's for macros
9 const SourceType = @TypeOf(target);9 const SourceType = @TypeOf(target);
10 switch (@typeInfo(DestType)) {10 switch (@typeInfo(DestType)) {
11 .Fn, .Pointer => return castToPtr(DestType, SourceType, target),11 .Fn => if (@import("builtin").zig_backend == .stage1)
12 return castToPtr(DestType, SourceType, target)
13 else
14 return castToPtr(*const DestType, SourceType, target),
15 .Pointer => return castToPtr(DestType, SourceType, target),
12 .Optional => |dest_opt| {16 .Optional => |dest_opt| {
13 if (@typeInfo(dest_opt.child) == .Pointer or @typeInfo(dest_opt.child) == .Fn) {17 if (@typeInfo(dest_opt.child) == .Pointer) {
14 return castToPtr(DestType, SourceType, target);18 return castToPtr(DestType, SourceType, target);
19 } else if (@typeInfo(dest_opt.child) == .Fn) {
20 if (@import("builtin").zig_backend == .stage1)
21 return castToPtr(DestType, SourceType, target)
22 else
23 return castToPtr(?*const dest_opt.child, SourceType, target);
15 }24 }
16 },25 },
17 .Int => {26 .Int => {
...@@ -124,7 +133,10 @@ test "cast" {...@@ -124,7 +133,10 @@ test "cast" {
124 try testing.expect(cast(?*anyopaque, -1) == @intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))));133 try testing.expect(cast(?*anyopaque, -1) == @intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))));
125 try testing.expect(cast(?*anyopaque, foo) == @intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))));134 try testing.expect(cast(?*anyopaque, foo) == @intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))));
126135
127 const FnPtr = ?fn (*anyopaque) void;136 const FnPtr = if (@import("builtin").zig_backend == .stage1)
137 ?fn (*anyopaque) void
138 else
139 ?*const fn (*anyopaque) void;
128 try testing.expect(cast(FnPtr, 0) == @intToPtr(FnPtr, @as(usize, 0)));140 try testing.expect(cast(FnPtr, 0) == @intToPtr(FnPtr, @as(usize, 0)));
129 try testing.expect(cast(FnPtr, foo) == @intToPtr(FnPtr, @bitCast(usize, @as(isize, -1))));141 try testing.expect(cast(FnPtr, foo) == @intToPtr(FnPtr, @bitCast(usize, @as(isize, -1))));
130}142}
...@@ -135,9 +147,14 @@ pub fn sizeof(target: anytype) usize {...@@ -135,9 +147,14 @@ pub fn sizeof(target: anytype) usize {
135 switch (@typeInfo(T)) {147 switch (@typeInfo(T)) {
136 .Float, .Int, .Struct, .Union, .Array, .Bool, .Vector => return @sizeOf(T),148 .Float, .Int, .Struct, .Union, .Array, .Bool, .Vector => return @sizeOf(T),
137 .Fn => {149 .Fn => {
138 // sizeof(main) returns 1, sizeof(&main) returns pointer size.150 if (@import("builtin").zig_backend == .stage1) {
139 // We cannot distinguish those types in Zig, so use pointer size.151 // sizeof(main) returns 1, sizeof(&main) returns pointer size.
140 return @sizeOf(T);152 // We cannot distinguish those types in Zig, so use pointer size.
153 return @sizeOf(T);
154 }
155
156 // sizeof(main) in C returns 1
157 return 1;
141 },158 },
142 .Null => return @sizeOf(*anyopaque),159 .Null => return @sizeOf(*anyopaque),
143 .Void => {160 .Void => {
...@@ -233,7 +250,12 @@ test "sizeof" {...@@ -233,7 +250,12 @@ test "sizeof" {
233 try testing.expect(sizeof(*const *const [4:0]u8) == ptr_size);250 try testing.expect(sizeof(*const *const [4:0]u8) == ptr_size);
234 try testing.expect(sizeof(*const [4]u8) == ptr_size);251 try testing.expect(sizeof(*const [4]u8) == ptr_size);
235252
236 try testing.expect(sizeof(sizeof) == @sizeOf(@TypeOf(sizeof)));253 if (@import("builtin").zig_backend == .stage1) {
254 try testing.expect(sizeof(sizeof) == @sizeOf(@TypeOf(sizeof)));
255 } else if (false) { // TODO
256 try testing.expect(sizeof(&sizeof) == @sizeOf(@TypeOf(&sizeof)));
257 try testing.expect(sizeof(sizeof) == 1);
258 }
237259
238 try testing.expect(sizeof(void) == 1);260 try testing.expect(sizeof(void) == 1);
239 try testing.expect(sizeof(anyopaque) == 1);261 try testing.expect(sizeof(anyopaque) == 1);
src/Sema.zig+33-12
...@@ -3598,7 +3598,7 @@ fn zirValidateArrayInit(...@@ -3598,7 +3598,7 @@ fn zirValidateArrayInit(
3598 // any ZIR instructions at comptime; we need to do that here.3598 // any ZIR instructions at comptime; we need to do that here.
3599 if (array_ty.sentinel()) |sentinel_val| {3599 if (array_ty.sentinel()) |sentinel_val| {
3600 const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len);3600 const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len);
3601 const sentinel_ptr = try sema.elemPtrArray(block, init_src, array_ptr, init_src, array_len_ref);3601 const sentinel_ptr = try sema.elemPtrArray(block, init_src, array_ptr, init_src, array_len_ref, true);
3602 const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val);3602 const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val);
3603 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);3603 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);
3604 }3604 }
...@@ -6654,7 +6654,11 @@ fn zirFunc(...@@ -6654,7 +6654,11 @@ fn zirFunc(
6654 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;6654 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
6655 }6655 }
66566656
6657 const cc: std.builtin.CallingConvention = if (sema.owner_decl.is_exported)6657 // If this instruction has a body it means it's the type of the `owner_decl`
6658 // otherwise it's a function type without a `callconv` attribute and should
6659 // never be `.C`.
6660 // NOTE: revisit when doing #1717
6661 const cc: std.builtin.CallingConvention = if (sema.owner_decl.is_exported and has_body)
6658 .C6662 .C
6659 else6663 else
6660 .Unspecified;6664 .Unspecified;
...@@ -7540,7 +7544,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -7540,7 +7544,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
7540 const bin_inst = sema.code.instructions.items(.data)[inst].bin;7544 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
7541 const array_ptr = try sema.resolveInst(bin_inst.lhs);7545 const array_ptr = try sema.resolveInst(bin_inst.lhs);
7542 const elem_index = try sema.resolveInst(bin_inst.rhs);7546 const elem_index = try sema.resolveInst(bin_inst.rhs);
7543 return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);7547 return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src, false);
7544}7548}
75457549
7546fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7550fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -7553,7 +7557,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7553,7 +7557,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7553 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;7557 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
7554 const array_ptr = try sema.resolveInst(extra.lhs);7558 const array_ptr = try sema.resolveInst(extra.lhs);
7555 const elem_index = try sema.resolveInst(extra.rhs);7559 const elem_index = try sema.resolveInst(extra.rhs);
7556 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);7560 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false);
7557}7561}
75587562
7559fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7563fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -7565,7 +7569,7 @@ fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -7565,7 +7569,7 @@ fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
7565 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;7569 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
7566 const array_ptr = try sema.resolveInst(extra.ptr);7570 const array_ptr = try sema.resolveInst(extra.ptr);
7567 const elem_index = try sema.addIntUnsigned(Type.usize, extra.index);7571 const elem_index = try sema.addIntUnsigned(Type.usize, extra.index);
7568 return sema.elemPtr(block, src, array_ptr, elem_index, src);7572 return sema.elemPtr(block, src, array_ptr, elem_index, src, true);
7569}7573}
75707574
7571fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7575fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -11547,7 +11551,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -11547,7 +11551,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
11547 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };11551 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
11548 const ty = try sema.resolveType(block, operand_src, inst_data.operand);11552 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
11549 switch (ty.zigTypeTag()) {11553 switch (ty.zigTypeTag()) {
11550 .Fn => unreachable,11554 .Fn,
11551 .NoReturn,11555 .NoReturn,
11552 .Undefined,11556 .Undefined,
11553 .Null,11557 .Null,
...@@ -13465,7 +13469,12 @@ fn zirStructInit(...@@ -13465,7 +13469,12 @@ fn zirStructInit(
13465 }13469 }
1346613470
13467 if (is_ref) {13471 if (is_ref) {
13468 const alloc = try block.addTy(.alloc, resolved_ty);13472 const target = sema.mod.getTarget();
13473 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
13474 .pointee_type = resolved_ty,
13475 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
13476 });
13477 const alloc = try block.addTy(.alloc, alloc_ty);
13469 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty);13478 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty);
13470 try sema.storePtr(block, src, field_ptr, init_inst);13479 try sema.storePtr(block, src, field_ptr, init_inst);
13471 return alloc;13480 return alloc;
...@@ -18719,6 +18728,7 @@ fn elemPtr(...@@ -18719,6 +18728,7 @@ fn elemPtr(
18719 indexable_ptr: Air.Inst.Ref,18728 indexable_ptr: Air.Inst.Ref,
18720 elem_index: Air.Inst.Ref,18729 elem_index: Air.Inst.Ref,
18721 elem_index_src: LazySrcLoc,18730 elem_index_src: LazySrcLoc,
18731 init: bool,
18722) CompileError!Air.Inst.Ref {18732) CompileError!Air.Inst.Ref {
18723 const indexable_ptr_src = src; // TODO better source location18733 const indexable_ptr_src = src; // TODO better source location
18724 const indexable_ptr_ty = sema.typeOf(indexable_ptr);18734 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
...@@ -18755,11 +18765,11 @@ fn elemPtr(...@@ -18755,11 +18765,11 @@ fn elemPtr(
18755 },18765 },
18756 .One => {18766 .One => {
18757 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable18767 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
18758 return sema.elemPtrArray(block, indexable_ptr_src, indexable, elem_index_src, elem_index);18768 return sema.elemPtrArray(block, indexable_ptr_src, indexable, elem_index_src, elem_index, init);
18759 },18769 },
18760 }18770 }
18761 },18771 },
18762 .Array, .Vector => return sema.elemPtrArray(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index),18772 .Array, .Vector => return sema.elemPtrArray(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init),
18763 .Struct => {18773 .Struct => {
18764 // Tuple field access.18774 // Tuple field access.
18765 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);18775 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
...@@ -18813,7 +18823,7 @@ fn elemVal(...@@ -18813,7 +18823,7 @@ fn elemVal(
18813 },18823 },
18814 .One => {18824 .One => {
18815 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable18825 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
18816 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src);18826 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false);
18817 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);18827 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
18818 },18828 },
18819 },18829 },
...@@ -18994,6 +19004,7 @@ fn elemPtrArray(...@@ -18994,6 +19004,7 @@ fn elemPtrArray(
18994 array_ptr: Air.Inst.Ref,19004 array_ptr: Air.Inst.Ref,
18995 elem_index_src: LazySrcLoc,19005 elem_index_src: LazySrcLoc,
18996 elem_index: Air.Inst.Ref,19006 elem_index: Air.Inst.Ref,
19007 init: bool,
18997) CompileError!Air.Inst.Ref {19008) CompileError!Air.Inst.Ref {
18998 const target = sema.mod.getTarget();19009 const target = sema.mod.getTarget();
18999 const array_ptr_ty = sema.typeOf(array_ptr);19010 const array_ptr_ty = sema.typeOf(array_ptr);
...@@ -19030,7 +19041,7 @@ fn elemPtrArray(...@@ -19030,7 +19041,7 @@ fn elemPtrArray(
19030 }19041 }
1903119042
19032 const valid_rt = try sema.validateRunTimeType(block, elem_index_src, array_ty.elemType2(), false);19043 const valid_rt = try sema.validateRunTimeType(block, elem_index_src, array_ty.elemType2(), false);
19033 if (!valid_rt) {19044 if (!valid_rt and !init) {
19034 const msg = msg: {19045 const msg = msg: {
19035 const msg = try sema.errMsg(19046 const msg = try sema.errMsg(
19036 block,19047 block,
...@@ -20133,7 +20144,7 @@ fn storePtr2(...@@ -20133,7 +20144,7 @@ fn storePtr2(
20133 const elem_src = operand_src; // TODO better source location20144 const elem_src = operand_src; // TODO better source location
20134 const elem = try tupleField(sema, block, operand_src, uncasted_operand, elem_src, i);20145 const elem = try tupleField(sema, block, operand_src, uncasted_operand, elem_src, i);
20135 const elem_index = try sema.addIntUnsigned(Type.usize, i);20146 const elem_index = try sema.addIntUnsigned(Type.usize, i);
20136 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src);20147 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false);
20137 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);20148 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
20138 }20149 }
20139 return;20150 return;
...@@ -20400,6 +20411,16 @@ fn beginComptimePtrMutation(...@@ -20400,6 +20411,16 @@ fn beginComptimePtrMutation(
20400 .ty = elem_ty,20411 .ty = elem_ty,
20401 },20412 },
2040220413
20414 .the_only_possible_value => {
20415 const duped = try sema.arena.create(Value);
20416 duped.* = Value.initTag(.the_only_possible_value);
20417 return ComptimePtrMutationKit{
20418 .decl_ref_mut = parent.decl_ref_mut,
20419 .val = duped,
20420 .ty = elem_ty,
20421 };
20422 },
20423
20403 else => unreachable,20424 else => unreachable,
20404 }20425 }
20405 },20426 },
src/codegen/llvm.zig+3-1
...@@ -5389,7 +5389,9 @@ pub const FuncGen = struct {...@@ -5389,7 +5389,9 @@ pub const FuncGen = struct {
5389 }5389 }
5390 llvm_constraints.appendSliceAssumeCapacity(constraint);5390 llvm_constraints.appendSliceAssumeCapacity(constraint);
53915391
5392 name_map.putAssumeCapacityNoClobber(name, {});5392 if (!std.mem.eql(u8, name, "_")) {
5393 name_map.putAssumeCapacityNoClobber(name, {});
5394 }
5393 llvm_param_i += 1;5395 llvm_param_i += 1;
5394 total_i += 1;5396 total_i += 1;
5395 }5397 }
src/type.zig+23-11
...@@ -784,7 +784,7 @@ pub const Type = extern union {...@@ -784,7 +784,7 @@ pub const Type = extern union {
784784
785 .anyframe_T => {785 .anyframe_T => {
786 if (b.zigTypeTag() != .AnyFrame) return false;786 if (b.zigTypeTag() != .AnyFrame) return false;
787 return a.childType().eql(b.childType(), mod);787 return a.elemType2().eql(b.elemType2(), mod);
788 },788 },
789789
790 .empty_struct => {790 .empty_struct => {
...@@ -2035,7 +2035,11 @@ pub const Type = extern union {...@@ -2035,7 +2035,11 @@ pub const Type = extern union {
2035 try writer.writeAll("fn(");2035 try writer.writeAll("fn(");
2036 for (fn_info.param_types) |param_ty, i| {2036 for (fn_info.param_types) |param_ty, i| {
2037 if (i != 0) try writer.writeAll(", ");2037 if (i != 0) try writer.writeAll(", ");
2038 try print(param_ty, writer, mod);2038 if (param_ty.tag() == .generic_poison) {
2039 try writer.writeAll("anytype");
2040 } else {
2041 try print(param_ty, writer, mod);
2042 }
2039 }2043 }
2040 if (fn_info.is_var_args) {2044 if (fn_info.is_var_args) {
2041 if (fn_info.param_types.len != 0) {2045 if (fn_info.param_types.len != 0) {
...@@ -2052,7 +2056,11 @@ pub const Type = extern union {...@@ -2052,7 +2056,11 @@ pub const Type = extern union {
2052 if (fn_info.alignment != 0) {2056 if (fn_info.alignment != 0) {
2053 try writer.print("align({d}) ", .{fn_info.alignment});2057 try writer.print("align({d}) ", .{fn_info.alignment});
2054 }2058 }
2055 try print(fn_info.return_type, writer, mod);2059 if (fn_info.return_type.tag() == .generic_poison) {
2060 try writer.writeAll("anytype");
2061 } else {
2062 try print(fn_info.return_type, writer, mod);
2063 }
2056 },2064 },
20572065
2058 .error_union => {2066 .error_union => {
...@@ -4125,14 +4133,15 @@ pub const Type = extern union {...@@ -4125,14 +4133,15 @@ pub const Type = extern union {
4125 /// TODO this is deprecated in favor of `childType`.4133 /// TODO this is deprecated in favor of `childType`.
4126 pub const elemType = childType;4134 pub const elemType = childType;
41274135
4128 /// For *[N]T, returns T.4136 /// For *[N]T, returns T.
4129 /// For ?*T, returns T.4137 /// For ?*T, returns T.
4130 /// For ?*[N]T, returns T.4138 /// For ?*[N]T, returns T.
4131 /// For ?[*]T, returns T.4139 /// For ?[*]T, returns T.
4132 /// For *T, returns T.4140 /// For *T, returns T.
4133 /// For [*]T, returns T.4141 /// For [*]T, returns T.
4134 /// For [N]T, returns T.4142 /// For [N]T, returns T.
4135 /// For []T, returns T.4143 /// For []T, returns T.
4144 /// For anyframe->T, returns T.
4136 pub fn elemType2(ty: Type) Type {4145 pub fn elemType2(ty: Type) Type {
4137 return switch (ty.tag()) {4146 return switch (ty.tag()) {
4138 .vector => ty.castTag(.vector).?.data.elem_type,4147 .vector => ty.castTag(.vector).?.data.elem_type,
...@@ -4173,6 +4182,9 @@ pub const Type = extern union {...@@ -4173,6 +4182,9 @@ pub const Type = extern union {
4173 .optional_single_mut_pointer => ty.castPointer().?.data,4182 .optional_single_mut_pointer => ty.castPointer().?.data,
4174 .optional_single_const_pointer => ty.castPointer().?.data,4183 .optional_single_const_pointer => ty.castPointer().?.data,
41754184
4185 .anyframe_T => ty.castTag(.anyframe_T).?.data,
4186 .@"anyframe" => Type.@"void",
4187
4176 else => unreachable,4188 else => unreachable,
4177 };4189 };
4178 }4190 }
src/value.zig+13-1
...@@ -1174,6 +1174,10 @@ pub const Value = extern union {...@@ -1174,6 +1174,10 @@ pub const Value = extern union {
1174 return;1174 return;
1175 }1175 }
1176 switch (ty.zigTypeTag()) {1176 switch (ty.zigTypeTag()) {
1177 .Void => {},
1178 .Bool => {
1179 buffer[0] = @boolToInt(val.toBool());
1180 },
1177 .Int => {1181 .Int => {
1178 var bigint_buffer: BigIntSpace = undefined;1182 var bigint_buffer: BigIntSpace = undefined;
1179 const bigint = val.toBigInt(&bigint_buffer, target);1183 const bigint = val.toBigInt(&bigint_buffer, target);
...@@ -1291,6 +1295,14 @@ pub const Value = extern union {...@@ -1291,6 +1295,14 @@ pub const Value = extern union {
1291 ) Allocator.Error!Value {1295 ) Allocator.Error!Value {
1292 const target = mod.getTarget();1296 const target = mod.getTarget();
1293 switch (ty.zigTypeTag()) {1297 switch (ty.zigTypeTag()) {
1298 .Void => return Value.@"void",
1299 .Bool => {
1300 if (buffer[0] == 0) {
1301 return Value.@"false";
1302 } else {
1303 return Value.@"true";
1304 }
1305 },
1294 .Int => {1306 .Int => {
1295 if (buffer.len == 0) return Value.zero;1307 if (buffer.len == 0) return Value.zero;
1296 const int_info = ty.intInfo(target);1308 const int_info = ty.intInfo(target);
...@@ -1311,7 +1323,7 @@ pub const Value = extern union {...@@ -1311,7 +1323,7 @@ pub const Value = extern union {
1311 128 => return Value.Tag.float_128.create(arena, floatReadFromMemory(f128, target, buffer)),1323 128 => return Value.Tag.float_128.create(arena, floatReadFromMemory(f128, target, buffer)),
1312 else => unreachable,1324 else => unreachable,
1313 },1325 },
1314 .Array => {1326 .Array, .Vector => {
1315 const elem_ty = ty.childType();1327 const elem_ty = ty.childType();
1316 const elem_size = elem_ty.abiSize(target);1328 const elem_size = elem_ty.abiSize(target);
1317 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));1329 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));
test/behavior/array.zig+9
...@@ -573,3 +573,12 @@ test "type coercion of pointer to anon struct literal to pointer to array" {...@@ -573,3 +573,12 @@ test "type coercion of pointer to anon struct literal to pointer to array" {
573 try S.doTheTest();573 try S.doTheTest();
574 comptime try S.doTheTest();574 comptime try S.doTheTest();
575}575}
576
577test "array with comptime only element type" {
578 const a = [_]type{
579 u32,
580 i32,
581 };
582 try testing.expect(a[0] == u32);
583 try testing.expect(a[1] == i32);
584}
test/cases/compile_errors/runtime_indexing_comptime_array.zig+6-6
...@@ -23,9 +23,9 @@ pub export fn entry3() void {...@@ -23,9 +23,9 @@ pub export fn entry3() void {
23// error23// error
24// backend=stage2,llvm24// backend=stage2,llvm
25//25//
26// :6:33: error: values of type '[2]fn() callconv(.C) void' must be comptime known, but index value is runtime known26// :6:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
27// :6:33: note: use '*const fn() callconv(.C) void' for a function pointer type27// :6:5: note: use '*const fn() void' for a function pointer type
28// :13:33: error: values of type '[2]fn() callconv(.C) void' must be comptime known, but index value is runtime known28// :13:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
29// :13:33: note: use '*const fn() callconv(.C) void' for a function pointer type29// :13:5: note: use '*const fn() void' for a function pointer type
30// :19:33: error: values of type '[2]fn() callconv(.C) void' must be comptime known, but index value is runtime known30// :19:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
31// :19:33: note: use '*const fn() callconv(.C) void' for a function pointer type31// :19:5: note: use '*const fn() void' for a function pointer type