authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-31 14:28:21+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-31 20:49:02-05:00
log58c1d98c1463210135ab7f405d204b0769525328
treef174445e9c623e4d367f65f05aaa1ee71fe2d0c4
parent1c711b0a64a7bd13e5be80dfc107cba9cc9bedc4

add tests for fixed stage1 bugs

Closes #4144 Closes #4255 Closes #4372 Closes #4375 Closes #4380 Closes #4417 Closes #4423 Closes #4476 Closes #4528 Closes #4562 Closes #4572 Closes #4597 Closes #4639 Closes #4672 Closes #4782 Closes #4955 Closes #4984 Closes #4997 Closes #5010 Closes #5114 Closes #5166 Closes #5173 Closes #5276

14 files changed, 283 insertions(+), 6 deletions(-)

lib/std/fmt.zig+18
...@@ -2773,3 +2773,21 @@ test "runtime precision specifier" {...@@ -2773,3 +2773,21 @@ test "runtime precision specifier" {
2773 try expectFmt("3.14e+00", "{:1.[1]}", .{ number, precision });2773 try expectFmt("3.14e+00", "{:1.[1]}", .{ number, precision });
2774 try expectFmt("3.14e+00", "{:1.[precision]}", .{ .number = number, .precision = precision });2774 try expectFmt("3.14e+00", "{:1.[precision]}", .{ .number = number, .precision = precision });
2775}2775}
2776
2777test "recursive format function" {
2778 const R = union(enum) {
2779 const R = @This();
2780 Leaf: i32,
2781 Branch: struct { left: *const R, right: *const R },
2782
2783 pub fn format(self: R, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
2784 return switch (self) {
2785 .Leaf => |n| std.fmt.format(writer, "Leaf({})", .{n}),
2786 .Branch => |b| std.fmt.format(writer, "Branch({}, {})", .{ b.left, b.right }),
2787 };
2788 }
2789 };
2790
2791 var r = R{ .Leaf = 1 };
2792 try expectFmt("Leaf(1)\n", "{}\n", .{&r});
2793}
lib/std/io/fixed_buffer_stream.zig+11
...@@ -132,6 +132,17 @@ test "FixedBufferStream output" {...@@ -132,6 +132,17 @@ test "FixedBufferStream output" {
132 try testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten());132 try testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten());
133}133}
134134
135test "FixedBufferStream output at comptime" {
136 comptime {
137 var buf: [255]u8 = undefined;
138 var fbs = fixedBufferStream(&buf);
139 const stream = fbs.writer();
140
141 try stream.print("{s}{s}!", .{ "Hello", "World" });
142 try testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten());
143 }
144}
145
135test "FixedBufferStream output 2" {146test "FixedBufferStream output 2" {
136 var buffer: [10]u8 = undefined;147 var buffer: [10]u8 = undefined;
137 var fbs = fixedBufferStream(&buffer);148 var fbs = fixedBufferStream(&buffer);
test/behavior/array.zig+8
...@@ -654,3 +654,11 @@ test "array init of container level array variable" {...@@ -654,3 +654,11 @@ test "array init of container level array variable" {
654 S.bar(5, 6);654 S.bar(5, 6);
655 try expectEqual([2]usize{ 5, 6 }, S.pair);655 try expectEqual([2]usize{ 5, 6 }, S.pair);
656}656}
657
658test "runtime initialized sentinel-terminated array literal" {
659 var c: u16 = 300;
660 const f = &[_:0x9999]u16{c};
661 const g = @ptrCast(*[4]u8, f);
662 try std.testing.expect(g[2] == 0x99);
663 try std.testing.expect(g[3] == 0x99);
664}
test/behavior/call.zig+17
...@@ -394,3 +394,20 @@ test "recursive inline call with comptime known argument" {...@@ -394,3 +394,20 @@ test "recursive inline call with comptime known argument" {
394394
395 try expect(S.foo(4) == 20);395 try expect(S.foo(4) == 20);
396}396}
397
398test "inline while with @call" {
399 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
400 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
401
402 const S = struct {
403 fn inc(a: *u32) void {
404 a.* += 1;
405 }
406 };
407 var a: u32 = 0;
408 comptime var i = 0;
409 inline while (i < 10) : (i += 1) {
410 @call(.auto, S.inc, .{&a});
411 }
412 try expect(a == 10);
413}
test/behavior/cast.zig+16
...@@ -1528,3 +1528,19 @@ test "optional pointer coerced to optional allowzero pointer" {...@@ -1528,3 +1528,19 @@ test "optional pointer coerced to optional allowzero pointer" {
1528 q = p;1528 q = p;
1529 try expect(@ptrToInt(q.?) == 4);1529 try expect(@ptrToInt(q.?) == 4);
1530}1530}
1531
1532test "ptrToInt on const inside comptime block" {
1533 var a = comptime blk: {
1534 const b: u8 = 1;
1535 const c = @ptrToInt(&b);
1536 break :blk c;
1537 };
1538 try expect(@intToPtr(*const u8, a).* == 1);
1539}
1540
1541test "single item pointer to pointer to array to slice" {
1542 var x: i32 = 1234;
1543 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);
1544 const z1 = @as([]const i32, @as(*[1]i32, &x));
1545 try expect(z1[0] == 1234);
1546}
test/behavior/eval.zig+35
...@@ -1621,3 +1621,38 @@ test "inline for loop of functions returning error unions" {...@@ -1621,3 +1621,38 @@ test "inline for loop of functions returning error unions" {
1621 }1621 }
1622 try expect(a == 3);1622 try expect(a == 3);
1623}1623}
1624
1625test "if inside a switch" {
1626 var condition = true;
1627 var wave_type: u32 = 0;
1628 var sample: i32 = switch (wave_type) {
1629 0 => if (condition) 2 else 3,
1630 1 => 100,
1631 2 => 200,
1632 3 => 300,
1633 else => unreachable,
1634 };
1635 try expect(sample == 2);
1636}
1637
1638test "function has correct return type when previous return is casted to smaller type" {
1639 const S = struct {
1640 fn foo(b: bool) u16 {
1641 if (b) return @as(u8, 0xFF);
1642 return 0xFFFF;
1643 }
1644 };
1645 try expect(S.foo(true) == 0xFF);
1646}
1647
1648test "early exit in container level const" {
1649 const S = struct {
1650 const value = blk: {
1651 if (true) {
1652 break :blk @as(u32, 1);
1653 }
1654 break :blk @as(u32, 0);
1655 };
1656 };
1657 try expect(S.value == 1);
1658}
test/behavior/fn.zig+33
...@@ -484,3 +484,36 @@ test "using @ptrCast on function pointers" {...@@ -484,3 +484,36 @@ test "using @ptrCast on function pointers" {
484 // https://github.com/ziglang/zig/issues/2626484 // https://github.com/ziglang/zig/issues/2626
485 // try comptime S.run();485 // try comptime S.run();
486}486}
487
488test "function returns function returning type" {
489 const S = struct {
490 fn a() fn () type {
491 return (struct {
492 fn b() type {
493 return u32;
494 }
495 }).b;
496 }
497 };
498 try expect(S.a()() == u32);
499}
500
501test "peer type resolution of inferred error set with non-void payload" {
502 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
503
504 const S = struct {
505 fn openDataFile(mode: enum { read, write }) !u32 {
506 return switch (mode) {
507 .read => foo(),
508 .write => bar(),
509 };
510 }
511 fn foo() error{ a, b }!u32 {
512 return 1;
513 }
514 fn bar() error{ c, d }!u32 {
515 return 2;
516 }
517 };
518 try expect(try S.openDataFile(.read) == 1);
519}
test/behavior/packed-struct.zig+11
...@@ -588,3 +588,14 @@ test "overaligned pointer to packed struct" {...@@ -588,3 +588,14 @@ test "overaligned pointer to packed struct" {
588 },588 },
589 }589 }
590}590}
591
592test "packed struct initialized in bitcast" {
593 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
594 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
595 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
596
597 const T = packed struct { val: u8 };
598 var val: u8 = 123;
599 const t = @bitCast(u8, T{ .val = val });
600 try expect(t == val);
601}
test/behavior/slice.zig+10
...@@ -737,3 +737,13 @@ test "empty slice ptr is non null" {...@@ -737,3 +737,13 @@ test "empty slice ptr is non null" {
737 const t = @ptrCast([*]i8, p);737 const t = @ptrCast([*]i8, p);
738 try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr));738 try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr));
739}739}
740
741test "slice decays to many pointer" {
742 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
743 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
744 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
745
746 var buf: [8]u8 = "abcdefg\x00".*;
747 const p: [*:0]const u8 = buf[0..7 :0];
748 try expectEqualStrings(buf[0..7], std.mem.span(p));
749}
test/behavior/struct.zig+60
...@@ -1495,3 +1495,63 @@ test "function pointer in struct returns the struct" {...@@ -1495,3 +1495,63 @@ test "function pointer in struct returns the struct" {
1495 var a = A.f();1495 var a = A.f();
1496 try expect(a.f == A.f);1496 try expect(a.f == A.f);
1497}1497}
1498
1499test "no dependency loop on optional field wrapped in generic function" {
1500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1501
1502 const S = struct {
1503 fn Atomic(comptime T: type) type {
1504 return T;
1505 }
1506 const A = struct { b: Atomic(?*B) };
1507 const B = struct { a: ?*A };
1508 };
1509 var a: S.A = .{ .b = null };
1510 var b: S.B = .{ .a = &a };
1511 a.b = &b;
1512
1513 try expect(a.b == &b);
1514 try expect(b.a == &a);
1515}
1516
1517test "optional field init with tuple" {
1518 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1519 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1520 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1521
1522 const S = struct {
1523 a: ?struct { b: u32 },
1524 };
1525 var a: u32 = 0;
1526 var b = S{
1527 .a = .{ .b = a },
1528 };
1529 try expect(b.a.?.b == a);
1530}
1531
1532test "if inside struct init inside if" {
1533 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1534
1535 const MyStruct = struct { x: u32 };
1536 const b: u32 = 5;
1537 var i: u32 = 1;
1538 var my_var = if (i < 5)
1539 MyStruct{
1540 .x = 1 + if (i > 0) b else 0,
1541 }
1542 else
1543 MyStruct{
1544 .x = 1 + if (i > 0) b else 0,
1545 };
1546 try expect(my_var.x == 6);
1547}
1548
1549test "optional generic function label struct field" {
1550 const Options = struct {
1551 isFoo: ?fn (type) u8 = defaultIsFoo,
1552 fn defaultIsFoo(comptime _: type) u8 {
1553 return 123;
1554 }
1555 };
1556 try expect((Options{}).isFoo.?(u8) == 123);
1557}
test/behavior/translate_c_macros.zig+4
...@@ -221,3 +221,7 @@ test "Macro that uses remainder operator. Issue #13346" {...@@ -221,3 +221,7 @@ test "Macro that uses remainder operator. Issue #13346" {
221 ),221 ),
222 );222 );
223}223}
224
225test "@typeInfo on @cImport result" {
226 try expect(@typeInfo(h).Struct.decls.len > 1);
227}
test/behavior/tuple.zig+37-6
...@@ -3,6 +3,7 @@ const std = @import("std");...@@ -3,6 +3,7 @@ const std = @import("std");
3const testing = std.testing;3const testing = std.testing;
4const expect = testing.expect;4const expect = testing.expect;
5const expectEqualStrings = std.testing.expectEqualStrings;5const expectEqualStrings = std.testing.expectEqualStrings;
6const expectEqual = std.testing.expectEqual;
67
7test "tuple concatenation" {8test "tuple concatenation" {
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -233,31 +234,31 @@ test "fieldParentPtr of anon struct" {...@@ -233,31 +234,31 @@ test "fieldParentPtr of anon struct" {
233test "offsetOf tuple" {234test "offsetOf tuple" {
234 var x: u32 = 0;235 var x: u32 = 0;
235 const T = @TypeOf(.{ x, x });236 const T = @TypeOf(.{ x, x });
236 _ = @offsetOf(T, "1");237 try expect(@offsetOf(T, "1") == @sizeOf(u32));
237}238}
238239
239test "offsetOf anon struct" {240test "offsetOf anon struct" {
240 var x: u32 = 0;241 var x: u32 = 0;
241 const T = @TypeOf(.{ .foo = x, .bar = x });242 const T = @TypeOf(.{ .foo = x, .bar = x });
242 _ = @offsetOf(T, "bar");243 try expect(@offsetOf(T, "bar") == @sizeOf(u32));
243}244}
244245
245test "initializing tuple with mixed comptime-runtime fields" {246test "initializing tuple with mixed comptime-runtime fields" {
246 if (true) return error.SkipZigTest; // TODO247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
247248
248 var x: u32 = 15;249 var x: u32 = 15;
249 const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x });250 const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x });
250 var a: T = .{ -1234, 5678, x + 1 };251 var a: T = .{ -1234, 5678, x + 1 };
251 _ = a;252 try expect(a[2] == 16);
252}253}
253254
254test "initializing anon struct with mixed comptime-runtime fields" {255test "initializing anon struct with mixed comptime-runtime fields" {
255 if (true) return error.SkipZigTest; // TODO256 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
256257
257 var x: u32 = 15;258 var x: u32 = 15;
258 const T = @TypeOf(.{ .foo = @as(i32, -1234), .bar = x });259 const T = @TypeOf(.{ .foo = @as(i32, -1234), .bar = x });
259 var a: T = .{ .foo = -1234, .bar = x + 1 };260 var a: T = .{ .foo = -1234, .bar = x + 1 };
260 _ = a;261 try expect(a.bar == 16);
261}262}
262263
263test "tuple in tuple passed to generic function" {264test "tuple in tuple passed to generic function" {
...@@ -366,3 +367,33 @@ test "tuple initialized with a runtime known value" {...@@ -366,3 +367,33 @@ test "tuple initialized with a runtime known value" {
366 const w = .{W{ .w = e }};367 const w = .{W{ .w = e }};
367 try expectEqualStrings(w[0].w.e, "test");368 try expectEqualStrings(w[0].w.e, "test");
368}369}
370
371test "tuple of struct concatenation and coercion to array" {
372 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
373 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
374 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
375 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
376
377 const StructWithDefault = struct { value: f32 = 42 };
378 const SomeStruct = struct { array: [4]StructWithDefault };
379
380 const value1 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{.{}} ** 3 };
381 const value2 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{.{}} ** 3 };
382
383 try expectEqual(value1, value2);
384}
385
386test "nested runtime conditionals in tuple initializer" {
387 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
388 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
389 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
390
391 var data: u8 = 0;
392 const x = .{
393 if (data != 0) "" else switch (@truncate(u1, data)) {
394 0 => "up",
395 1 => "down",
396 },
397 };
398 try expectEqualStrings("up", x[0]);
399}
test/behavior/union.zig+2
...@@ -1482,6 +1482,8 @@ test "no dependency loop when function pointer in union returns the union" {...@@ -1482,6 +1482,8 @@ test "no dependency loop when function pointer in union returns the union" {
1482 b: *const fn (x: U) void,1482 b: *const fn (x: U) void,
1483 c: *const fn (x: U) U,1483 c: *const fn (x: U) U,
1484 d: *const fn (x: u8) U,1484 d: *const fn (x: u8) U,
1485 e: *const fn (x: *U) void,
1486 f: *const fn (x: *U) U,
1485 fn foo(x: u8) U {1487 fn foo(x: u8) U {
1486 return .{ .a = x };1488 return .{ .a = x };
1487 }1489 }
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig+21
...@@ -53,6 +53,21 @@ export fn foo_slice() void {...@@ -53,6 +53,21 @@ export fn foo_slice() void {
53 _ = slice;53 _ = slice;
54 }54 }
55}55}
56export fn undefined_slice() void {
57 const arr: [100]u16 = undefined;
58 const slice = arr[0..12 :0];
59 _ = slice;
60}
61export fn string_slice() void {
62 const str = "abcdefg";
63 const slice = str[0..1 :12];
64 _ = slice;
65}
66export fn typeName_slice() void {
67 const arr = @typeName(usize);
68 const slice = arr[0..2 :0];
69 _ = slice;
70}
5671
57// error72// error
58// backend=stage273// backend=stage2
...@@ -72,3 +87,9 @@ export fn foo_slice() void {...@@ -72,3 +87,9 @@ export fn foo_slice() void {
72// :44:29: note: expected '255', found '0'87// :44:29: note: expected '255', found '0'
73// :52:29: error: value in memory does not match slice sentinel88// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '255', found '0'89// :52:29: note: expected '255', found '0'
90// :58:22: error: value in memory does not match slice sentinel
91// :58:22: note: expected '0', found 'undefined'
92// :63:22: error: value in memory does not match slice sentinel
93// :63:22: note: expected '12', found '98'
94// :68:22: error: value in memory does not match slice sentinel
95// :68:22: note: expected '0', found '105'