aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-03-08 20:44:58 -0800
committerAndrew Kelley <andrew@ziglang.org>2022-03-10 14:20:16 -0700
commit569870ca41e73c64d8dc9f1eccfef3529caf2266 (patch)
tree8a4ec47628cacc1723efbff01ba36ebc147a86ad /test
parent0b82c02945c69e2e0465b5a4d9de471ea3c76d50 (diff)
downloadzig-569870ca41e73c64d8dc9f1eccfef3529caf2266.tar.gz
zig-569870ca41e73c64d8dc9f1eccfef3529caf2266.zip
stage2: error_set_merged type equality
This implements type equality for error sets. This is done through element-wise error set comparison. Inferred error sets are always distinct types and other error sets are always sorted. See #11022.
Diffstat (limited to 'test')
-rw-r--r--test/behavior/cast.zig16
-rw-r--r--test/behavior/error.zig107
-rw-r--r--test/behavior/type_info.zig7
-rw-r--r--test/stage2/x86_64.zig19
4 files changed, 113 insertions, 36 deletions
diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig
index 6f300773ae..1f92a0214f 100644
--- a/test/behavior/cast.zig
+++ b/test/behavior/cast.zig
@@ -669,8 +669,8 @@ test "peer type resolution: disjoint error sets" {
try expect(error_set_info == .ErrorSet);
try expect(error_set_info.ErrorSet.?.len == 3);
try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Three"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Two"));
}
{
@@ -678,8 +678,8 @@ test "peer type resolution: disjoint error sets" {
const error_set_info = @typeInfo(ty);
try expect(error_set_info == .ErrorSet);
try expect(error_set_info.ErrorSet.?.len == 3);
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "Three"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "One"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Three"));
try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Two"));
}
}
@@ -704,8 +704,8 @@ test "peer type resolution: error union and error set" {
const error_set_info = @typeInfo(info.ErrorUnion.error_set);
try expect(error_set_info.ErrorSet.?.len == 3);
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "Three"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "One"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Three"));
try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Two"));
}
@@ -717,8 +717,8 @@ test "peer type resolution: error union and error set" {
const error_set_info = @typeInfo(info.ErrorUnion.error_set);
try expect(error_set_info.ErrorSet.?.len == 3);
try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Three"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Two"));
}
}
diff --git a/test/behavior/error.zig b/test/behavior/error.zig
index 7dd0d44e01..8541c7defd 100644
--- a/test/behavior/error.zig
+++ b/test/behavior/error.zig
@@ -330,7 +330,11 @@ fn intLiteral(str: []const u8) !?i64 {
}
test "nested error union function call in optional unwrap" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
const Foo = struct {
@@ -375,7 +379,11 @@ test "nested error union function call in optional unwrap" {
}
test "return function call to error set from error union function" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
fn errorable() anyerror!i32 {
@@ -404,7 +412,11 @@ test "optional error set is the same size as error set" {
}
test "nested catch" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
fn entry() !void {
@@ -428,11 +440,18 @@ test "nested catch" {
}
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
+ // This test uses the stage2 const fn pointer
+ if (builtin.zig_backend == .stage1) return error.SkipZigTest;
+
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
const Foo = struct {
- fun: fn (a: i32) (anyerror!*Foo),
+ fun: *const fn (a: i32) (anyerror!*Foo),
};
const Err = error{UnspecifiedErr};
@@ -480,7 +499,11 @@ test "return result loc as peer result loc in inferred error set function" {
}
test "error payload type is correctly resolved" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const MyIntWrapper = struct {
const Self = @This();
@@ -496,7 +519,11 @@ test "error payload type is correctly resolved" {
}
test "error union comptime caching" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
fn quux(comptime arg: anytype) void {
@@ -539,3 +566,69 @@ test "@errorName sentinel length matches slice length" {
pub fn testBuiltinErrorName(err: anyerror) [:0]const u8 {
return @errorName(err);
}
+
+test "error set equality" {
+ // This tests using stage2 logic (#11022)
+ if (builtin.zig_backend == .stage1) return error.SkipZigTest;
+
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+
+ const a = error{One};
+ const b = error{One};
+
+ try expect(a == a);
+ try expect(a == b);
+ try expect(a == error{One});
+
+ // should treat as a set
+ const c = error{ One, Two };
+ const d = error{ Two, One };
+
+ try expect(c == d);
+}
+
+test "inferred error set equality" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+
+ const S = struct {
+ fn foo() !void {
+ return @This().bar();
+ }
+
+ fn bar() !void {
+ return error.Bad;
+ }
+
+ fn baz() !void {
+ return quux();
+ }
+
+ fn quux() anyerror!void {}
+ };
+
+ const FooError = @typeInfo(@typeInfo(@TypeOf(S.foo)).Fn.return_type.?).ErrorUnion.error_set;
+ const BarError = @typeInfo(@typeInfo(@TypeOf(S.bar)).Fn.return_type.?).ErrorUnion.error_set;
+ const BazError = @typeInfo(@typeInfo(@TypeOf(S.baz)).Fn.return_type.?).ErrorUnion.error_set;
+
+ try expect(BarError != error{Bad});
+
+ try expect(FooError != anyerror);
+ try expect(BarError != anyerror);
+ try expect(BazError != anyerror);
+
+ try expect(FooError != BarError);
+ try expect(FooError != BazError);
+ try expect(BarError != BazError);
+
+ try expect(FooError == FooError);
+ try expect(BarError == BarError);
+ try expect(BazError == BazError);
+}
diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig
index ad8fe03c15..8b917ad5e1 100644
--- a/test/behavior/type_info.zig
+++ b/test/behavior/type_info.zig
@@ -205,6 +205,9 @@ test "type info: error set single value" {
}
test "type info: error set merged" {
+ // #11022 forces ordering of error sets in stage2
+ if (builtin.zig_backend == .stage1) return error.SkipZigTest;
+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
@@ -217,8 +220,8 @@ test "type info: error set merged" {
try expect(error_set_info == .ErrorSet);
try expect(error_set_info.ErrorSet.?.len == 3);
try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two"));
- try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Three"));
+ try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Two"));
}
test "type info: enum info" {
diff --git a/test/stage2/x86_64.zig b/test/stage2/x86_64.zig
index aeed29bf43..458289e06e 100644
--- a/test/stage2/x86_64.zig
+++ b/test/stage2/x86_64.zig
@@ -1413,25 +1413,6 @@ pub fn addCases(ctx: *TestContext) !void {
}
{
- var case = ctx.exe("error set equality", target);
-
- case.addCompareOutput(
- \\pub fn main() void {
- \\ assert(@TypeOf(error.Foo) == @TypeOf(error.Foo));
- \\ assert(@TypeOf(error.Bar) != @TypeOf(error.Foo));
- \\ assert(anyerror == anyerror);
- \\ assert(error{Foo} != error{Foo});
- \\ // TODO put inferred error sets here when @typeInfo works
- \\}
- \\fn assert(b: bool) void {
- \\ if (!b) unreachable;
- \\}
- ,
- "",
- );
- }
-
- {
var case = ctx.exe("comptime var", target);
case.addError(