mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
stage2: improve Type.eql and Type.hash for error sets
* Reduce branching in Type.eql and Type.hash for error sets. * `Type.eql` uses element-wise bytes comparison since it can rely on the error sets being pre-sorted. * Avoid unnecessarily skipping tests that are passing.
This commit is contained in:
parent
569870ca41
commit
9f163310f2
45
src/type.zig
45
src/type.zig
@ -556,37 +556,36 @@ pub const Type = extern union {
|
||||
return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits;
|
||||
},
|
||||
|
||||
.error_set_inferred => {
|
||||
// Inferred error sets are only equal if both are inferred
|
||||
// and they originate from the exact same function.
|
||||
const a_set = a.castTag(.error_set_inferred).?.data;
|
||||
const b_set = (b.castTag(.error_set_inferred) orelse return false).data;
|
||||
return a_set.func == b_set.func;
|
||||
},
|
||||
|
||||
.anyerror => {
|
||||
return b.tag() == .anyerror;
|
||||
},
|
||||
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.anyerror,
|
||||
.error_set_inferred,
|
||||
.error_set_merged,
|
||||
=> {
|
||||
if (b.zigTypeTag() != .ErrorSet) return false;
|
||||
|
||||
// inferred error sets are only equal if both are inferred
|
||||
// and they originate from the exact same function.
|
||||
if (a.castTag(.error_set_inferred)) |a_pl| {
|
||||
if (b.castTag(.error_set_inferred)) |b_pl| {
|
||||
return a_pl.data.func == b_pl.data.func;
|
||||
}
|
||||
return false;
|
||||
switch (b.tag()) {
|
||||
.error_set, .error_set_single, .error_set_merged => {},
|
||||
else => return false,
|
||||
}
|
||||
if (b.tag() == .error_set_inferred) return false;
|
||||
|
||||
// anyerror matches exactly.
|
||||
const a_is_any = a.isAnyError();
|
||||
const b_is_any = b.isAnyError();
|
||||
if (a_is_any or b_is_any) return a_is_any and b_is_any;
|
||||
|
||||
// two resolved sets match if their error set names match.
|
||||
// Two resolved sets match if their error set names match.
|
||||
// Since they are pre-sorted we compare them element-wise.
|
||||
const a_set = a.errorSetNames();
|
||||
const b_set = b.errorSetNames();
|
||||
if (a_set.len != b_set.len) return false;
|
||||
for (b_set) |b_val| {
|
||||
if (!a.errorSetHasField(b_val)) return false;
|
||||
for (a_set) |a_item, i| {
|
||||
const b_item = b_set[i];
|
||||
if (!std.mem.eql(u8, a_item, b_item)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -984,10 +983,10 @@ pub const Type = extern union {
|
||||
|
||||
.error_set_inferred => {
|
||||
// inferred error sets are compared using their data pointer
|
||||
const data = ty.castTag(.error_set_inferred).?.data.func;
|
||||
const set = ty.castTag(.error_set_inferred).?.data;
|
||||
std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet);
|
||||
std.hash.autoHash(hasher, Tag.error_set_inferred);
|
||||
std.hash.autoHash(hasher, data);
|
||||
std.hash.autoHash(hasher, set.func);
|
||||
},
|
||||
|
||||
.@"opaque" => {
|
||||
|
||||
@ -330,11 +330,11 @@ fn intLiteral(str: []const u8) !?i64 {
|
||||
}
|
||||
|
||||
test "nested error union function call in optional unwrap" {
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const Foo = struct {
|
||||
@ -381,9 +381,9 @@ test "nested error union function call in optional unwrap" {
|
||||
test "return function call to error set from error union function" {
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn errorable() anyerror!i32 {
|
||||
@ -414,9 +414,9 @@ test "optional error set is the same size as error set" {
|
||||
test "nested catch" {
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn entry() !void {
|
||||
@ -440,14 +440,16 @@ test "nested catch" {
|
||||
}
|
||||
|
||||
test "function pointer with return type that is error union with payload which is pointer of parent struct" {
|
||||
// This test uses the stage2 const fn pointer
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
// stage1 has wrong function pointer semantics
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const Foo = struct {
|
||||
@ -501,9 +503,9 @@ test "return result loc as peer result loc in inferred error set function" {
|
||||
test "error payload type is correctly resolved" {
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const MyIntWrapper = struct {
|
||||
const Self = @This();
|
||||
@ -519,12 +521,6 @@ test "error payload type is correctly resolved" {
|
||||
}
|
||||
|
||||
test "error union comptime caching" {
|
||||
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 {
|
||||
arg catch {};
|
||||
@ -571,12 +567,6 @@ 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};
|
||||
|
||||
@ -592,11 +582,7 @@ test "error set equality" {
|
||||
}
|
||||
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn foo() !void {
|
||||
|
||||
@ -209,10 +209,8 @@ test "type info: error set merged" {
|
||||
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
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const TestSet = error{ One, Two } || error{Three};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user