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
This commit is contained in:
parent
1c711b0a64
commit
58c1d98c14
|
@ -2773,3 +2773,21 @@ test "runtime precision specifier" {
|
|||
try expectFmt("3.14e+00", "{:1.[1]}", .{ number, precision });
|
||||
try expectFmt("3.14e+00", "{:1.[precision]}", .{ .number = number, .precision = precision });
|
||||
}
|
||||
|
||||
test "recursive format function" {
|
||||
const R = union(enum) {
|
||||
const R = @This();
|
||||
Leaf: i32,
|
||||
Branch: struct { left: *const R, right: *const R },
|
||||
|
||||
pub fn format(self: R, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
return switch (self) {
|
||||
.Leaf => |n| std.fmt.format(writer, "Leaf({})", .{n}),
|
||||
.Branch => |b| std.fmt.format(writer, "Branch({}, {})", .{ b.left, b.right }),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var r = R{ .Leaf = 1 };
|
||||
try expectFmt("Leaf(1)\n", "{}\n", .{&r});
|
||||
}
|
||||
|
|
|
@ -132,6 +132,17 @@ test "FixedBufferStream output" {
|
|||
try testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten());
|
||||
}
|
||||
|
||||
test "FixedBufferStream output at comptime" {
|
||||
comptime {
|
||||
var buf: [255]u8 = undefined;
|
||||
var fbs = fixedBufferStream(&buf);
|
||||
const stream = fbs.writer();
|
||||
|
||||
try stream.print("{s}{s}!", .{ "Hello", "World" });
|
||||
try testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten());
|
||||
}
|
||||
}
|
||||
|
||||
test "FixedBufferStream output 2" {
|
||||
var buffer: [10]u8 = undefined;
|
||||
var fbs = fixedBufferStream(&buffer);
|
||||
|
|
|
@ -654,3 +654,11 @@ test "array init of container level array variable" {
|
|||
S.bar(5, 6);
|
||||
try expectEqual([2]usize{ 5, 6 }, S.pair);
|
||||
}
|
||||
|
||||
test "runtime initialized sentinel-terminated array literal" {
|
||||
var c: u16 = 300;
|
||||
const f = &[_:0x9999]u16{c};
|
||||
const g = @ptrCast(*[4]u8, f);
|
||||
try std.testing.expect(g[2] == 0x99);
|
||||
try std.testing.expect(g[3] == 0x99);
|
||||
}
|
||||
|
|
|
@ -394,3 +394,20 @@ test "recursive inline call with comptime known argument" {
|
|||
|
||||
try expect(S.foo(4) == 20);
|
||||
}
|
||||
|
||||
test "inline while with @call" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn inc(a: *u32) void {
|
||||
a.* += 1;
|
||||
}
|
||||
};
|
||||
var a: u32 = 0;
|
||||
comptime var i = 0;
|
||||
inline while (i < 10) : (i += 1) {
|
||||
@call(.auto, S.inc, .{&a});
|
||||
}
|
||||
try expect(a == 10);
|
||||
}
|
||||
|
|
|
@ -1528,3 +1528,19 @@ test "optional pointer coerced to optional allowzero pointer" {
|
|||
q = p;
|
||||
try expect(@ptrToInt(q.?) == 4);
|
||||
}
|
||||
|
||||
test "ptrToInt on const inside comptime block" {
|
||||
var a = comptime blk: {
|
||||
const b: u8 = 1;
|
||||
const c = @ptrToInt(&b);
|
||||
break :blk c;
|
||||
};
|
||||
try expect(@intToPtr(*const u8, a).* == 1);
|
||||
}
|
||||
|
||||
test "single item pointer to pointer to array to slice" {
|
||||
var x: i32 = 1234;
|
||||
try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);
|
||||
const z1 = @as([]const i32, @as(*[1]i32, &x));
|
||||
try expect(z1[0] == 1234);
|
||||
}
|
||||
|
|
|
@ -1621,3 +1621,38 @@ test "inline for loop of functions returning error unions" {
|
|||
}
|
||||
try expect(a == 3);
|
||||
}
|
||||
|
||||
test "if inside a switch" {
|
||||
var condition = true;
|
||||
var wave_type: u32 = 0;
|
||||
var sample: i32 = switch (wave_type) {
|
||||
0 => if (condition) 2 else 3,
|
||||
1 => 100,
|
||||
2 => 200,
|
||||
3 => 300,
|
||||
else => unreachable,
|
||||
};
|
||||
try expect(sample == 2);
|
||||
}
|
||||
|
||||
test "function has correct return type when previous return is casted to smaller type" {
|
||||
const S = struct {
|
||||
fn foo(b: bool) u16 {
|
||||
if (b) return @as(u8, 0xFF);
|
||||
return 0xFFFF;
|
||||
}
|
||||
};
|
||||
try expect(S.foo(true) == 0xFF);
|
||||
}
|
||||
|
||||
test "early exit in container level const" {
|
||||
const S = struct {
|
||||
const value = blk: {
|
||||
if (true) {
|
||||
break :blk @as(u32, 1);
|
||||
}
|
||||
break :blk @as(u32, 0);
|
||||
};
|
||||
};
|
||||
try expect(S.value == 1);
|
||||
}
|
||||
|
|
|
@ -484,3 +484,36 @@ test "using @ptrCast on function pointers" {
|
|||
// https://github.com/ziglang/zig/issues/2626
|
||||
// try comptime S.run();
|
||||
}
|
||||
|
||||
test "function returns function returning type" {
|
||||
const S = struct {
|
||||
fn a() fn () type {
|
||||
return (struct {
|
||||
fn b() type {
|
||||
return u32;
|
||||
}
|
||||
}).b;
|
||||
}
|
||||
};
|
||||
try expect(S.a()() == u32);
|
||||
}
|
||||
|
||||
test "peer type resolution of inferred error set with non-void payload" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn openDataFile(mode: enum { read, write }) !u32 {
|
||||
return switch (mode) {
|
||||
.read => foo(),
|
||||
.write => bar(),
|
||||
};
|
||||
}
|
||||
fn foo() error{ a, b }!u32 {
|
||||
return 1;
|
||||
}
|
||||
fn bar() error{ c, d }!u32 {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
try expect(try S.openDataFile(.read) == 1);
|
||||
}
|
||||
|
|
|
@ -588,3 +588,14 @@ test "overaligned pointer to packed struct" {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
test "packed struct initialized in bitcast" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
|
||||
const T = packed struct { val: u8 };
|
||||
var val: u8 = 123;
|
||||
const t = @bitCast(u8, T{ .val = val });
|
||||
try expect(t == val);
|
||||
}
|
||||
|
|
|
@ -737,3 +737,13 @@ test "empty slice ptr is non null" {
|
|||
const t = @ptrCast([*]i8, p);
|
||||
try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr));
|
||||
}
|
||||
|
||||
test "slice decays to many pointer" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
|
||||
var buf: [8]u8 = "abcdefg\x00".*;
|
||||
const p: [*:0]const u8 = buf[0..7 :0];
|
||||
try expectEqualStrings(buf[0..7], std.mem.span(p));
|
||||
}
|
||||
|
|
|
@ -1495,3 +1495,63 @@ test "function pointer in struct returns the struct" {
|
|||
var a = A.f();
|
||||
try expect(a.f == A.f);
|
||||
}
|
||||
|
||||
test "no dependency loop on optional field wrapped in generic function" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn Atomic(comptime T: type) type {
|
||||
return T;
|
||||
}
|
||||
const A = struct { b: Atomic(?*B) };
|
||||
const B = struct { a: ?*A };
|
||||
};
|
||||
var a: S.A = .{ .b = null };
|
||||
var b: S.B = .{ .a = &a };
|
||||
a.b = &b;
|
||||
|
||||
try expect(a.b == &b);
|
||||
try expect(b.a == &a);
|
||||
}
|
||||
|
||||
test "optional field init with tuple" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
a: ?struct { b: u32 },
|
||||
};
|
||||
var a: u32 = 0;
|
||||
var b = S{
|
||||
.a = .{ .b = a },
|
||||
};
|
||||
try expect(b.a.?.b == a);
|
||||
}
|
||||
|
||||
test "if inside struct init inside if" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const MyStruct = struct { x: u32 };
|
||||
const b: u32 = 5;
|
||||
var i: u32 = 1;
|
||||
var my_var = if (i < 5)
|
||||
MyStruct{
|
||||
.x = 1 + if (i > 0) b else 0,
|
||||
}
|
||||
else
|
||||
MyStruct{
|
||||
.x = 1 + if (i > 0) b else 0,
|
||||
};
|
||||
try expect(my_var.x == 6);
|
||||
}
|
||||
|
||||
test "optional generic function label struct field" {
|
||||
const Options = struct {
|
||||
isFoo: ?fn (type) u8 = defaultIsFoo,
|
||||
fn defaultIsFoo(comptime _: type) u8 {
|
||||
return 123;
|
||||
}
|
||||
};
|
||||
try expect((Options{}).isFoo.?(u8) == 123);
|
||||
}
|
||||
|
|
|
@ -221,3 +221,7 @@ test "Macro that uses remainder operator. Issue #13346" {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
test "@typeInfo on @cImport result" {
|
||||
try expect(@typeInfo(h).Struct.decls.len > 1);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ const std = @import("std");
|
|||
const testing = std.testing;
|
||||
const expect = testing.expect;
|
||||
const expectEqualStrings = std.testing.expectEqualStrings;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
|
||||
test "tuple concatenation" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
@ -233,31 +234,31 @@ test "fieldParentPtr of anon struct" {
|
|||
test "offsetOf tuple" {
|
||||
var x: u32 = 0;
|
||||
const T = @TypeOf(.{ x, x });
|
||||
_ = @offsetOf(T, "1");
|
||||
try expect(@offsetOf(T, "1") == @sizeOf(u32));
|
||||
}
|
||||
|
||||
test "offsetOf anon struct" {
|
||||
var x: u32 = 0;
|
||||
const T = @TypeOf(.{ .foo = x, .bar = x });
|
||||
_ = @offsetOf(T, "bar");
|
||||
try expect(@offsetOf(T, "bar") == @sizeOf(u32));
|
||||
}
|
||||
|
||||
test "initializing tuple with mixed comptime-runtime fields" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
var x: u32 = 15;
|
||||
const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x });
|
||||
var a: T = .{ -1234, 5678, x + 1 };
|
||||
_ = a;
|
||||
try expect(a[2] == 16);
|
||||
}
|
||||
|
||||
test "initializing anon struct with mixed comptime-runtime fields" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
var x: u32 = 15;
|
||||
const T = @TypeOf(.{ .foo = @as(i32, -1234), .bar = x });
|
||||
var a: T = .{ .foo = -1234, .bar = x + 1 };
|
||||
_ = a;
|
||||
try expect(a.bar == 16);
|
||||
}
|
||||
|
||||
test "tuple in tuple passed to generic function" {
|
||||
|
@ -366,3 +367,33 @@ test "tuple initialized with a runtime known value" {
|
|||
const w = .{W{ .w = e }};
|
||||
try expectEqualStrings(w[0].w.e, "test");
|
||||
}
|
||||
|
||||
test "tuple of struct concatenation and coercion to array" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
|
||||
const StructWithDefault = struct { value: f32 = 42 };
|
||||
const SomeStruct = struct { array: [4]StructWithDefault };
|
||||
|
||||
const value1 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{.{}} ** 3 };
|
||||
const value2 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{.{}} ** 3 };
|
||||
|
||||
try expectEqual(value1, value2);
|
||||
}
|
||||
|
||||
test "nested runtime conditionals in tuple initializer" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
|
||||
var data: u8 = 0;
|
||||
const x = .{
|
||||
if (data != 0) "" else switch (@truncate(u1, data)) {
|
||||
0 => "up",
|
||||
1 => "down",
|
||||
},
|
||||
};
|
||||
try expectEqualStrings("up", x[0]);
|
||||
}
|
||||
|
|
|
@ -1482,6 +1482,8 @@ test "no dependency loop when function pointer in union returns the union" {
|
|||
b: *const fn (x: U) void,
|
||||
c: *const fn (x: U) U,
|
||||
d: *const fn (x: u8) U,
|
||||
e: *const fn (x: *U) void,
|
||||
f: *const fn (x: *U) U,
|
||||
fn foo(x: u8) U {
|
||||
return .{ .a = x };
|
||||
}
|
||||
|
|
|
@ -53,6 +53,21 @@ export fn foo_slice() void {
|
|||
_ = slice;
|
||||
}
|
||||
}
|
||||
export fn undefined_slice() void {
|
||||
const arr: [100]u16 = undefined;
|
||||
const slice = arr[0..12 :0];
|
||||
_ = slice;
|
||||
}
|
||||
export fn string_slice() void {
|
||||
const str = "abcdefg";
|
||||
const slice = str[0..1 :12];
|
||||
_ = slice;
|
||||
}
|
||||
export fn typeName_slice() void {
|
||||
const arr = @typeName(usize);
|
||||
const slice = arr[0..2 :0];
|
||||
_ = slice;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
|
@ -72,3 +87,9 @@ export fn foo_slice() void {
|
|||
// :44:29: note: expected '255', found '0'
|
||||
// :52:29: error: value in memory does not match slice sentinel
|
||||
// :52:29: note: expected '255', found '0'
|
||||
// :58:22: error: value in memory does not match slice sentinel
|
||||
// :58:22: note: expected '0', found 'undefined'
|
||||
// :63:22: error: value in memory does not match slice sentinel
|
||||
// :63:22: note: expected '12', found '98'
|
||||
// :68:22: error: value in memory does not match slice sentinel
|
||||
// :68:22: note: expected '0', found '105'
|
||||
|
|
Loading…
Reference in New Issue
Block a user