authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-03 16:02:23+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-03 20:21:20+03:00
log6d44c0a16c90a13cb3507751e2015edf51c642cf
tree6dfa9b43c776a3a34fad7aedada8b76b5eac5ac2
parent1a7b4ddeaedb81255cfa8907958c3cf09dd340ee

std: update tests to stage2 semantics


11 files changed, 262 insertions(+), 144 deletions(-)

lib/std/crypto/25519/scalar.zig+8-4
......@@ -34,12 +34,14 @@ pub fn rejectNonCanonical(s: CompressedScalar) NonCanonicalError!void {
3434
3535/// Reduce a scalar to the field size.
3636pub fn reduce(s: CompressedScalar) CompressedScalar {
37 return Scalar.fromBytes(s).toBytes();
37 var scalar = Scalar.fromBytes(s);
38 return scalar.toBytes();
3839}
3940
4041/// Reduce a 64-bytes scalar to the field size.
4142pub fn reduce64(s: [64]u8) CompressedScalar {
42 return ScalarDouble.fromBytes64(s).toBytes();
43 var scalar = ScalarDouble.fromBytes64(s);
44 return scalar.toBytes();
4345}
4446
4547/// Perform the X25519 "clamping" operation.
......@@ -106,12 +108,14 @@ pub const Scalar = struct {
106108
107109 /// Unpack a 32-byte representation of a scalar
108110 pub fn fromBytes(bytes: CompressedScalar) Scalar {
109 return ScalarDouble.fromBytes32(bytes).reduce(5);
111 var scalar = ScalarDouble.fromBytes32(bytes);
112 return scalar.reduce(5);
110113 }
111114
112115 /// Unpack a 64-byte representation of a scalar
113116 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);
115119 }
116120
117121 /// 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 {
679679}
680680
681681test "BLAKE3 reference test cases" {
682 var hash = &Blake3.init(.{});
683 var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* });
684 var derive_key = &Blake3.initKdf(reference_test.context_string, .{});
682 var hash_state = Blake3.init(.{});
683 const hash = &hash_state;
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
686689 for (reference_test.cases) |t| {
687690 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 {
128128 r.* = mem.readIntLittle(u64, d[8 * i ..][0..8]);
129129 }
130130
131 comptime var x: usize = 0;
132 comptime var y: usize = 0;
133131 for (RC[0..no_rounds]) |round| {
134132 // theta
135 x = 0;
133 comptime var x: usize = 0;
136134 inline while (x < 5) : (x += 1) {
137135 c[x] = s[x] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20];
138136 }
139137 x = 0;
140138 inline while (x < 5) : (x += 1) {
141139 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;
143141 inline while (y < 5) : (y += 1) {
144142 s[x + y * 5] ^= t[0];
145143 }
......@@ -155,7 +153,7 @@ fn keccakF(comptime F: usize, d: *[F / 8]u8) void {
155153 }
156154
157155 // chi
158 y = 0;
156 comptime var y: usize = 0;
159157 inline while (y < 5) : (y += 1) {
160158 x = 0;
161159 inline while (x < 5) : (x += 1) {
lib/std/fmt.zig+1
......@@ -2123,6 +2123,7 @@ test "pointer" {
21232123 try expectFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});
21242124 try expectFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});
21252125 }
2126 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
21262127 {
21272128 const value = @intToPtr(fn () void, 0xdeadbeef);
21282129 try expectFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
lib/std/heap.zig+2-1
......@@ -1210,7 +1210,8 @@ pub fn testAllocatorAlignedShrink(base_allocator: mem.Allocator) !void {
12101210 const allocator = validationAllocator.allocator();
12111211
12121212 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
12151216 const alloc_size = mem.page_size * 2 + 50;
12161217 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" {
9191
9292 var allocator_buf: [10]u8 = undefined;
9393 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
9697 var a = try allocator.alloc(u8, 10);
9798 a = allocator.shrink(a, 5);
lib/std/io/reader.zig+64-32
......@@ -344,7 +344,8 @@ pub fn Reader(
344344
345345test "Reader" {
346346 var buf = "a\x02".*;
347 const reader = std.io.fixedBufferStream(&buf).reader();
347 var fis = std.io.fixedBufferStream(&buf);
348 const reader = fis.reader();
348349 try testing.expect((try reader.readByte()) == 'a');
349350 try testing.expect((try reader.readEnum(enum(u8) {
350351 a = 0,
......@@ -356,13 +357,15 @@ test "Reader" {
356357}
357358
358359test "Reader.isBytes" {
359 const reader = std.io.fixedBufferStream("foobar").reader();
360 var fis = std.io.fixedBufferStream("foobar");
361 const reader = fis.reader();
360362 try testing.expectEqual(true, try reader.isBytes("foo"));
361363 try testing.expectEqual(false, try reader.isBytes("qux"));
362364}
363365
364366test "Reader.skipBytes" {
365 const reader = std.io.fixedBufferStream("foobar").reader();
367 var fis = std.io.fixedBufferStream("foobar");
368 const reader = fis.reader();
366369 try reader.skipBytes(3, .{});
367370 try testing.expect(try reader.isBytes("bar"));
368371 try reader.skipBytes(0, .{});
......@@ -374,7 +377,8 @@ test "Reader.readUntilDelimiterArrayList returns ArrayLists with bytes read unti
374377 var list = std.ArrayList(u8).init(a);
375378 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
379383 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
380384 try std.testing.expectEqualStrings("0000", list.items);
......@@ -388,7 +392,8 @@ test "Reader.readUntilDelimiterArrayList returns an empty ArrayList" {
388392 var list = std.ArrayList(u8).init(a);
389393 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
393398 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
394399 try std.testing.expectEqualStrings("", list.items);
......@@ -399,7 +404,8 @@ test "Reader.readUntilDelimiterArrayList returns StreamTooLong, then an ArrayLis
399404 var list = std.ArrayList(u8).init(a);
400405 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
404410 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterArrayList(&list, '\n', 5));
405411 try std.testing.expectEqualStrings("12345", list.items);
......@@ -412,7 +418,8 @@ test "Reader.readUntilDelimiterArrayList returns EndOfStream" {
412418 var list = std.ArrayList(u8).init(a);
413419 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
417424 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));
418425 try std.testing.expectEqualStrings("1234", list.items);
......@@ -421,7 +428,8 @@ test "Reader.readUntilDelimiterArrayList returns EndOfStream" {
421428test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
422429 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
426434 {
427435 var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
......@@ -441,7 +449,8 @@ test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until th
441449test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {
442450 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
446455 {
447456 var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
......@@ -453,7 +462,8 @@ test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {
453462test "Reader.readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
454463 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
458468 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
465475test "Reader.readUntilDelimiterAlloc returns EndOfStream" {
466476 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
470481 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));
471482}
472483
473484test "Reader.readUntilDelimiter returns bytes read until the delimiter" {
474485 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();
476488 try std.testing.expectEqualStrings("0000", try reader.readUntilDelimiter(&buf, '\n'));
477489 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
478490}
479491
480492test "Reader.readUntilDelimiter returns an empty string" {
481493 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();
483496 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
484497}
485498
486499test "Reader.readUntilDelimiter returns StreamTooLong, then an empty string" {
487500 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();
489503 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
490504 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
491505}
492506
493507test "Reader.readUntilDelimiter returns StreamTooLong, then bytes read until the delimiter" {
494508 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();
496511 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
497512 try std.testing.expectEqualStrings("67", try reader.readUntilDelimiter(&buf, '\n'));
498513}
499514
500515test "Reader.readUntilDelimiter returns EndOfStream" {
501516 var buf: [5]u8 = undefined;
502 const reader = std.io.fixedBufferStream("").reader();
517 var fis = std.io.fixedBufferStream("");
518 const reader = fis.reader();
503519 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
504520}
505521
506522test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {
507523 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();
509526 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
510527 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
511528}
512529
513530test "Reader.readUntilDelimiter returns EndOfStream" {
514531 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();
516534 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
517535}
518536
519537test "Reader.readUntilDelimiter returns StreamTooLong, then EndOfStream" {
520538 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();
522541 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
523542 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
524543}
525544
526545test "Reader.readUntilDelimiter writes all bytes read to the output buffer" {
527546 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();
529549 _ = try reader.readUntilDelimiter(&buf, '\n');
530550 try std.testing.expectEqualStrings("0000\n", &buf);
531551 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" {
535555test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
536556 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
540561 {
541562 var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
......@@ -555,7 +576,8 @@ test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read unt
555576test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {
556577 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
560582 {
561583 var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
......@@ -567,7 +589,8 @@ test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {
567589test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
568590 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
572595 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEofAlloc(a, '\n', 5));
573596
......@@ -578,60 +601,69 @@ test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayLi
578601
579602test "Reader.readUntilDelimiterOrEof returns bytes read until the delimiter" {
580603 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();
582606 try std.testing.expectEqualStrings("0000", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
583607 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
584608}
585609
586610test "Reader.readUntilDelimiterOrEof returns an empty string" {
587611 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();
589614 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
590615}
591616
592617test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then an empty string" {
593618 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();
595621 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
596622 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
597623}
598624
599625test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until the delimiter" {
600626 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();
602629 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
603630 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
604631}
605632
606633test "Reader.readUntilDelimiterOrEof returns null" {
607634 var buf: [5]u8 = undefined;
608 const reader = std.io.fixedBufferStream("").reader();
635 var fis = std.io.fixedBufferStream("");
636 const reader = fis.reader();
609637 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
610638}
611639
612640test "Reader.readUntilDelimiterOrEof returns bytes read until delimiter, then null" {
613641 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();
615644 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
616645 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
617646}
618647
619648test "Reader.readUntilDelimiterOrEof returns bytes read until end-of-stream" {
620649 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();
622652 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
623653}
624654
625655test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until end-of-stream" {
626656 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();
628659 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
629660 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
630661}
631662
632663test "Reader.readUntilDelimiterOrEof writes all bytes read to the output buffer" {
633664 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();
635667 _ = try reader.readUntilDelimiterOrEof(&buf, '\n');
636668 try std.testing.expectEqualStrings("0000\n", &buf);
637669 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 {
15061506}
15071507
15081508test "skipValue" {
1509 try skipValue(&TokenStream.init("false"));
1510 try skipValue(&TokenStream.init("true"));
1511 try skipValue(&TokenStream.init("null"));
1512 try skipValue(&TokenStream.init("42"));
1513 try skipValue(&TokenStream.init("42.0"));
1514 try skipValue(&TokenStream.init("\"foo\""));
1515 try skipValue(&TokenStream.init("[101, 111, 121]"));
1516 try skipValue(&TokenStream.init("{}"));
1517 try skipValue(&TokenStream.init("{\"foo\": \"bar\"}"));
1509 var ts = TokenStream.init("false");
1510 try skipValue(&ts);
1511 ts = TokenStream.init("true");
1512 try skipValue(&ts);
1513 ts = TokenStream.init("null");
1514 try skipValue(&ts);
1515 ts = TokenStream.init("42");
1516 try skipValue(&ts);
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
15191528 { // An absurd number of nestings
15201529 const nestings = StreamingParser.default_max_nestings + 1;
15211530
1522 try testing.expectError(
1523 error.TooManyNestedItems,
1524 skipValue(&TokenStream.init("[" ** nestings ++ "]" ** nestings)),
1525 );
1531 ts = TokenStream.init("[" ** nestings ++ "]" ** nestings);
1532 try testing.expectError(error.TooManyNestedItems, skipValue(&ts));
15261533 }
15271534
15281535 { // Would a number token cause problems in a deeply-nested array?
15291536 const nestings = StreamingParser.default_max_nestings;
15301537 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(
1535 error.TooManyNestedItems,
1536 skipValue(&TokenStream.init("[" ++ deeply_nested_array ++ "]")),
1537 );
1542 ts = TokenStream.init("[" ++ deeply_nested_array ++ "]");
1543 try testing.expectError(error.TooManyNestedItems, skipValue(&ts));
15381544 }
15391545
15401546 // Mismatched brace/square bracket
1541 try testing.expectError(
1542 error.UnexpectedClosingBrace,
1543 skipValue(&TokenStream.init("[102, 111, 111}")),
1544 );
1547 ts = TokenStream.init("[102, 111, 111}");
1548 try testing.expectError(error.UnexpectedClosingBrace, skipValue(&ts));
15451549
15461550 { // should fail if no value found (e.g. immediate close of object)
15471551 var empty_object = TokenStream.init("{}");
......@@ -1980,18 +1984,29 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
19801984}
19811985
19821986test "parse" {
1983 try testing.expectEqual(false, try parse(bool, &TokenStream.init("false"), ParseOptions{}));
1984 try testing.expectEqual(true, try parse(bool, &TokenStream.init("true"), ParseOptions{}));
1985 try testing.expectEqual(@as(u1, 1), try parse(u1, &TokenStream.init("1"), ParseOptions{}));
1986 try testing.expectError(error.Overflow, parse(u1, &TokenStream.init("50"), ParseOptions{}));
1987 try testing.expectEqual(@as(u64, 42), try parse(u64, &TokenStream.init("42"), ParseOptions{}));
1988 try testing.expectEqual(@as(f64, 42), try parse(f64, &TokenStream.init("42.0"), ParseOptions{}));
1989 try testing.expectEqual(@as(?bool, null), try parse(?bool, &TokenStream.init("null"), ParseOptions{}));
1990 try testing.expectEqual(@as(?bool, true), try parse(?bool, &TokenStream.init("true"), ParseOptions{}));
1991
1992 try testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("\"foo\""), ParseOptions{}));
1993 try testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("[102, 111, 111]"), ParseOptions{}));
1994 try testing.expectEqual(@as([0]u8, undefined), try parse([0]u8, &TokenStream.init("[]"), ParseOptions{}));
1987 var ts = TokenStream.init("false");
1988 try testing.expectEqual(false, try parse(bool, &ts, ParseOptions{}));
1989 ts = TokenStream.init("true");
1990 try testing.expectEqual(true, try parse(bool, &ts, ParseOptions{}));
1991 ts = TokenStream.init("1");
1992 try testing.expectEqual(@as(u1, 1), try parse(u1, &ts, ParseOptions{}));
1993 ts = TokenStream.init("50");
1994 try testing.expectError(error.Overflow, parse(u1, &ts, ParseOptions{}));
1995 ts = TokenStream.init("42");
1996 try testing.expectEqual(@as(u64, 42), try parse(u64, &ts, ParseOptions{}));
1997 ts = TokenStream.init("42.0");
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{}));
19952010}
19962011
19972012test "parse into enum" {
......@@ -2000,36 +2015,48 @@ test "parse into enum" {
20002015 Bar,
20012016 @"with\\escape",
20022017 };
2003 try testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("\"Foo\""), ParseOptions{}));
2004 try testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("42"), ParseOptions{}));
2005 try testing.expectEqual(@as(T, .@"with\\escape"), try parse(T, &TokenStream.init("\"with\\\\escape\""), ParseOptions{}));
2006 try testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("5"), ParseOptions{}));
2007 try testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("\"Qux\""), ParseOptions{}));
2018 var ts = TokenStream.init("\"Foo\"");
2019 try testing.expectEqual(@as(T, .Foo), try parse(T, &ts, ParseOptions{}));
2020 ts = TokenStream.init("42");
2021 try testing.expectEqual(@as(T, .Foo), try parse(T, &ts, 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{}));
20082028}
20092029
20102030test "parse with trailing data" {
2011 try testing.expectEqual(false, try parse(bool, &TokenStream.init("falsed"), ParseOptions{ .allow_trailing_data = true }));
2012 try testing.expectError(error.InvalidTopLevelTrailing, parse(bool, &TokenStream.init("falsed"), ParseOptions{ .allow_trailing_data = false }));
2031 var ts = TokenStream.init("falsed");
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 }));
20132035 // 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 }));
20152038}
20162039
20172040test "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
20202044 const options = ParseOptions{ .allocator = testing.allocator };
20212045 {
2022 const r = try parse([]u8, &TokenStream.init("\"foo\""), options);
2046 ts = TokenStream.init("\"foo\"");
2047 const r = try parse([]u8, &ts, options);
20232048 defer parseFree([]u8, r, options);
20242049 try testing.expectEqualSlices(u8, "foo", r);
20252050 }
20262051 {
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);
20282054 defer parseFree([]u8, r, options);
20292055 try testing.expectEqualSlices(u8, "foo", r);
20302056 }
20312057 {
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);
20332060 defer parseFree([]u8, r, options);
20342061 try testing.expectEqualSlices(u8, "with\\escape", r);
20352062 }
......@@ -2042,7 +2069,8 @@ test "parse into tagged union" {
20422069 float: f64,
20432070 string: []const u8,
20442071 };
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{}));
20462074 }
20472075
20482076 { // failing allocations should be bubbled up instantly without trying next member
......@@ -2053,7 +2081,8 @@ test "parse into tagged union" {
20532081 string: []const u8,
20542082 array: [3]u8,
20552083 };
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));
20572086 }
20582087
20592088 {
......@@ -2062,7 +2091,8 @@ test "parse into tagged union" {
20622091 x: u8,
20632092 y: u8,
20642093 };
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{}));
20662096 }
20672097
20682098 { // needs to back out when first union member doesn't match
......@@ -2070,7 +2100,8 @@ test "parse into tagged union" {
20702100 A: struct { x: u32 },
20712101 B: struct { y: u32 },
20722102 };
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{}));
20742105 }
20752106}
20762107
......@@ -2080,7 +2111,8 @@ test "parse union bubbles up AllocatorRequired" {
20802111 string: []const u8,
20812112 int: i32,
20822113 };
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{}));
20842116 }
20852117
20862118 { // string member not first in union (and matching)
......@@ -2089,7 +2121,8 @@ test "parse union bubbles up AllocatorRequired" {
20892121 float: f64,
20902122 string: []const u8,
20912123 };
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{}));
20932126 }
20942127}
20952128
......@@ -2102,7 +2135,8 @@ test "parseFree descends into tagged union" {
21022135 string: []const u8,
21032136 };
21042137 // 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);
21062140 try testing.expectEqual(std.meta.Tag(T).string, @as(std.meta.Tag(T), r));
21072141 try testing.expectEqualSlices(u8, "withąunicode", r.string);
21082142 try testing.expectEqual(@as(usize, 0), fail_alloc.deallocations);
......@@ -2116,12 +2150,13 @@ test "parse with comptime field" {
21162150 comptime a: i32 = 0,
21172151 b: bool,
21182152 };
2119 try testing.expectEqual(T{ .a = 0, .b = true }, try parse(T, &TokenStream.init(
2153 var ts = TokenStream.init(
21202154 \\{
21212155 \\ "a": 0,
21222156 \\ "b": true
21232157 \\}
2124 ), ParseOptions{}));
2158 );
2159 try testing.expectEqual(T{ .a = 0, .b = true }, try parse(T, &ts, ParseOptions{}));
21252160 }
21262161
21272162 { // string comptime values currently require an allocator
......@@ -2140,12 +2175,13 @@ test "parse with comptime field" {
21402175 .allocator = std.testing.allocator,
21412176 };
21422177
2143 const r = try parse(T, &TokenStream.init(
2178 var ts = TokenStream.init(
21442179 \\{
21452180 \\ "kind": "float",
21462181 \\ "b": 1.0
21472182 \\}
2148 ), options);
2183 );
2184 const r = try parse(T, &ts, options);
21492185
21502186 // check that parseFree doesn't try to free comptime fields
21512187 parseFree(T, r, options);
......@@ -2154,7 +2190,8 @@ test "parse with comptime field" {
21542190
21552191test "parse into struct with no fields" {
21562192 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{}));
21582195}
21592196
21602197test "parse into struct with misc fields" {
......@@ -2186,7 +2223,7 @@ test "parse into struct with misc fields" {
21862223 string: []const u8,
21872224 };
21882225 };
2189 const r = try parse(T, &TokenStream.init(
2226 var ts = TokenStream.init(
21902227 \\{
21912228 \\ "int": 420,
21922229 \\ "float": 3.14,
......@@ -2208,7 +2245,8 @@ test "parse into struct with misc fields" {
22082245 \\ ],
22092246 \\ "a_union": 100000
22102247 \\}
2211 ), options);
2248 );
2249 const r = try parse(T, &ts, options);
22122250 defer parseFree(T, r, options);
22132251 try testing.expectEqual(@as(i64, 420), r.int);
22142252 try testing.expectEqual(@as(f64, 3.14), r.float);
......@@ -2239,14 +2277,15 @@ test "parse into struct with strings and arrays with sentinels" {
22392277 data: [:99]const i32,
22402278 simple_data: []const i32,
22412279 };
2242 const r = try parse(T, &TokenStream.init(
2280 var ts = TokenStream.init(
22432281 \\{
22442282 \\ "language": "zig",
22452283 \\ "language_without_sentinel": "zig again!",
22462284 \\ "data": [1, 2, 3],
22472285 \\ "simple_data": [4, 5, 6]
22482286 \\}
2249 ), options);
2287 );
2288 const r = try parse(T, &ts, options);
22502289 defer parseFree(T, r, options);
22512290
22522291 try testing.expectEqualSentinel(u8, 0, "zig", r.language);
......@@ -2275,19 +2314,25 @@ test "parse into struct with duplicate field" {
22752314
22762315 const T1 = struct { a: *u64 };
22772316 // 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));
2279 try testing.expectError(error.InvalidNumber, parse(T1, &TokenStream.init(str), options_last));
2317 var ts = TokenStream.init(str);
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
22812322 const T2 = struct { a: f64 };
2282 try testing.expectEqual(T2{ .a = 1.0 }, try parse(T2, &TokenStream.init(str), options_first));
2283 try testing.expectEqual(T2{ .a = 0.25 }, try parse(T2, &TokenStream.init(str), options_last));
2323 ts = TokenStream.init(str);
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
22852328 const T3 = struct { comptime a: f64 = 1.0 };
22862329 // .UseFirst should succeed because second "a" value is unconditionally ignored (even though != 1.0)
22872330 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));
22892333 // .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));
22912336}
22922337
22932338test "parse into struct ignoring unknown fields" {
......@@ -2301,7 +2346,7 @@ test "parse into struct ignoring unknown fields" {
23012346 .ignore_unknown_fields = true,
23022347 };
23032348
2304 const r = try parse(T, &std.json.TokenStream.init(
2349 var ts = TokenStream.init(
23052350 \\{
23062351 \\ "int": 420,
23072352 \\ "float": 3.14,
......@@ -2323,7 +2368,8 @@ test "parse into struct ignoring unknown fields" {
23232368 \\ "a_union": 100000,
23242369 \\ "language": "zig"
23252370 \\}
2326 ), ops);
2371 );
2372 const r = try parse(T, &ts, ops);
23272373 defer parseFree(T, r, ops);
23282374
23292375 try testing.expectEqual(@as(i64, 420), r.int);
......@@ -2341,7 +2387,8 @@ test "parse into recursive union definition" {
23412387 };
23422388 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);
23452392 defer parseFree(T, r, ops);
23462393
23472394 try testing.expectEqual(@as(i64, 58), r.values.array[0].integer);
......@@ -2363,7 +2410,8 @@ test "parse into double recursive union definition" {
23632410 };
23642411 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);
23672415 defer parseFree(T, r, ops);
23682416
23692417 try testing.expectEqual(@as(i64, 58), r.values.array[0].array[0].integer);
......@@ -2806,10 +2854,13 @@ test "integer after float has proper type" {
28062854
28072855test "parse exponential into int" {
28082856 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{});
28102859 try testing.expectEqual(@as(i64, 420), r.int);
2811 try testing.expectError(error.InvalidNumber, parse(T, &TokenStream.init("{ \"int\": 0.042e2 }"), ParseOptions{}));
2812 try testing.expectError(error.Overflow, parse(T, &TokenStream.init("{ \"int\": 18446744073709551616.0 }"), ParseOptions{}));
2860 ts = TokenStream.init("{ \"int\": 0.042e2 }");
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{}));
28132864}
28142865
28152866test "escaped characters" {
......@@ -2858,10 +2909,12 @@ test "string copy option" {
28582909 defer arena_allocator.deinit();
28592910 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);
28622914 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);
28652918 const obj_copy = tree_copy.root.Object;
28662919
28672920 for ([_][]const u8{ "noescape", "simple", "unicode", "surrogatepair" }) |field_name| {
......@@ -3376,14 +3429,12 @@ test "stringify null optional fields" {
33763429 StringifyOptions{ .emit_null_optional_fields = false },
33773430 );
33783431
3379 try std.testing.expect(try parsesTo(
3380 MyStruct,
3381 MyStruct{},
3382 &TokenStream.init(
3383 \\{"required":"something","another_required":"something else"}
3384 ),
3385 .{ .allocator = std.testing.allocator },
3386 ));
3432 var ts = TokenStream.init(
3433 \\{"required":"something","another_required":"something else"}
3434 );
3435 try std.testing.expect(try parsesTo(MyStruct, MyStruct{}, &ts, .{
3436 .allocator = std.testing.allocator,
3437 }));
33873438}
33883439
33893440// 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
311311 const ReturnType = Sentinel(T, sentinel_val);
312312 switch (@typeInfo(T)) {
313313 .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),
315318 .Many, .One => return @ptrCast(ReturnType, p),
316319 .C => {},
317320 },
lib/std/net.zig+7-5
......@@ -1141,18 +1141,20 @@ fn linuxLookupNameFromHosts(
11411141 };
11421142 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();
11451146 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) {
11471148 error.StreamTooLong => blk: {
1148 // Skip to the delimiter in the stream, to fix parsing
1149 try stream.skipUntilDelimiterOrEof('\n');
1149 // Skip to the delimiter in the reader, to fix parsing
1150 try reader.skipUntilDelimiterOrEof('\n');
11501151 // Use the truncated line. A truncated comment or hostname will be handled correctly.
11511152 break :blk &line_buf;
11521153 },
11531154 else => |e| return e,
11541155 }) |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
11571159 var line_it = mem.tokenize(u8, no_comment_line, " \t");
11581160 const ip_text = line_it.next() orelse continue;
lib/std/zig/c_translation.zig+29-7
......@@ -8,10 +8,19 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
88 // this function should behave like transCCast in translate-c, except it's for macros
99 const SourceType = @TypeOf(target);
1010 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),
1216 .Optional => |dest_opt| {
13 if (@typeInfo(dest_opt.child) == .Pointer or @typeInfo(dest_opt.child) == .Fn) {
17 if (@typeInfo(dest_opt.child) == .Pointer) {
1418 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);
1524 }
1625 },
1726 .Int => {
......@@ -124,7 +133,10 @@ test "cast" {
124133 try testing.expect(cast(?*anyopaque, -1) == @intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))));
125134 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;
128140 try testing.expect(cast(FnPtr, 0) == @intToPtr(FnPtr, @as(usize, 0)));
129141 try testing.expect(cast(FnPtr, foo) == @intToPtr(FnPtr, @bitCast(usize, @as(isize, -1))));
130142}
......@@ -135,9 +147,14 @@ pub fn sizeof(target: anytype) usize {
135147 switch (@typeInfo(T)) {
136148 .Float, .Int, .Struct, .Union, .Array, .Bool, .Vector => return @sizeOf(T),
137149 .Fn => {
138 // sizeof(main) returns 1, sizeof(&main) returns pointer size.
139 // We cannot distinguish those types in Zig, so use pointer size.
140 return @sizeOf(T);
150 if (@import("builtin").zig_backend == .stage1) {
151 // sizeof(main) returns 1, sizeof(&main) returns pointer size.
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;
141158 },
142159 .Null => return @sizeOf(*anyopaque),
143160 .Void => {
......@@ -233,7 +250,12 @@ test "sizeof" {
233250 try testing.expect(sizeof(*const *const [4:0]u8) == ptr_size);
234251 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
238260 try testing.expect(sizeof(void) == 1);
239261 try testing.expect(sizeof(anyopaque) == 1);