mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
add tests for fixed stage1 bugs
Closes #1957 Closes #1994 Closes #2140 Closes #2746 Closes #2802 Closes #2855 Closes #2895 Closes #2981 Closes #3054 Closes #3158 Closes #3234 Closes #3259 Closes #3371 Closes #3376 Closes #3387 Closes #3529 Closes #3653 Closes #3750 Closes #3778 Closes #3882 Closes #3915 Closes #3929 Closes #3961 Closes #3988 Closes #4123 Closes #7448
This commit is contained in:
parent
7350f0d9b5
commit
9a0c593a54
@ -1604,3 +1604,20 @@ test "std.ArrayList(u0)" {
|
||||
}
|
||||
try testing.expectEqual(count, 3);
|
||||
}
|
||||
|
||||
test "std.ArrayList(?u32).popOrNull()" {
|
||||
const a = testing.allocator;
|
||||
|
||||
var list = ArrayList(?u32).init(a);
|
||||
defer list.deinit();
|
||||
|
||||
try list.append(null);
|
||||
try list.append(1);
|
||||
try list.append(2);
|
||||
try testing.expectEqual(list.items.len, 3);
|
||||
|
||||
try testing.expect(list.popOrNull().? == @as(u32, 2));
|
||||
try testing.expect(list.popOrNull().? == @as(u32, 1));
|
||||
try testing.expect(list.popOrNull().? == null);
|
||||
try testing.expect(list.popOrNull() == null);
|
||||
}
|
||||
|
||||
@ -1518,3 +1518,13 @@ test "bitcast packed struct with u0" {
|
||||
const i = @bitCast(u2, s);
|
||||
try expect(i == 2);
|
||||
}
|
||||
|
||||
test "optional pointer coerced to optional allowzero pointer" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var p: ?*u32 = undefined;
|
||||
var q: ?*allowzero u32 = undefined;
|
||||
p = @intToPtr(*u32, 4);
|
||||
q = p;
|
||||
try expect(@ptrToInt(q.?) == 4);
|
||||
}
|
||||
|
||||
@ -1547,3 +1547,77 @@ test "comptime function turns function value to function pointer" {
|
||||
};
|
||||
comptime try expect(S.foo[0] == &S.Nil);
|
||||
}
|
||||
|
||||
test "container level const and var have unique addresses" {
|
||||
const S = struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
const c = @This(){ .x = 1, .y = 1 };
|
||||
var v: @This() = c;
|
||||
};
|
||||
var p = &S.c;
|
||||
try std.testing.expect(p.x == S.c.x);
|
||||
S.v.x = 2;
|
||||
try std.testing.expect(p.x == S.c.x);
|
||||
}
|
||||
|
||||
test "break from block results in type" {
|
||||
const S = struct {
|
||||
fn NewType(comptime T: type) type {
|
||||
const Padded = blk: {
|
||||
if (@sizeOf(T) <= @sizeOf(usize)) break :blk void;
|
||||
break :blk T;
|
||||
};
|
||||
|
||||
return Padded;
|
||||
}
|
||||
};
|
||||
const T = S.NewType(usize);
|
||||
try expect(T == void);
|
||||
}
|
||||
|
||||
test "struct in comptime false branch is not evaluated" {
|
||||
const S = struct {
|
||||
const comptime_const = 2;
|
||||
fn some(comptime V: type) type {
|
||||
return switch (comptime_const) {
|
||||
3 => struct { a: V.foo },
|
||||
2 => V,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
try expect(S.some(u32) == u32);
|
||||
}
|
||||
|
||||
test "result of nested switch assigned to variable" {
|
||||
var zds: u32 = 0;
|
||||
zds = switch (zds) {
|
||||
0 => switch (zds) {
|
||||
0...0 => 1234,
|
||||
1...1 => zds,
|
||||
2 => zds,
|
||||
else => return,
|
||||
},
|
||||
else => zds,
|
||||
};
|
||||
try expect(zds == 1234);
|
||||
}
|
||||
|
||||
test "inline for loop of functions returning error unions" {
|
||||
const T1 = struct {
|
||||
fn v() error{}!usize {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
const T2 = struct {
|
||||
fn v() error{Error}!usize {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
var a: usize = 0;
|
||||
inline for (.{ T1, T2 }) |T| {
|
||||
a += try T.v();
|
||||
}
|
||||
try expect(a == 3);
|
||||
}
|
||||
|
||||
@ -227,3 +227,25 @@ test "else continue outer for" {
|
||||
} else continue;
|
||||
}
|
||||
}
|
||||
|
||||
test "for loop with else branch" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
{
|
||||
var x = [_]u32{ 1, 2 };
|
||||
const q = for (x) |y| {
|
||||
if ((y & 1) != 0) continue;
|
||||
break y * 2;
|
||||
} else @as(u32, 1);
|
||||
try expect(q == 4);
|
||||
}
|
||||
{
|
||||
var x = [_]u32{ 1, 2 };
|
||||
const q = for (x) |y| {
|
||||
if ((y & 1) != 0) continue;
|
||||
break y * 2;
|
||||
} else @panic("");
|
||||
try expect(q == 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,3 +448,46 @@ test "Optional slice size is optimized" {
|
||||
a = "hello";
|
||||
try expectEqualStrings(a.?, "hello");
|
||||
}
|
||||
|
||||
test "peer type resolution in nested if expressions" {
|
||||
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;
|
||||
|
||||
const Thing = struct { n: i32 };
|
||||
var a = false;
|
||||
var b = false;
|
||||
|
||||
var result1 = if (a)
|
||||
Thing{ .n = 1 }
|
||||
else
|
||||
null;
|
||||
try expect(result1 == null);
|
||||
try expect(@TypeOf(result1) == ?Thing);
|
||||
|
||||
var result2 = if (a)
|
||||
Thing{ .n = 0 }
|
||||
else if (b)
|
||||
Thing{ .n = 1 }
|
||||
else
|
||||
null;
|
||||
try expect(result2 == null);
|
||||
try expect(@TypeOf(result2) == ?Thing);
|
||||
}
|
||||
|
||||
test "cast slice to const slice nested in error union and optional" {
|
||||
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 S = struct {
|
||||
fn inner() !?[]u8 {
|
||||
return error.Foo;
|
||||
}
|
||||
fn outer() !?[]const u8 {
|
||||
return inner();
|
||||
}
|
||||
};
|
||||
try std.testing.expectError(error.Foo, S.outer());
|
||||
}
|
||||
|
||||
@ -567,3 +567,24 @@ test "packed struct passed to callconv(.C) function" {
|
||||
}, 5, 4, 3, 2, 1);
|
||||
try expect(result);
|
||||
}
|
||||
|
||||
test "overaligned pointer to packed struct" {
|
||||
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;
|
||||
|
||||
const S = packed struct { a: u32, b: u32 };
|
||||
var foo: S align(4) = .{ .a = 123, .b = 456 };
|
||||
const ptr: *align(4) S = &foo;
|
||||
switch (comptime builtin.cpu.arch.endian()) {
|
||||
.Little => {
|
||||
const ptr_to_b: *u32 = &ptr.b;
|
||||
try expect(ptr_to_b.* == 456);
|
||||
},
|
||||
.Big => {
|
||||
// Byte aligned packed struct field pointers have not been implemented yet.
|
||||
const ptr_to_a: *align(4:0:8) u32 = &ptr.a;
|
||||
try expect(ptr_to_a.* == 123);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,3 +270,15 @@ test "comptime @ptrCast a subset of an array, then write through it" {
|
||||
std.mem.copy(u8, buff[4..], "abcdef");
|
||||
}
|
||||
}
|
||||
|
||||
test "@ptrCast undefined value at comptime" {
|
||||
const S = struct {
|
||||
fn transmute(comptime T: type, comptime U: type, value: T) U {
|
||||
return @ptrCast(*const U, &value).*;
|
||||
}
|
||||
};
|
||||
comptime {
|
||||
var x = S.transmute([]u8, i32, undefined);
|
||||
_ = x;
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,3 +706,34 @@ test "global slice field access" {
|
||||
S.slice.len -= 2;
|
||||
try expectEqualStrings("trin", S.slice);
|
||||
}
|
||||
|
||||
test "slice of void" {
|
||||
var n: usize = 10;
|
||||
var arr: [12]void = undefined;
|
||||
const slice = @as([]void, &arr)[0..n];
|
||||
try expect(slice.len == n);
|
||||
}
|
||||
|
||||
test "slice with dereferenced value" {
|
||||
var a: usize = 0;
|
||||
var idx: *usize = &a;
|
||||
_ = blk: {
|
||||
var array = [_]u8{};
|
||||
break :blk array[idx.*..];
|
||||
};
|
||||
const res = blk: {
|
||||
var array = [_]u8{};
|
||||
break :blk array[idx.*..];
|
||||
};
|
||||
try expect(res.len == 0);
|
||||
}
|
||||
|
||||
test "empty slice ptr is non null" {
|
||||
if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and (builtin.os.tag == .macos or builtin.os.tag == .windows)) return error.SkipZigTest; // TODO
|
||||
|
||||
const empty_slice: []u8 = &[_]u8{};
|
||||
const p: [*]u8 = empty_slice.ptr + 0;
|
||||
const t = @ptrCast([*]i8, p);
|
||||
try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr));
|
||||
}
|
||||
|
||||
@ -1458,3 +1458,40 @@ test "struct has only one reference" {
|
||||
try expectEqual(@sizeOf(struct { x: u16 }), S.optionalComptimeIntParam(@sizeOf(struct { x: u16 })));
|
||||
try expectEqual(@sizeOf(struct { x: u32 }), S.errorUnionComptimeIntParam(@sizeOf(struct { x: u32 })));
|
||||
}
|
||||
|
||||
test "no dependency loop on pointer to optional struct" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const A = struct { b: B };
|
||||
const B = struct { a: *?A };
|
||||
};
|
||||
var a1: ?S.A = null;
|
||||
var a2: ?S.A = .{ .b = .{ .a = &a1 } };
|
||||
a1 = .{ .b = .{ .a = &a2 } };
|
||||
|
||||
try expect(a1.?.b.a == &a2);
|
||||
try expect(a2.?.b.a == &a1);
|
||||
}
|
||||
|
||||
test "discarded struct initialization works as expected" {
|
||||
const S = struct { a: u32 };
|
||||
_ = S{ .a = 1 };
|
||||
}
|
||||
|
||||
test "function pointer in struct returns the struct" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const A = struct {
|
||||
const A = @This();
|
||||
f: *const fn () A,
|
||||
|
||||
fn f() A {
|
||||
return .{ .f = f };
|
||||
}
|
||||
};
|
||||
var a = A.f();
|
||||
try expect(a.f == A.f);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
const expect = testing.expect;
|
||||
const expectEqualStrings = std.testing.expectEqualStrings;
|
||||
|
||||
test "tuple concatenation" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
@ -340,3 +341,28 @@ test "tuple type with void field and a runtime field" {
|
||||
var t: T = .{ 5, {} };
|
||||
try expect(t[0] == 5);
|
||||
}
|
||||
|
||||
test "branching inside tuple literal" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn foo(a: anytype) !void {
|
||||
try expect(a[0] == 1234);
|
||||
}
|
||||
};
|
||||
var a = false;
|
||||
try S.foo(.{if (a) @as(u32, 5678) else @as(u32, 1234)});
|
||||
}
|
||||
|
||||
test "tuple initialized with a runtime known value" {
|
||||
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;
|
||||
|
||||
const E = union(enum) { e: []const u8 };
|
||||
const W = union(enum) { w: E };
|
||||
var e = E{ .e = "test" };
|
||||
const w = .{W{ .w = e }};
|
||||
try expectEqualStrings(w[0].w.e, "test");
|
||||
}
|
||||
|
||||
@ -1471,3 +1471,34 @@ test "union int tag type is properly managed" {
|
||||
};
|
||||
try expect(@sizeOf(Bar) + 1 == 3);
|
||||
}
|
||||
|
||||
test "no dependency loop when function pointer in union returns the union" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = union(enum) {
|
||||
const U = @This();
|
||||
a: u8,
|
||||
b: *const fn (x: U) void,
|
||||
c: *const fn (x: U) U,
|
||||
d: *const fn (x: u8) U,
|
||||
fn foo(x: u8) U {
|
||||
return .{ .a = x };
|
||||
}
|
||||
};
|
||||
var b: U = .{ .d = U.foo };
|
||||
try expect(b.d(2).a == 2);
|
||||
}
|
||||
|
||||
test "union reassignment can use previous value" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = union {
|
||||
a: u32,
|
||||
b: u32,
|
||||
};
|
||||
var a = U{ .a = 32 };
|
||||
a = U{ .b = a.a };
|
||||
try expect(a.b == 32);
|
||||
}
|
||||
|
||||
@ -6,6 +6,27 @@ export fn foo() void {
|
||||
}
|
||||
|
||||
fn bar() void { }
|
||||
export fn baz() void {
|
||||
comptime var idx: u32 = 0;
|
||||
while (idx < 1) {
|
||||
const not_null: ?u32 = 1;
|
||||
_ = not_null orelse return;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
export fn qux() void {
|
||||
comptime var i = 0;
|
||||
while (i < 3) : (i += 1) {
|
||||
const T = switch (i) {
|
||||
0 => f32,
|
||||
1 => i8,
|
||||
2 => bool,
|
||||
else => unreachable,
|
||||
};
|
||||
_ = T;
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
@ -13,3 +34,7 @@ fn bar() void { }
|
||||
//
|
||||
// :3:24: error: cannot store to comptime variable in non-inline loop
|
||||
// :3:5: note: non-inline loop here
|
||||
// :14:13: error: cannot store to comptime variable in non-inline loop
|
||||
// :11:5: note: non-inline loop here
|
||||
// :20:24: error: cannot store to comptime variable in non-inline loop
|
||||
// :20:5: note: non-inline loop here
|
||||
|
||||
@ -18,6 +18,10 @@ export fn qux() void {
|
||||
var ptr = &S{.x=1,.y=2};
|
||||
ptr.x = 2;
|
||||
}
|
||||
export fn quux() void {
|
||||
var x = &@returnAddress();
|
||||
x.* = 6;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
@ -27,3 +31,4 @@ export fn qux() void {
|
||||
// :7:8: error: cannot assign to constant
|
||||
// :11:8: error: cannot assign to constant
|
||||
// :19:8: error: cannot assign to constant
|
||||
// :23:6: error: cannot assign to constant
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
fn A(comptime T: type) type {
|
||||
return struct { a: T };
|
||||
}
|
||||
fn B(comptime T: type) type {
|
||||
return struct { b: T };
|
||||
}
|
||||
fn foo() A(u32) {
|
||||
return B(u32){ .b = 1 };
|
||||
}
|
||||
export fn entry() void {
|
||||
_ = foo();
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :8:18: error: expected type 'tmp.A(u32)', found 'tmp.B(u32)'
|
||||
// :5:12: note: struct declared here
|
||||
// :2:12: note: struct declared here
|
||||
Loading…
x
Reference in New Issue
Block a user