aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/type.zig8
-rw-r--r--src/value.zig19
2 files changed, 27 insertions, 0 deletions
diff --git a/src/type.zig b/src/type.zig
index ccf1b37471..68085500bc 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -2934,6 +2934,14 @@ pub const Type = extern union {
};
}
+ /// Asserts the type is a union; returns the tag type, even if the tag will
+ /// not be stored at runtime.
+ pub fn unionTagTypeHypothetical(ty: Type) Type {
+ const union_obj = ty.cast(Payload.Union).?.data;
+ assert(union_obj.haveFieldTypes());
+ return union_obj.tag_ty;
+ }
+
pub fn unionFields(ty: Type) Module.Union.Fields {
const union_obj = ty.cast(Payload.Union).?.data;
assert(union_obj.haveFieldTypes());
diff --git a/src/value.zig b/src/value.zig
index 7c28398b73..9d2d73928b 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -1902,6 +1902,25 @@ pub const Value = extern union {
}
return true;
},
+ .@"union" => {
+ const a_union = a.castTag(.@"union").?.data;
+ const b_union = b.castTag(.@"union").?.data;
+ switch (ty.containerLayout()) {
+ .Packed, .Extern => {
+ // In this case, we must disregard mismatching tags and compare
+ // based on the in-memory bytes of the payloads.
+ @panic("TODO implement comparison of extern union values");
+ },
+ .Auto => {
+ const tag_ty = ty.unionTagTypeHypothetical();
+ if (!a_union.tag.eql(b_union.tag, tag_ty)) {
+ return false;
+ }
+ const active_field_ty = ty.unionFieldType(a_union.tag);
+ return a_union.val.eql(b_union.val, active_field_ty);
+ },
+ }
+ },
else => {},
} else if (a_tag == .null_value or b_tag == .null_value) {
return false;