diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 91978c6dde24..fab32b10d9c7 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -1242,3 +1242,24 @@ test "Non-exhaustive enum backed by comptime_int" { e = @as(E, @enumFromInt(378089457309184723749)); try expect(@intFromEnum(e) == 378089457309184723749); } + +test "matching captures causes enum equivalence" { + const S = struct { + fn Nonexhaustive(comptime I: type) type { + const UTag = @Type(.{ .Int = .{ + .signedness = .unsigned, + .bits = @typeInfo(I).Int.bits, + } }); + return enum(UTag) { _ }; + } + }; + + comptime assert(S.Nonexhaustive(u8) == S.Nonexhaustive(i8)); + comptime assert(S.Nonexhaustive(u16) == S.Nonexhaustive(i16)); + comptime assert(S.Nonexhaustive(u8) != S.Nonexhaustive(u16)); + + const a: S.Nonexhaustive(u8) = @enumFromInt(123); + const b: S.Nonexhaustive(i8) = @enumFromInt(123); + comptime assert(@TypeOf(a) == @TypeOf(b)); + try expect(@intFromEnum(a) == @intFromEnum(b)); +} diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 9f4d3f0298b2..f85e783342a1 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -2127,3 +2127,26 @@ test "struct containing optional pointer to array of @This()" { _ = &s; try expect(s.x.?[0].x == null); } + +test "matching captures causes struct equivalence" { + const S = struct { + fn UnsignedWrapper(comptime I: type) type { + const bits = @typeInfo(I).Int.bits; + return struct { + x: @Type(.{ .Int = .{ + .signedness = .unsigned, + .bits = bits, + } }), + }; + } + }; + + comptime assert(S.UnsignedWrapper(u8) == S.UnsignedWrapper(i8)); + comptime assert(S.UnsignedWrapper(u16) == S.UnsignedWrapper(i16)); + comptime assert(S.UnsignedWrapper(u8) != S.UnsignedWrapper(u16)); + + const a: S.UnsignedWrapper(u8) = .{ .x = 10 }; + const b: S.UnsignedWrapper(i8) = .{ .x = 10 }; + comptime assert(@TypeOf(a) == @TypeOf(b)); + try expect(a.x == b.x); +} diff --git a/test/behavior/type.zig b/test/behavior/type.zig index 1ce31fecfd59..d1310a216724 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -2,6 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); const Type = std.builtin.Type; const testing = std.testing; +const assert = std.debug.assert; fn testTypes(comptime types: []const type) !void { inline for (types) |testType| { @@ -734,3 +735,28 @@ test "struct field names sliced at comptime from larger string" { try testing.expectEqualStrings("f3", gen_fields[2].name); } } + +test "matching captures causes opaque equivalence" { + const S = struct { + fn UnsignedId(comptime I: type) type { + const U = @Type(.{ .Int = .{ + .signedness = .unsigned, + .bits = @typeInfo(I).Int.bits, + } }); + return opaque { + fn id(x: U) U { + return x; + } + }; + } + }; + + comptime assert(S.UnsignedId(u8) == S.UnsignedId(i8)); + comptime assert(S.UnsignedId(u16) == S.UnsignedId(i16)); + comptime assert(S.UnsignedId(u8) != S.UnsignedId(u16)); + + const a = S.UnsignedId(u8).id(123); + const b = S.UnsignedId(i8).id(123); + comptime assert(@TypeOf(a) == @TypeOf(b)); + try testing.expect(a == b); +} diff --git a/test/behavior/union.zig b/test/behavior/union.zig index fa050d36be24..bd92a5221789 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -2273,3 +2273,30 @@ test "create union(enum) from other union(enum)" { else => {}, } } + +test "matching captures causes union equivalence" { + const S = struct { + fn SignedUnsigned(comptime I: type) type { + const bits = @typeInfo(I).Int.bits; + return union { + u: @Type(.{ .Int = .{ + .signedness = .unsigned, + .bits = bits, + } }), + i: @Type(.{ .Int = .{ + .signedness = .signed, + .bits = bits, + } }), + }; + } + }; + + comptime assert(S.SignedUnsigned(u8) == S.SignedUnsigned(i8)); + comptime assert(S.SignedUnsigned(u16) == S.SignedUnsigned(i16)); + comptime assert(S.SignedUnsigned(u8) != S.SignedUnsigned(u16)); + + const a: S.SignedUnsigned(u8) = .{ .u = 10 }; + const b: S.SignedUnsigned(i8) = .{ .u = 10 }; + comptime assert(@TypeOf(a) == @TypeOf(b)); + try expect(a.u == b.u); +}