aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-10 14:17:27 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-03-10 14:21:37 -0700
commit9f163310f2bfa4f5289c1db6231089f3be0c9b93 (patch)
treea3e6012d38c15d34c847773c27189c8a4f1edadb /src/type.zig
parent569870ca41e73c64d8dc9f1eccfef3529caf2266 (diff)
downloadzig-9f163310f2bfa4f5289c1db6231089f3be0c9b93.tar.gz
zig-9f163310f2bfa4f5289c1db6231089f3be0c9b93.zip
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.
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig45
1 files changed, 22 insertions, 23 deletions
diff --git a/src/type.zig b/src/type.zig
index 9126f1213b..e35006d930 100644
--- a/src/type.zig
+++ b/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" => {