Skip to content

Commit b2c507a

Browse files
committed
add tests for fixed stage1 bugs
Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
1 parent a1d8235 commit b2c507a

13 files changed

+308
-0
lines changed

lib/std/array_list.zig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,3 +1604,20 @@ test "std.ArrayList(u0)" {
16041604
}
16051605
try testing.expectEqual(count, 3);
16061606
}
1607+
1608+
test "std.ArrayList(?u32).popOrNull()" {
1609+
const a = testing.allocator;
1610+
1611+
var list = ArrayList(?u32).init(a);
1612+
defer list.deinit();
1613+
1614+
try list.append(null);
1615+
try list.append(1);
1616+
try list.append(2);
1617+
try testing.expectEqual(list.items.len, 3);
1618+
1619+
try testing.expect(list.popOrNull().? == @as(u32, 2));
1620+
try testing.expect(list.popOrNull().? == @as(u32, 1));
1621+
try testing.expect(list.popOrNull().? == null);
1622+
try testing.expect(list.popOrNull() == null);
1623+
}

test/behavior/cast.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,3 +1518,13 @@ test "bitcast packed struct with u0" {
15181518
const i = @bitCast(u2, s);
15191519
try expect(i == 2);
15201520
}
1521+
1522+
test "optional pointer coerced to optional allowzero pointer" {
1523+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1524+
1525+
var p: ?*u32 = undefined;
1526+
var q: ?*allowzero u32 = undefined;
1527+
p = @intToPtr(*u32, 4);
1528+
q = p;
1529+
try expect(@ptrToInt(q.?) == 4);
1530+
}

test/behavior/eval.zig

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,3 +1547,59 @@ test "comptime function turns function value to function pointer" {
15471547
};
15481548
comptime try expect(S.foo[0] == &S.Nil);
15491549
}
1550+
1551+
test "container level const and var have unique addresses" {
1552+
const S = struct {
1553+
x: i32,
1554+
y: i32,
1555+
const c = @This(){ .x = 1, .y = 1 };
1556+
var v: @This() = c;
1557+
};
1558+
var p = &S.c;
1559+
try std.testing.expect(p.x == S.c.x);
1560+
S.v.x = 2;
1561+
try std.testing.expect(p.x == S.c.x);
1562+
}
1563+
1564+
test "break from block results in type" {
1565+
const S = struct {
1566+
fn NewType(comptime T: type) type {
1567+
const Padded = blk: {
1568+
if (@sizeOf(T) <= @sizeOf(usize)) break :blk void;
1569+
break :blk T;
1570+
};
1571+
1572+
return Padded;
1573+
}
1574+
};
1575+
const T = S.NewType(usize);
1576+
try expect(T == void);
1577+
}
1578+
1579+
test "struct in comptime false branch is not evaluated" {
1580+
const S = struct {
1581+
const comptime_const = 2;
1582+
fn some(comptime V: type) type {
1583+
return switch (comptime_const) {
1584+
3 => struct { a: V.foo },
1585+
2 => V,
1586+
else => unreachable,
1587+
};
1588+
}
1589+
};
1590+
try expect(S.some(u32) == u32);
1591+
}
1592+
1593+
test "result of nested switch assigned to variable" {
1594+
var zds: u32 = 0;
1595+
zds = switch (zds) {
1596+
0 => switch (zds) {
1597+
0...0 => 1234,
1598+
1...1 => zds,
1599+
2 => zds,
1600+
else => return,
1601+
},
1602+
else => zds,
1603+
};
1604+
try expect(zds == 1234);
1605+
}

test/behavior/for.zig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,25 @@ test "else continue outer for" {
227227
} else continue;
228228
}
229229
}
230+
231+
test "for loop with else branch" {
232+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
233+
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
234+
235+
{
236+
var x = [_]u32{ 1, 2 };
237+
const q = for (x) |y| {
238+
if ((y & 1) != 0) continue;
239+
break y * 2;
240+
} else @as(u32, 1);
241+
try expect(q == 4);
242+
}
243+
{
244+
var x = [_]u32{ 1, 2 };
245+
const q = for (x) |y| {
246+
if ((y & 1) != 0) continue;
247+
break y * 2;
248+
} else @panic("");
249+
try expect(q == 4);
250+
}
251+
}

test/behavior/optional.zig

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,3 +448,42 @@ test "Optional slice size is optimized" {
448448
a = "hello";
449449
try expectEqualStrings(a.?, "hello");
450450
}
451+
452+
test "peer type resolution in nested if expressions" {
453+
const Thing = struct { n: i32 };
454+
var a = false;
455+
var b = false;
456+
457+
var result1 = if (a)
458+
Thing{ .n = 1 }
459+
else
460+
null;
461+
try expect(result1 == null);
462+
try expect(@TypeOf(result1) == ?Thing);
463+
464+
var result2 = if (a)
465+
Thing{ .n = 0 }
466+
else if (b)
467+
Thing{ .n = 1 }
468+
else
469+
null;
470+
try expect(result2 == null);
471+
try expect(@TypeOf(result2) == ?Thing);
472+
}
473+
474+
test "cast slice to const slice nested in error union and optional" {
475+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
476+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
477+
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
478+
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
479+
480+
const S = struct {
481+
fn inner() !?[]u8 {
482+
return error.Foo;
483+
}
484+
fn outer() !?[]const u8 {
485+
return inner();
486+
}
487+
};
488+
try std.testing.expectError(error.Foo, S.outer());
489+
}

test/behavior/ptrcast.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,15 @@ test "comptime @ptrCast a subset of an array, then write through it" {
270270
std.mem.copy(u8, buff[4..], "abcdef");
271271
}
272272
}
273+
274+
test "@ptrCast undefined value at comptime" {
275+
const S = struct {
276+
fn transmute(comptime T: type, comptime U: type, value: T) U {
277+
return @ptrCast(*const U, &value).*;
278+
}
279+
};
280+
comptime {
281+
var x = S.transmute([]u8, i32, undefined);
282+
_ = x;
283+
}
284+
}

test/behavior/slice.zig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,3 +706,24 @@ test "global slice field access" {
706706
S.slice.len -= 2;
707707
try expectEqualStrings("trin", S.slice);
708708
}
709+
710+
test "slice of void" {
711+
var n: usize = 10;
712+
var arr: [12]void = undefined;
713+
const slice = @as([]void, &arr)[0..n];
714+
try expect(slice.len == n);
715+
}
716+
717+
test "slice with dereferenced value" {
718+
var a: usize = 0;
719+
var idx: *usize = &a;
720+
_ = blk: {
721+
var array = [_]u8{};
722+
break :blk array[idx.*..];
723+
};
724+
const res = blk: {
725+
var array = [_]u8{};
726+
break :blk array[idx.*..];
727+
};
728+
try expect(res.len == 0);
729+
}

test/behavior/struct.zig

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,3 +1458,40 @@ test "struct has only one reference" {
14581458
try expectEqual(@sizeOf(struct { x: u16 }), S.optionalComptimeIntParam(@sizeOf(struct { x: u16 })));
14591459
try expectEqual(@sizeOf(struct { x: u32 }), S.errorUnionComptimeIntParam(@sizeOf(struct { x: u32 })));
14601460
}
1461+
1462+
test "no dependency loop on pointer to optional struct" {
1463+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1464+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1465+
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1466+
1467+
const S = struct {
1468+
const A = struct { b: B };
1469+
const B = struct { a: *?A };
1470+
};
1471+
var a1: ?S.A = null;
1472+
var a2: ?S.A = .{ .b = .{ .a = &a1 } };
1473+
a1 = .{ .b = .{ .a = &a2 } };
1474+
1475+
try expect(a1.?.b.a == &a2);
1476+
try expect(a2.?.b.a == &a1);
1477+
}
1478+
1479+
test "discarded struct initialization works as expected" {
1480+
const S = struct { a: u32 };
1481+
_ = S{ .a = 1 };
1482+
}
1483+
1484+
test "function pointer in struct returns the struct" {
1485+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1486+
1487+
const A = struct {
1488+
const A = @This();
1489+
f: *const fn () A,
1490+
1491+
fn f() A {
1492+
return .{ .f = f };
1493+
}
1494+
};
1495+
var a = A.f();
1496+
try expect(a.f == A.f);
1497+
}

test/behavior/tuple.zig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const builtin = @import("builtin");
22
const std = @import("std");
33
const testing = std.testing;
44
const expect = testing.expect;
5+
const expectEqualStrings = std.testing.expectEqualStrings;
56

67
test "tuple concatenation" {
78
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
@@ -340,3 +341,28 @@ test "tuple type with void field and a runtime field" {
340341
var t: T = .{ 5, {} };
341342
try expect(t[0] == 5);
342343
}
344+
345+
test "branching inside tuple literal" {
346+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
347+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
348+
349+
const S = struct {
350+
fn foo(a: anytype) !void {
351+
try expect(a[0] == 1234);
352+
}
353+
};
354+
var a = false;
355+
try S.foo(.{if (a) @as(u32, 5678) else @as(u32, 1234)});
356+
}
357+
358+
test "tuple initialized with a runtime known value" {
359+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
360+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
361+
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
362+
363+
const E = union(enum) { e: []const u8 };
364+
const W = union(enum) { w: E };
365+
var e = E{ .e = "test" };
366+
const w = .{W{ .w = e }};
367+
try expectEqualStrings(w[0].w.e, "test");
368+
}

test/behavior/union.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,3 +1471,21 @@ test "union int tag type is properly managed" {
14711471
};
14721472
try expect(@sizeOf(Bar) + 1 == 3);
14731473
}
1474+
1475+
test "no dependency loop when function pointer in union returns the union" {
1476+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1477+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1478+
1479+
const U = union(enum) {
1480+
const U = @This();
1481+
a: u8,
1482+
b: *const fn (x: U) void,
1483+
c: *const fn (x: U) U,
1484+
d: *const fn (x: u8) U,
1485+
fn foo(x: u8) U {
1486+
return .{ .a = x };
1487+
}
1488+
};
1489+
var b: U = .{ .d = U.foo };
1490+
try expect(b.d(2).a == 2);
1491+
}

test/cases/compile_errors/control_flow_uses_comptime_var_at_runtime.zig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,35 @@ export fn foo() void {
66
}
77

88
fn bar() void { }
9+
export fn baz() void {
10+
comptime var idx: u32 = 0;
11+
while (idx < 1) {
12+
const not_null: ?u32 = 1;
13+
_ = not_null orelse return;
14+
idx += 1;
15+
}
16+
}
17+
18+
export fn qux() void {
19+
comptime var i = 0;
20+
while (i < 3) : (i += 1) {
21+
const T = switch (i) {
22+
0 => f32,
23+
1 => i8,
24+
2 => bool,
25+
else => unreachable,
26+
};
27+
_ = T;
28+
}
29+
}
930

1031
// error
1132
// backend=stage2
1233
// target=native
1334
//
1435
// :3:24: error: cannot store to comptime variable in non-inline loop
1536
// :3:5: note: non-inline loop here
37+
// :14:13: error: cannot store to comptime variable in non-inline loop
38+
// :11:5: note: non-inline loop here
39+
// :20:24: error: cannot store to comptime variable in non-inline loop
40+
// :20:5: note: non-inline loop here

test/cases/compile_errors/reference_to_const_data.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ export fn qux() void {
1818
var ptr = &S{.x=1,.y=2};
1919
ptr.x = 2;
2020
}
21+
export fn quux() void {
22+
var x = &@returnAddress();
23+
x.* = 6;
24+
}
2125

2226
// error
2327
// backend=stage2
@@ -27,3 +31,4 @@ export fn qux() void {
2731
// :7:8: error: cannot assign to constant
2832
// :11:8: error: cannot assign to constant
2933
// :19:8: error: cannot assign to constant
34+
// :23:6: error: cannot assign to constant
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
fn A(comptime T: type) type {
2+
return struct { a: T };
3+
}
4+
fn B(comptime T: type) type {
5+
return struct { b: T };
6+
}
7+
fn foo() A(u32) {
8+
return B(u32){ .b = 1 };
9+
}
10+
export fn entry() void {
11+
_ = foo();
12+
}
13+
14+
// error
15+
// backend=stage2
16+
// target=native
17+
//
18+
// :8:18: error: expected type 'tmp.A(u32)', found 'tmp.B(u32)'
19+
// :5:12: note: struct declared here
20+
// :2:12: note: struct declared here

0 commit comments

Comments
 (0)