Commit 35423b0054
Changed files (13)
test/behavior/call.zig
@@ -1,3 +1,81 @@
+const builtin = @import("builtin");
const std = @import("std");
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
+
+test "basic invocations" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const foo = struct {
+ fn foo() i32 {
+ return 1234;
+ }
+ }.foo;
+ try expect(@call(.{}, foo, .{}) == 1234);
+ comptime {
+ // modifiers that allow comptime calls
+ try expect(@call(.{}, foo, .{}) == 1234);
+ try expect(@call(.{ .modifier = .no_async }, foo, .{}) == 1234);
+ try expect(@call(.{ .modifier = .always_tail }, foo, .{}) == 1234);
+ try expect(@call(.{ .modifier = .always_inline }, foo, .{}) == 1234);
+ }
+ {
+ // comptime call without comptime keyword
+ const result = @call(.{ .modifier = .compile_time }, foo, .{}) == 1234;
+ comptime try expect(result);
+ }
+ {
+ // call of non comptime-known function
+ var alias_foo = foo;
+ try expect(@call(.{ .modifier = .no_async }, alias_foo, .{}) == 1234);
+ try expect(@call(.{ .modifier = .never_tail }, alias_foo, .{}) == 1234);
+ try expect(@call(.{ .modifier = .never_inline }, alias_foo, .{}) == 1234);
+ }
+}
+
+test "tuple parameters" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const add = struct {
+ fn add(a: i32, b: i32) i32 {
+ return a + b;
+ }
+ }.add;
+ var a: i32 = 12;
+ var b: i32 = 34;
+ try expect(@call(.{}, add, .{ a, 34 }) == 46);
+ try expect(@call(.{}, add, .{ 12, b }) == 46);
+ try expect(@call(.{}, add, .{ a, b }) == 46);
+ try expect(@call(.{}, add, .{ 12, 34 }) == 46);
+ comptime try expect(@call(.{}, add, .{ 12, 34 }) == 46);
+ {
+ const separate_args0 = .{ a, b };
+ const separate_args1 = .{ a, 34 };
+ const separate_args2 = .{ 12, 34 };
+ const separate_args3 = .{ 12, b };
+ try expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46);
+ try expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46);
+ try expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46);
+ try expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);
+ }
+}
+
+test "comptime call with bound function as parameter" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn ReturnType(func: anytype) type {
+ return switch (@typeInfo(@TypeOf(func))) {
+ .BoundFn => |info| info,
+ else => unreachable,
+ }.return_type orelse void;
+ }
+
+ fn call_me_maybe() ?i32 {
+ return 123;
+ }
+ };
+
+ var inst: S = undefined;
+ try expectEqual(?i32, S.ReturnType(inst.call_me_maybe));
+}
test/behavior/call_stage1.zig
@@ -1,74 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const expectEqual = std.testing.expectEqual;
-
-test "basic invocations" {
- const foo = struct {
- fn foo() i32 {
- return 1234;
- }
- }.foo;
- try expect(@call(.{}, foo, .{}) == 1234);
- comptime {
- // modifiers that allow comptime calls
- try expect(@call(.{}, foo, .{}) == 1234);
- try expect(@call(.{ .modifier = .no_async }, foo, .{}) == 1234);
- try expect(@call(.{ .modifier = .always_tail }, foo, .{}) == 1234);
- try expect(@call(.{ .modifier = .always_inline }, foo, .{}) == 1234);
- }
- {
- // comptime call without comptime keyword
- const result = @call(.{ .modifier = .compile_time }, foo, .{}) == 1234;
- comptime try expect(result);
- }
- {
- // call of non comptime-known function
- var alias_foo = foo;
- try expect(@call(.{ .modifier = .no_async }, alias_foo, .{}) == 1234);
- try expect(@call(.{ .modifier = .never_tail }, alias_foo, .{}) == 1234);
- try expect(@call(.{ .modifier = .never_inline }, alias_foo, .{}) == 1234);
- }
-}
-
-test "tuple parameters" {
- const add = struct {
- fn add(a: i32, b: i32) i32 {
- return a + b;
- }
- }.add;
- var a: i32 = 12;
- var b: i32 = 34;
- try expect(@call(.{}, add, .{ a, 34 }) == 46);
- try expect(@call(.{}, add, .{ 12, b }) == 46);
- try expect(@call(.{}, add, .{ a, b }) == 46);
- try expect(@call(.{}, add, .{ 12, 34 }) == 46);
- comptime try expect(@call(.{}, add, .{ 12, 34 }) == 46);
- {
- const separate_args0 = .{ a, b };
- const separate_args1 = .{ a, 34 };
- const separate_args2 = .{ 12, 34 };
- const separate_args3 = .{ 12, b };
- try expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46);
- try expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46);
- try expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46);
- try expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);
- }
-}
-
-test "comptime call with bound function as parameter" {
- const S = struct {
- fn ReturnType(func: anytype) type {
- return switch (@typeInfo(@TypeOf(func))) {
- .BoundFn => |info| info,
- else => unreachable,
- }.return_type orelse void;
- }
-
- fn call_me_maybe() ?i32 {
- return 123;
- }
- };
-
- var inst: S = undefined;
- try expectEqual(?i32, S.ReturnType(inst.call_me_maybe));
-}
test/behavior/error.zig
@@ -132,3 +132,349 @@ fn foo2(f: fn () anyerror!void) void {
}
fn bar2() (error{}!void) {}
+
+test "error union type " {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testErrorUnionType();
+ comptime try testErrorUnionType();
+}
+
+fn testErrorUnionType() !void {
+ const x: anyerror!i32 = 1234;
+ if (x) |value| try expect(value == 1234) else |_| unreachable;
+ try expect(@typeInfo(@TypeOf(x)) == .ErrorUnion);
+ try expect(@typeInfo(@typeInfo(@TypeOf(x)).ErrorUnion.error_set) == .ErrorSet);
+ try expect(@typeInfo(@TypeOf(x)).ErrorUnion.error_set == anyerror);
+}
+
+test "error set type" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testErrorSetType();
+ comptime try testErrorSetType();
+}
+
+const MyErrSet = error{
+ OutOfMemory,
+ FileNotFound,
+};
+
+fn testErrorSetType() !void {
+ try expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2);
+
+ const a: MyErrSet!i32 = 5678;
+ const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
+ try expect(b catch error.OutOfMemory == error.OutOfMemory);
+
+ if (a) |value| try expect(value == 5678) else |err| switch (err) {
+ error.OutOfMemory => unreachable,
+ error.FileNotFound => unreachable,
+ }
+}
+
+test "explicit error set cast" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testExplicitErrorSetCast(Set1.A);
+ comptime try testExplicitErrorSetCast(Set1.A);
+}
+
+const Set1 = error{ A, B };
+const Set2 = error{ A, C };
+
+fn testExplicitErrorSetCast(set1: Set1) !void {
+ var x = @errSetCast(Set2, set1);
+ var y = @errSetCast(Set1, x);
+ try expect(y == error.A);
+}
+
+test "comptime test error for empty error set" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testComptimeTestErrorEmptySet(1234);
+ comptime try testComptimeTestErrorEmptySet(1234);
+}
+
+const EmptyErrorSet = error{};
+
+fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {
+ if (x) |v| try expect(v == 1234) else |err| {
+ _ = err;
+ @compileError("bad");
+ }
+}
+
+test "comptime err to int of error set with only 1 possible value" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
+ comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
+}
+fn testErrToIntWithOnePossibleValue(
+ x: error{A},
+ comptime value: u32,
+) void {
+ if (@errorToInt(x) != value) {
+ @compileError("bad");
+ }
+}
+
+test "error union peer type resolution" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testErrorUnionPeerTypeResolution(1);
+}
+
+fn testErrorUnionPeerTypeResolution(x: i32) !void {
+ const y = switch (x) {
+ 1 => bar_1(),
+ 2 => baz_1(),
+ else => quux_1(),
+ };
+ if (y) |_| {
+ @panic("expected error");
+ } else |e| {
+ try expect(e == error.A);
+ }
+}
+
+fn bar_1() anyerror {
+ return error.A;
+}
+
+fn baz_1() !i32 {
+ return error.B;
+}
+
+fn quux_1() !i32 {
+ return error.C;
+}
+
+test "error: Zero sized error set returned with value payload crash" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ _ = foo3(0) catch {};
+ _ = comptime foo3(0) catch {};
+}
+
+const Error = error{};
+fn foo3(b: usize) Error!usize {
+ return b;
+}
+
+test "error: Infer error set from literals" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ _ = nullLiteral("n") catch |err| handleErrors(err);
+ _ = floatLiteral("n") catch |err| handleErrors(err);
+ _ = intLiteral("n") catch |err| handleErrors(err);
+ _ = comptime nullLiteral("n") catch |err| handleErrors(err);
+ _ = comptime floatLiteral("n") catch |err| handleErrors(err);
+ _ = comptime intLiteral("n") catch |err| handleErrors(err);
+}
+
+fn handleErrors(err: anytype) noreturn {
+ switch (err) {
+ error.T => {},
+ }
+
+ unreachable;
+}
+
+fn nullLiteral(str: []const u8) !?i64 {
+ if (str[0] == 'n') return null;
+
+ return error.T;
+}
+
+fn floatLiteral(str: []const u8) !?f64 {
+ if (str[0] == 'n') return 1.0;
+
+ return error.T;
+}
+
+fn intLiteral(str: []const u8) !?i64 {
+ if (str[0] == 'n') return 1;
+
+ return error.T;
+}
+
+test "nested error union function call in optional unwrap" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const Foo = struct {
+ a: i32,
+ };
+
+ fn errorable() !i32 {
+ var x: Foo = (try getFoo()) orelse return error.Other;
+ return x.a;
+ }
+
+ fn errorable2() !i32 {
+ var x: Foo = (try getFoo2()) orelse return error.Other;
+ return x.a;
+ }
+
+ fn errorable3() !i32 {
+ var x: Foo = (try getFoo3()) orelse return error.Other;
+ return x.a;
+ }
+
+ fn getFoo() anyerror!?Foo {
+ return Foo{ .a = 1234 };
+ }
+
+ fn getFoo2() anyerror!?Foo {
+ return error.Failure;
+ }
+
+ fn getFoo3() anyerror!?Foo {
+ return null;
+ }
+ };
+ try expect((try S.errorable()) == 1234);
+ try expectError(error.Failure, S.errorable2());
+ try expectError(error.Other, S.errorable3());
+ comptime {
+ try expect((try S.errorable()) == 1234);
+ try expectError(error.Failure, S.errorable2());
+ try expectError(error.Other, S.errorable3());
+ }
+}
+
+test "return function call to error set from error union function" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn errorable() anyerror!i32 {
+ return fail();
+ }
+
+ fn fail() anyerror {
+ return error.Failure;
+ }
+ };
+ try expectError(error.Failure, S.errorable());
+ comptime try expectError(error.Failure, S.errorable());
+}
+
+test "optional error set is the same size as error set" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ comptime try expect(@sizeOf(?anyerror) == @sizeOf(anyerror));
+ const S = struct {
+ fn returnsOptErrSet() ?anyerror {
+ return null;
+ }
+ };
+ try expect(S.returnsOptErrSet() == null);
+ comptime try expect(S.returnsOptErrSet() == null);
+}
+
+test "nested catch" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn entry() !void {
+ try expectError(error.Bad, func());
+ }
+ fn fail() anyerror!Foo {
+ return error.Wrong;
+ }
+ fn func() anyerror!Foo {
+ _ = fail() catch
+ fail() catch
+ return error.Bad;
+ unreachable;
+ }
+ const Foo = struct {
+ field: i32,
+ };
+ };
+ try S.entry();
+ comptime try S.entry();
+}
+
+test "function pointer with return type that is error union with payload which is pointer of parent struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const Foo = struct {
+ fun: fn (a: i32) (anyerror!*Foo),
+ };
+
+ const Err = error{UnspecifiedErr};
+
+ fn bar(a: i32) anyerror!*Foo {
+ _ = a;
+ return Err.UnspecifiedErr;
+ }
+
+ fn doTheTest() !void {
+ var x = Foo{ .fun = @This().bar };
+ try expectError(error.UnspecifiedErr, x.fun(1));
+ }
+ };
+ try S.doTheTest();
+}
+
+test "return result loc as peer result loc in inferred error set function" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ if (quux(2)) |x| {
+ try expect(x.Two);
+ } else |e| switch (e) {
+ error.Whatever => @panic("fail"),
+ }
+ try expectError(error.Whatever, quux(99));
+ }
+ const FormValue = union(enum) {
+ One: void,
+ Two: bool,
+ };
+
+ fn quux(id: u64) !FormValue {
+ return switch (id) {
+ 2 => FormValue{ .Two = true },
+ 1 => FormValue{ .One = {} },
+ else => return error.Whatever,
+ };
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "error payload type is correctly resolved" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const MyIntWrapper = struct {
+ const Self = @This();
+
+ x: i32,
+
+ pub fn create() anyerror!Self {
+ return Self{ .x = 42 };
+ }
+ };
+
+ try expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create());
+}
+
+test "error union comptime caching" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn quux(comptime arg: anytype) void {
+ arg catch {};
+ }
+ };
+
+ S.quux(@as(anyerror!void, {}));
+ S.quux(@as(anyerror!void, {}));
+}
test/behavior/error_stage1.zig
@@ -1,319 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const expectError = std.testing.expectError;
-const expectEqual = std.testing.expectEqual;
-const mem = std.mem;
-
-test "error union type " {
- try testErrorUnionType();
- comptime try testErrorUnionType();
-}
-
-fn testErrorUnionType() !void {
- const x: anyerror!i32 = 1234;
- if (x) |value| try expect(value == 1234) else |_| unreachable;
- try expect(@typeInfo(@TypeOf(x)) == .ErrorUnion);
- try expect(@typeInfo(@typeInfo(@TypeOf(x)).ErrorUnion.error_set) == .ErrorSet);
- try expect(@typeInfo(@TypeOf(x)).ErrorUnion.error_set == anyerror);
-}
-
-test "error set type" {
- try testErrorSetType();
- comptime try testErrorSetType();
-}
-
-const MyErrSet = error{
- OutOfMemory,
- FileNotFound,
-};
-
-fn testErrorSetType() !void {
- try expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2);
-
- const a: MyErrSet!i32 = 5678;
- const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
- try expect(b catch error.OutOfMemory == error.OutOfMemory);
-
- if (a) |value| try expect(value == 5678) else |err| switch (err) {
- error.OutOfMemory => unreachable,
- error.FileNotFound => unreachable,
- }
-}
-
-test "explicit error set cast" {
- try testExplicitErrorSetCast(Set1.A);
- comptime try testExplicitErrorSetCast(Set1.A);
-}
-
-const Set1 = error{ A, B };
-const Set2 = error{ A, C };
-
-fn testExplicitErrorSetCast(set1: Set1) !void {
- var x = @errSetCast(Set2, set1);
- var y = @errSetCast(Set1, x);
- try expect(y == error.A);
-}
-
-test "comptime test error for empty error set" {
- try testComptimeTestErrorEmptySet(1234);
- comptime try testComptimeTestErrorEmptySet(1234);
-}
-
-const EmptyErrorSet = error{};
-
-fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {
- if (x) |v| try expect(v == 1234) else |err| {
- _ = err;
- @compileError("bad");
- }
-}
-
-test "comptime err to int of error set with only 1 possible value" {
- testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
- comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
-}
-fn testErrToIntWithOnePossibleValue(
- x: error{A},
- comptime value: u32,
-) void {
- if (@errorToInt(x) != value) {
- @compileError("bad");
- }
-}
-
-test "error union peer type resolution" {
- try testErrorUnionPeerTypeResolution(1);
-}
-
-fn testErrorUnionPeerTypeResolution(x: i32) !void {
- const y = switch (x) {
- 1 => bar_1(),
- 2 => baz_1(),
- else => quux_1(),
- };
- if (y) |_| {
- @panic("expected error");
- } else |e| {
- try expect(e == error.A);
- }
-}
-
-fn bar_1() anyerror {
- return error.A;
-}
-
-fn baz_1() !i32 {
- return error.B;
-}
-
-fn quux_1() !i32 {
- return error.C;
-}
-
-test "error: Zero sized error set returned with value payload crash" {
- _ = foo3(0) catch {};
- _ = comptime foo3(0) catch {};
-}
-
-const Error = error{};
-fn foo3(b: usize) Error!usize {
- return b;
-}
-
-test "error: Infer error set from literals" {
- _ = nullLiteral("n") catch |err| handleErrors(err);
- _ = floatLiteral("n") catch |err| handleErrors(err);
- _ = intLiteral("n") catch |err| handleErrors(err);
- _ = comptime nullLiteral("n") catch |err| handleErrors(err);
- _ = comptime floatLiteral("n") catch |err| handleErrors(err);
- _ = comptime intLiteral("n") catch |err| handleErrors(err);
-}
-
-fn handleErrors(err: anytype) noreturn {
- switch (err) {
- error.T => {},
- }
-
- unreachable;
-}
-
-fn nullLiteral(str: []const u8) !?i64 {
- if (str[0] == 'n') return null;
-
- return error.T;
-}
-
-fn floatLiteral(str: []const u8) !?f64 {
- if (str[0] == 'n') return 1.0;
-
- return error.T;
-}
-
-fn intLiteral(str: []const u8) !?i64 {
- if (str[0] == 'n') return 1;
-
- return error.T;
-}
-
-test "nested error union function call in optional unwrap" {
- const S = struct {
- const Foo = struct {
- a: i32,
- };
-
- fn errorable() !i32 {
- var x: Foo = (try getFoo()) orelse return error.Other;
- return x.a;
- }
-
- fn errorable2() !i32 {
- var x: Foo = (try getFoo2()) orelse return error.Other;
- return x.a;
- }
-
- fn errorable3() !i32 {
- var x: Foo = (try getFoo3()) orelse return error.Other;
- return x.a;
- }
-
- fn getFoo() anyerror!?Foo {
- return Foo{ .a = 1234 };
- }
-
- fn getFoo2() anyerror!?Foo {
- return error.Failure;
- }
-
- fn getFoo3() anyerror!?Foo {
- return null;
- }
- };
- try expect((try S.errorable()) == 1234);
- try expectError(error.Failure, S.errorable2());
- try expectError(error.Other, S.errorable3());
- comptime {
- try expect((try S.errorable()) == 1234);
- try expectError(error.Failure, S.errorable2());
- try expectError(error.Other, S.errorable3());
- }
-}
-
-test "return function call to error set from error union function" {
- const S = struct {
- fn errorable() anyerror!i32 {
- return fail();
- }
-
- fn fail() anyerror {
- return error.Failure;
- }
- };
- try expectError(error.Failure, S.errorable());
- comptime try expectError(error.Failure, S.errorable());
-}
-
-test "optional error set is the same size as error set" {
- comptime try expect(@sizeOf(?anyerror) == @sizeOf(anyerror));
- const S = struct {
- fn returnsOptErrSet() ?anyerror {
- return null;
- }
- };
- try expect(S.returnsOptErrSet() == null);
- comptime try expect(S.returnsOptErrSet() == null);
-}
-
-test "nested catch" {
- const S = struct {
- fn entry() !void {
- try expectError(error.Bad, func());
- }
- fn fail() anyerror!Foo {
- return error.Wrong;
- }
- fn func() anyerror!Foo {
- _ = fail() catch
- fail() catch
- return error.Bad;
- unreachable;
- }
- const Foo = struct {
- field: i32,
- };
- };
- try S.entry();
- comptime try S.entry();
-}
-
-test "function pointer with return type that is error union with payload which is pointer of parent struct" {
- const S = struct {
- const Foo = struct {
- fun: fn (a: i32) (anyerror!*Foo),
- };
-
- const Err = error{UnspecifiedErr};
-
- fn bar(a: i32) anyerror!*Foo {
- _ = a;
- return Err.UnspecifiedErr;
- }
-
- fn doTheTest() !void {
- var x = Foo{ .fun = @This().bar };
- try expectError(error.UnspecifiedErr, x.fun(1));
- }
- };
- try S.doTheTest();
-}
-
-test "return result loc as peer result loc in inferred error set function" {
- const S = struct {
- fn doTheTest() !void {
- if (quux(2)) |x| {
- try expect(x.Two);
- } else |e| switch (e) {
- error.Whatever => @panic("fail"),
- }
- try expectError(error.Whatever, quux(99));
- }
- const FormValue = union(enum) {
- One: void,
- Two: bool,
- };
-
- fn quux(id: u64) !FormValue {
- return switch (id) {
- 2 => FormValue{ .Two = true },
- 1 => FormValue{ .One = {} },
- else => return error.Whatever,
- };
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "error payload type is correctly resolved" {
- const MyIntWrapper = struct {
- const Self = @This();
-
- x: i32,
-
- pub fn create() anyerror!Self {
- return Self{ .x = 42 };
- }
- };
-
- try expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create());
-}
-
-test "error union comptime caching" {
- const S = struct {
- fn quux(comptime arg: anytype) void {
- arg catch {};
- }
- };
-
- S.quux(@as(anyerror!void, {}));
- S.quux(@as(anyerror!void, {}));
-}
test/behavior/generics.zig
@@ -163,3 +163,49 @@ test "generic fn keeps non-generic parameter types" {
var x: [16]u8 align(A) = undefined;
try S.f(u8, &x);
}
+
+test "array of generic fns" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ try expect(foos[0](true));
+ try expect(!foos[1](true));
+}
+
+const foos = [_]fn (anytype) bool{
+ foo1,
+ foo2,
+};
+
+fn foo1(arg: anytype) bool {
+ return arg;
+}
+fn foo2(arg: anytype) bool {
+ return !arg;
+}
+
+test "generic struct" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ var a1 = GenNode(i32){
+ .value = 13,
+ .next = null,
+ };
+ var b1 = GenNode(bool){
+ .value = true,
+ .next = null,
+ };
+ try expect(a1.value == 13);
+ try expect(a1.value == a1.getVal());
+ try expect(b1.getVal());
+}
+fn GenNode(comptime T: type) type {
+ return struct {
+ value: T,
+ next: ?*GenNode(T),
+ fn getVal(n: *const GenNode(T)) T {
+ return n.value;
+ }
+ };
+}
test/behavior/generics_llvm.zig
@@ -1,49 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const builtin = @import("builtin");
-
-const foos = [_]fn (anytype) bool{
- foo1,
- foo2,
-};
-
-fn foo1(arg: anytype) bool {
- return arg;
-}
-fn foo2(arg: anytype) bool {
- return !arg;
-}
-
-test "array of generic fns" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
- if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
- try expect(foos[0](true));
- try expect(!foos[1](true));
-}
-
-test "generic struct" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
- if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
- var a1 = GenNode(i32){
- .value = 13,
- .next = null,
- };
- var b1 = GenNode(bool){
- .value = true,
- .next = null,
- };
- try expect(a1.value == 13);
- try expect(a1.value == a1.getVal());
- try expect(b1.getVal());
-}
-fn GenNode(comptime T: type) type {
- return struct {
- value: T,
- next: ?*GenNode(T),
- fn getVal(n: *const GenNode(T)) T {
- return n.value;
- }
- };
-}
test/behavior/saturating_arithmetic.zig
@@ -118,3 +118,25 @@ test "saturating shift-left" {
try S.doTheTest();
comptime try S.doTheTest();
}
+
+test "saturating shl uses the LHS type" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const lhs_const: u8 = 1;
+ var lhs_var: u8 = 1;
+
+ const rhs_const: usize = 8;
+ var rhs_var: usize = 8;
+
+ try expect((lhs_const <<| 8) == 255);
+ try expect((lhs_const <<| rhs_const) == 255);
+ try expect((lhs_const <<| rhs_var) == 255);
+
+ try expect((lhs_var <<| 8) == 255);
+ try expect((lhs_var <<| rhs_const) == 255);
+ try expect((lhs_var <<| rhs_var) == 255);
+
+ try expect((@as(u8, 1) <<| 8) == 255);
+ try expect((@as(u8, 1) <<| rhs_const) == 255);
+ try expect((@as(u8, 1) <<| rhs_var) == 255);
+}
test/behavior/saturating_arithmetic_stage1.zig
@@ -1,22 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-
-test "saturating shl uses the LHS type" {
- const lhs_const: u8 = 1;
- var lhs_var: u8 = 1;
-
- const rhs_const: usize = 8;
- var rhs_var: usize = 8;
-
- try expect((lhs_const <<| 8) == 255);
- try expect((lhs_const <<| rhs_const) == 255);
- try expect((lhs_const <<| rhs_var) == 255);
-
- try expect((lhs_var <<| 8) == 255);
- try expect((lhs_var <<| rhs_const) == 255);
- try expect((lhs_var <<| rhs_var) == 255);
-
- try expect((@as(u8, 1) <<| 8) == 255);
- try expect((@as(u8, 1) <<| rhs_const) == 255);
- try expect((@as(u8, 1) <<| rhs_var) == 255);
-}
test/behavior/struct_llvm.zig
@@ -305,3 +305,513 @@ test "default struct initialization fields" {
try expect(y.b == x.b);
try expect(1239 == x.a + x.b);
}
+
+// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
+test "packed array 24bits" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ comptime {
+ try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
+ try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
+ }
+
+ var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
+ bytes[bytes.len - 1] = 0xaa;
+ const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
+ try expect(ptr.a == 0);
+ try expect(ptr.b[0].field == 0);
+ try expect(ptr.b[1].field == 0);
+ try expect(ptr.c == 0);
+
+ ptr.a = maxInt(u16);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == 0);
+ try expect(ptr.b[1].field == 0);
+ try expect(ptr.c == 0);
+
+ ptr.b[0].field = maxInt(u24);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == maxInt(u24));
+ try expect(ptr.b[1].field == 0);
+ try expect(ptr.c == 0);
+
+ ptr.b[1].field = maxInt(u24);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == maxInt(u24));
+ try expect(ptr.b[1].field == maxInt(u24));
+ try expect(ptr.c == 0);
+
+ ptr.c = maxInt(u16);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == maxInt(u24));
+ try expect(ptr.b[1].field == maxInt(u24));
+ try expect(ptr.c == maxInt(u16));
+
+ try expect(bytes[bytes.len - 1] == 0xaa);
+}
+
+const Foo32Bits = packed struct {
+ field: u24,
+ pad: u8,
+};
+
+const FooArray24Bits = packed struct {
+ a: u16,
+ b: [2]Foo32Bits,
+ c: u16,
+};
+
+test "aligned array of packed struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ comptime {
+ try expect(@sizeOf(FooStructAligned) == 2);
+ try expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
+ }
+
+ var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
+ const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
+
+ try expect(ptr.a[0].a == 0xbb);
+ try expect(ptr.a[0].b == 0xbb);
+ try expect(ptr.a[1].a == 0xbb);
+ try expect(ptr.a[1].b == 0xbb);
+}
+
+const FooStructAligned = packed struct {
+ a: u8,
+ b: u8,
+};
+
+const FooArrayOfAligned = packed struct {
+ a: [2]FooStructAligned,
+};
+
+test "pointer to packed struct member in a stack variable" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = packed struct {
+ a: u2,
+ b: u2,
+ };
+
+ var s = S{ .a = 2, .b = 0 };
+ var b_ptr = &s.b;
+ try expect(s.b == 0);
+ b_ptr.* = 2;
+ try expect(s.b == 2);
+}
+
+test "non-byte-aligned array inside packed struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Foo = packed struct {
+ a: bool,
+ b: [0x16]u8,
+ };
+ const S = struct {
+ fn bar(slice: []const u8) !void {
+ try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu");
+ }
+ fn doTheTest() !void {
+ var foo = Foo{
+ .a = true,
+ .b = "abcdefghijklmnopqurstu".*,
+ };
+ const value = foo.b;
+ try bar(&value);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "packed struct with u0 field access" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = packed struct {
+ f0: u0,
+ };
+ var s = S{ .f0 = 0 };
+ comptime try expect(s.f0 == 0);
+}
+
+test "access to global struct fields" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ g_foo.bar.value = 42;
+ try expect(g_foo.bar.value == 42);
+}
+
+const S0 = struct {
+ bar: S1,
+
+ pub const S1 = struct {
+ value: u8,
+ };
+
+ fn init() @This() {
+ return S0{ .bar = S1{ .value = 123 } };
+ }
+};
+
+var g_foo: S0 = S0.init();
+
+test "packed struct with fp fields" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = packed struct {
+ data: [3]f32,
+
+ pub fn frob(self: *@This()) void {
+ self.data[0] += self.data[1] + self.data[2];
+ self.data[1] += self.data[0] + self.data[2];
+ self.data[2] += self.data[0] + self.data[1];
+ }
+ };
+
+ var s: S = undefined;
+ s.data[0] = 1.0;
+ s.data[1] = 2.0;
+ s.data[2] = 3.0;
+ s.frob();
+ try expectEqual(@as(f32, 6.0), s.data[0]);
+ try expectEqual(@as(f32, 11.0), s.data[1]);
+ try expectEqual(@as(f32, 20.0), s.data[2]);
+}
+
+test "fn with C calling convention returns struct by value" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn entry() !void {
+ var x = makeBar(10);
+ try expectEqual(@as(i32, 10), x.handle);
+ }
+
+ const ExternBar = extern struct {
+ handle: i32,
+ };
+
+ fn makeBar(t: i32) callconv(.C) ExternBar {
+ return ExternBar{
+ .handle = t,
+ };
+ }
+ };
+ try S.entry();
+ comptime try S.entry();
+}
+
+test "non-packed struct with u128 entry in union" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const U = union(enum) {
+ Num: u128,
+ Void,
+ };
+
+ const S = struct {
+ f1: U,
+ f2: U,
+ };
+
+ var sx: S = undefined;
+ var s = &sx;
+ try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
+ var v2 = U{ .Num = 123 };
+ s.f2 = v2;
+ try std.testing.expect(s.f2.Num == 123);
+}
+
+test "packed struct field passed to generic function" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const P = packed struct {
+ b: u5,
+ g: u5,
+ r: u5,
+ a: u1,
+ };
+
+ fn genericReadPackedField(ptr: anytype) u5 {
+ return ptr.*;
+ }
+ };
+
+ var p: S.P = undefined;
+ p.b = 29;
+ var loaded = S.genericReadPackedField(&p.b);
+ try expect(loaded == 29);
+}
+
+test "anonymous struct literal syntax" {
+ const S = struct {
+ const Point = struct {
+ x: i32,
+ y: i32,
+ };
+
+ fn doTheTest() !void {
+ var p: Point = .{
+ .x = 1,
+ .y = 2,
+ };
+ try expect(p.x == 1);
+ try expect(p.y == 2);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "fully anonymous struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try dump(.{
+ .int = @as(u32, 1234),
+ .float = @as(f64, 12.34),
+ .b = true,
+ .s = "hi",
+ });
+ }
+ fn dump(args: anytype) !void {
+ try expect(args.int == 1234);
+ try expect(args.float == 12.34);
+ try expect(args.b);
+ try expect(args.s[0] == 'h');
+ try expect(args.s[1] == 'i');
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "fully anonymous list literal" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
+ }
+ fn dump(args: anytype) !void {
+ try expect(args.@"0" == 1234);
+ try expect(args.@"1" == 12.34);
+ try expect(args.@"2");
+ try expect(args.@"3"[0] == 'h');
+ try expect(args.@"3"[1] == 'i');
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "anonymous struct literal assigned to variable" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
+ try expect(vec.@"0" == 22);
+ try expect(vec.@"1" == 55);
+ try expect(vec.@"2" == 99);
+}
+
+test "struct with var field" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Point = struct {
+ x: anytype,
+ y: anytype,
+ };
+ const pt = Point{
+ .x = 1,
+ .y = 2,
+ };
+ try expect(pt.x == 1);
+ try expect(pt.y == 2);
+}
+
+test "comptime struct field" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const T = struct {
+ a: i32,
+ comptime b: i32 = 1234,
+ };
+
+ var foo: T = undefined;
+ comptime try expect(foo.b == 1234);
+}
+
+test "anon struct literal field value initialized with fn call" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var x = .{foo()};
+ try expectEqualSlices(u8, x[0], "hi");
+ }
+ fn foo() []const u8 {
+ return "hi";
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "struct with union field" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Value = struct {
+ ref: u32 = 2,
+ kind: union(enum) {
+ None: usize,
+ Bool: bool,
+ },
+ };
+
+ var True = Value{
+ .kind = .{ .Bool = true },
+ };
+ try expectEqual(@as(u32, 2), True.ref);
+ try expectEqual(true, True.kind.Bool);
+}
+
+test "type coercion of anon struct literal to struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const S2 = struct {
+ A: u32,
+ B: []const u8,
+ C: void,
+ D: Foo = .{},
+ };
+
+ const Foo = struct {
+ field: i32 = 1234,
+ };
+
+ fn doTheTest() !void {
+ var y: u32 = 42;
+ const t0 = .{ .A = 123, .B = "foo", .C = {} };
+ const t1 = .{ .A = y, .B = "foo", .C = {} };
+ const y0: S2 = t0;
+ var y1: S2 = t1;
+ try expect(y0.A == 123);
+ try expect(std.mem.eql(u8, y0.B, "foo"));
+ try expect(y0.C == {});
+ try expect(y0.D.field == 1234);
+ try expect(y1.A == y);
+ try expect(std.mem.eql(u8, y1.B, "foo"));
+ try expect(y1.C == {});
+ try expect(y1.D.field == 1234);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "type coercion of pointer to anon struct literal to pointer to struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const S2 = struct {
+ A: u32,
+ B: []const u8,
+ C: void,
+ D: Foo = .{},
+ };
+
+ const Foo = struct {
+ field: i32 = 1234,
+ };
+
+ fn doTheTest() !void {
+ var y: u32 = 42;
+ const t0 = &.{ .A = 123, .B = "foo", .C = {} };
+ const t1 = &.{ .A = y, .B = "foo", .C = {} };
+ const y0: *const S2 = t0;
+ var y1: *const S2 = t1;
+ try expect(y0.A == 123);
+ try expect(std.mem.eql(u8, y0.B, "foo"));
+ try expect(y0.C == {});
+ try expect(y0.D.field == 1234);
+ try expect(y1.A == y);
+ try expect(std.mem.eql(u8, y1.B, "foo"));
+ try expect(y1.C == {});
+ try expect(y1.D.field == 1234);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "packed struct with undefined initializers" {
+ const S = struct {
+ const P = packed struct {
+ a: u3,
+ _a: u3 = undefined,
+ b: u3,
+ _b: u3 = undefined,
+ c: u3,
+ _c: u3 = undefined,
+ };
+
+ fn doTheTest() !void {
+ var p: P = undefined;
+ p = P{ .a = 2, .b = 4, .c = 6 };
+ // Make sure the compiler doesn't touch the unprefixed fields.
+ // Use expect since i386-linux doesn't like expectEqual
+ try expect(p.a == 2);
+ try expect(p.b == 4);
+ try expect(p.c == 6);
+ }
+ };
+
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "for loop over pointers to struct, getting field from struct pointer" {
+ // When enabling this test, be careful. I have observed it to pass when compiling
+ // stage2 alone, but when using stage1 with -fno-stage1 -fLLVM it fails.
+ // Maybe eyeball the LLVM that it generates and run in valgrind, both the compiler
+ // and the generated test at runtime.
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const Foo = struct {
+ name: []const u8,
+ };
+
+ var ok = true;
+
+ fn eql(a: []const u8) bool {
+ _ = a;
+ return true;
+ }
+
+ const ArrayList = struct {
+ fn toSlice(self: *ArrayList) []*Foo {
+ _ = self;
+ return @as([*]*Foo, undefined)[0..0];
+ }
+ };
+
+ fn doTheTest() !void {
+ var objects: ArrayList = undefined;
+
+ for (objects.toSlice()) |obj| {
+ if (eql(obj.name)) {
+ ok = false;
+ }
+ }
+
+ try expect(ok);
+ }
+ };
+ try S.doTheTest();
+}
test/behavior/struct_stage1.zig
@@ -1,473 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const native_endian = builtin.target.cpu.arch.endian();
-const expect = std.testing.expect;
-const expectEqual = std.testing.expectEqual;
-const expectEqualSlices = std.testing.expectEqualSlices;
-const maxInt = std.math.maxInt;
-
-const Foo32Bits = packed struct {
- field: u24,
- pad: u8,
-};
-
-const FooArray24Bits = packed struct {
- a: u16,
- b: [2]Foo32Bits,
- c: u16,
-};
-
-// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
-test "packed array 24bits" {
- comptime {
- try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
- try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
- }
-
- var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
- bytes[bytes.len - 1] = 0xaa;
- const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
- try expect(ptr.a == 0);
- try expect(ptr.b[0].field == 0);
- try expect(ptr.b[1].field == 0);
- try expect(ptr.c == 0);
-
- ptr.a = maxInt(u16);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == 0);
- try expect(ptr.b[1].field == 0);
- try expect(ptr.c == 0);
-
- ptr.b[0].field = maxInt(u24);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == maxInt(u24));
- try expect(ptr.b[1].field == 0);
- try expect(ptr.c == 0);
-
- ptr.b[1].field = maxInt(u24);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == maxInt(u24));
- try expect(ptr.b[1].field == maxInt(u24));
- try expect(ptr.c == 0);
-
- ptr.c = maxInt(u16);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == maxInt(u24));
- try expect(ptr.b[1].field == maxInt(u24));
- try expect(ptr.c == maxInt(u16));
-
- try expect(bytes[bytes.len - 1] == 0xaa);
-}
-
-const FooStructAligned = packed struct {
- a: u8,
- b: u8,
-};
-
-const FooArrayOfAligned = packed struct {
- a: [2]FooStructAligned,
-};
-
-test "aligned array of packed struct" {
- comptime {
- try expect(@sizeOf(FooStructAligned) == 2);
- try expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
- }
-
- var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
- const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
-
- try expect(ptr.a[0].a == 0xbb);
- try expect(ptr.a[0].b == 0xbb);
- try expect(ptr.a[1].a == 0xbb);
- try expect(ptr.a[1].b == 0xbb);
-}
-
-test "pointer to packed struct member in a stack variable" {
- const S = packed struct {
- a: u2,
- b: u2,
- };
-
- var s = S{ .a = 2, .b = 0 };
- var b_ptr = &s.b;
- try expect(s.b == 0);
- b_ptr.* = 2;
- try expect(s.b == 2);
-}
-
-test "non-byte-aligned array inside packed struct" {
- const Foo = packed struct {
- a: bool,
- b: [0x16]u8,
- };
- const S = struct {
- fn bar(slice: []const u8) !void {
- try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu");
- }
- fn doTheTest() !void {
- var foo = Foo{
- .a = true,
- .b = "abcdefghijklmnopqurstu".*,
- };
- const value = foo.b;
- try bar(&value);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "packed struct with u0 field access" {
- const S = packed struct {
- f0: u0,
- };
- var s = S{ .f0 = 0 };
- comptime try expect(s.f0 == 0);
-}
-
-const S0 = struct {
- bar: S1,
-
- pub const S1 = struct {
- value: u8,
- };
-
- fn init() @This() {
- return S0{ .bar = S1{ .value = 123 } };
- }
-};
-
-var g_foo: S0 = S0.init();
-
-test "access to global struct fields" {
- g_foo.bar.value = 42;
- try expect(g_foo.bar.value == 42);
-}
-
-test "packed struct with fp fields" {
- const S = packed struct {
- data: [3]f32,
-
- pub fn frob(self: *@This()) void {
- self.data[0] += self.data[1] + self.data[2];
- self.data[1] += self.data[0] + self.data[2];
- self.data[2] += self.data[0] + self.data[1];
- }
- };
-
- var s: S = undefined;
- s.data[0] = 1.0;
- s.data[1] = 2.0;
- s.data[2] = 3.0;
- s.frob();
- try expectEqual(@as(f32, 6.0), s.data[0]);
- try expectEqual(@as(f32, 11.0), s.data[1]);
- try expectEqual(@as(f32, 20.0), s.data[2]);
-}
-
-test "fn with C calling convention returns struct by value" {
- const S = struct {
- fn entry() !void {
- var x = makeBar(10);
- try expectEqual(@as(i32, 10), x.handle);
- }
-
- const ExternBar = extern struct {
- handle: i32,
- };
-
- fn makeBar(t: i32) callconv(.C) ExternBar {
- return ExternBar{
- .handle = t,
- };
- }
- };
- try S.entry();
- comptime try S.entry();
-}
-
-test "non-packed struct with u128 entry in union" {
- const U = union(enum) {
- Num: u128,
- Void,
- };
-
- const S = struct {
- f1: U,
- f2: U,
- };
-
- var sx: S = undefined;
- var s = &sx;
- try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
- var v2 = U{ .Num = 123 };
- s.f2 = v2;
- try std.testing.expect(s.f2.Num == 123);
-}
-
-test "packed struct field passed to generic function" {
- const S = struct {
- const P = packed struct {
- b: u5,
- g: u5,
- r: u5,
- a: u1,
- };
-
- fn genericReadPackedField(ptr: anytype) u5 {
- return ptr.*;
- }
- };
-
- var p: S.P = undefined;
- p.b = 29;
- var loaded = S.genericReadPackedField(&p.b);
- try expect(loaded == 29);
-}
-
-test "anonymous struct literal syntax" {
- const S = struct {
- const Point = struct {
- x: i32,
- y: i32,
- };
-
- fn doTheTest() !void {
- var p: Point = .{
- .x = 1,
- .y = 2,
- };
- try expect(p.x == 1);
- try expect(p.y == 2);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "fully anonymous struct" {
- const S = struct {
- fn doTheTest() !void {
- try dump(.{
- .int = @as(u32, 1234),
- .float = @as(f64, 12.34),
- .b = true,
- .s = "hi",
- });
- }
- fn dump(args: anytype) !void {
- try expect(args.int == 1234);
- try expect(args.float == 12.34);
- try expect(args.b);
- try expect(args.s[0] == 'h');
- try expect(args.s[1] == 'i');
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "fully anonymous list literal" {
- const S = struct {
- fn doTheTest() !void {
- try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
- }
- fn dump(args: anytype) !void {
- try expect(args.@"0" == 1234);
- try expect(args.@"1" == 12.34);
- try expect(args.@"2");
- try expect(args.@"3"[0] == 'h');
- try expect(args.@"3"[1] == 'i');
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "anonymous struct literal assigned to variable" {
- var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
- try expect(vec.@"0" == 22);
- try expect(vec.@"1" == 55);
- try expect(vec.@"2" == 99);
-}
-
-test "struct with var field" {
- const Point = struct {
- x: anytype,
- y: anytype,
- };
- const pt = Point{
- .x = 1,
- .y = 2,
- };
- try expect(pt.x == 1);
- try expect(pt.y == 2);
-}
-
-test "comptime struct field" {
- const T = struct {
- a: i32,
- comptime b: i32 = 1234,
- };
-
- var foo: T = undefined;
- comptime try expect(foo.b == 1234);
-}
-
-test "anon struct literal field value initialized with fn call" {
- const S = struct {
- fn doTheTest() !void {
- var x = .{foo()};
- try expectEqualSlices(u8, x[0], "hi");
- }
- fn foo() []const u8 {
- return "hi";
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "struct with union field" {
- const Value = struct {
- ref: u32 = 2,
- kind: union(enum) {
- None: usize,
- Bool: bool,
- },
- };
-
- var True = Value{
- .kind = .{ .Bool = true },
- };
- try expectEqual(@as(u32, 2), True.ref);
- try expectEqual(true, True.kind.Bool);
-}
-
-test "type coercion of anon struct literal to struct" {
- const S = struct {
- const S2 = struct {
- A: u32,
- B: []const u8,
- C: void,
- D: Foo = .{},
- };
-
- const Foo = struct {
- field: i32 = 1234,
- };
-
- fn doTheTest() !void {
- var y: u32 = 42;
- const t0 = .{ .A = 123, .B = "foo", .C = {} };
- const t1 = .{ .A = y, .B = "foo", .C = {} };
- const y0: S2 = t0;
- var y1: S2 = t1;
- try expect(y0.A == 123);
- try expect(std.mem.eql(u8, y0.B, "foo"));
- try expect(y0.C == {});
- try expect(y0.D.field == 1234);
- try expect(y1.A == y);
- try expect(std.mem.eql(u8, y1.B, "foo"));
- try expect(y1.C == {});
- try expect(y1.D.field == 1234);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "type coercion of pointer to anon struct literal to pointer to struct" {
- const S = struct {
- const S2 = struct {
- A: u32,
- B: []const u8,
- C: void,
- D: Foo = .{},
- };
-
- const Foo = struct {
- field: i32 = 1234,
- };
-
- fn doTheTest() !void {
- var y: u32 = 42;
- const t0 = &.{ .A = 123, .B = "foo", .C = {} };
- const t1 = &.{ .A = y, .B = "foo", .C = {} };
- const y0: *const S2 = t0;
- var y1: *const S2 = t1;
- try expect(y0.A == 123);
- try expect(std.mem.eql(u8, y0.B, "foo"));
- try expect(y0.C == {});
- try expect(y0.D.field == 1234);
- try expect(y1.A == y);
- try expect(std.mem.eql(u8, y1.B, "foo"));
- try expect(y1.C == {});
- try expect(y1.D.field == 1234);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "packed struct with undefined initializers" {
- const S = struct {
- const P = packed struct {
- a: u3,
- _a: u3 = undefined,
- b: u3,
- _b: u3 = undefined,
- c: u3,
- _c: u3 = undefined,
- };
-
- fn doTheTest() !void {
- var p: P = undefined;
- p = P{ .a = 2, .b = 4, .c = 6 };
- // Make sure the compiler doesn't touch the unprefixed fields.
- // Use expect since i386-linux doesn't like expectEqual
- try expect(p.a == 2);
- try expect(p.b == 4);
- try expect(p.c == 6);
- }
- };
-
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "for loop over pointers to struct, getting field from struct pointer" {
- const S = struct {
- const Foo = struct {
- name: []const u8,
- };
-
- var ok = true;
-
- fn eql(a: []const u8) bool {
- _ = a;
- return true;
- }
-
- const ArrayList = struct {
- fn toSlice(self: *ArrayList) []*Foo {
- _ = self;
- return @as([*]*Foo, undefined)[0..0];
- }
- };
-
- fn doTheTest() !void {
- var objects: ArrayList = undefined;
-
- for (objects.toSlice()) |obj| {
- if (eql(obj.name)) {
- ok = false;
- }
- }
-
- try expect(ok);
- }
- };
- try S.doTheTest();
-}
test/behavior/translate_c_macros.zig
@@ -1,3 +1,4 @@
+const builtin = @import("builtin");
const std = @import("std");
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
@@ -16,3 +17,33 @@ test "casting to void with a macro" {
h.IGNORE_ME_9(42);
h.IGNORE_ME_10(42);
}
+
+test "initializer list expression" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try expectEqual(h.Color{
+ .r = 200,
+ .g = 200,
+ .b = 200,
+ .a = 255,
+ }, h.LIGHTGRAY);
+}
+
+test "sizeof in macros" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
+ try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
+}
+
+test "reference to a struct type" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
+}
+
+test "cast negative integer to pointer" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try expectEqual(@intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED);
+}
test/behavior/translate_c_macros_stage1.zig
@@ -1,27 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const expectEqual = std.testing.expectEqual;
-
-const h = @cImport(@cInclude("behavior/translate_c_macros.h"));
-
-test "initializer list expression" {
- try expectEqual(h.Color{
- .r = 200,
- .g = 200,
- .b = 200,
- .a = 255,
- }, h.LIGHTGRAY);
-}
-
-test "sizeof in macros" {
- try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
- try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
-}
-
-test "reference to a struct type" {
- try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
-}
-
-test "cast negative integer to pointer" {
- try expectEqual(@intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED);
-}
test/behavior.zig
@@ -1,7 +1,6 @@
const builtin = @import("builtin");
test {
- // Tests that pass for stage1, llvm backend, C backend, wasm backend, arm backend and x86_64 backend.
_ = @import("behavior/align.zig");
_ = @import("behavior/alignof.zig");
_ = @import("behavior/array.zig");
@@ -26,7 +25,6 @@ test {
_ = @import("behavior/cast.zig");
_ = @import("behavior/comptime_memory.zig");
_ = @import("behavior/fn_in_struct_in_comptime.zig");
- _ = @import("behavior/generics_llvm.zig");
_ = @import("behavior/hasdecl.zig");
_ = @import("behavior/hasfield.zig");
_ = @import("behavior/namespace_depends_on_compile_var.zig");
@@ -43,6 +41,7 @@ test {
_ = @import("behavior/bitcast.zig");
_ = @import("behavior/bugs/624.zig");
_ = @import("behavior/bugs/704.zig");
+ _ = @import("behavior/bugs/1076.zig");
_ = @import("behavior/bugs/1486.zig");
_ = @import("behavior/bugs/2692.zig");
_ = @import("behavior/bugs/2889.zig");
@@ -128,7 +127,6 @@ test {
_ = @import("behavior/bugs/726.zig");
_ = @import("behavior/bugs/828.zig");
_ = @import("behavior/bugs/920.zig");
- _ = @import("behavior/bugs/1076.zig");
_ = @import("behavior/bugs/1120.zig");
_ = @import("behavior/bugs/1421.zig");
_ = @import("behavior/bugs/1442.zig");
@@ -150,9 +148,7 @@ test {
_ = @import("behavior/bugs/7047.zig");
_ = @import("behavior/bugs/10147.zig");
_ = @import("behavior/byteswap.zig");
- _ = @import("behavior/call_stage1.zig");
_ = @import("behavior/const_slice_child.zig");
- _ = @import("behavior/error_stage1.zig");
_ = @import("behavior/field_parent_ptr.zig");
_ = @import("behavior/floatop_stage1.zig");
_ = @import("behavior/fn_delegation.zig");
@@ -164,14 +160,12 @@ test {
_ = @import("behavior/optional_stage1.zig");
_ = @import("behavior/popcount_stage1.zig");
_ = @import("behavior/reflection.zig");
- _ = @import("behavior/saturating_arithmetic_stage1.zig");
_ = @import("behavior/select.zig");
_ = @import("behavior/shuffle.zig");
_ = @import("behavior/sizeof_and_typeof_stage1.zig");
_ = @import("behavior/slice_stage1.zig");
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
_ = @import("behavior/struct_contains_slice_of_itself.zig");
- _ = @import("behavior/struct_stage1.zig");
_ = @import("behavior/switch_prong_err_enum.zig");
_ = @import("behavior/switch_prong_implicit_cast.zig");
_ = @import("behavior/truncate_stage1.zig");
@@ -185,7 +179,6 @@ test {
if (builtin.target.cpu.arch == .wasm32) {
_ = @import("behavior/wasm.zig");
}
- _ = @import("behavior/translate_c_macros_stage1.zig");
}
}
}