authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-20 11:40:14-04:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-06-20 20:09:28-07:00
log8875efe54873b721cc3a6f6d83525b19d1c59ec3
treecfc48f81d16e591f69bd99a1c7184ebbc1480209
parent3267eb3a28f6c747772a40beedac14f5feae814f

Sema: fix auto-numbered enums with signed tag types

Closes #16095

2 files changed, 20 insertions(+), 16 deletions(-)

src/InternPool.zig+5-11
......@@ -443,18 +443,12 @@ pub const Key = union(enum) {
443443 return @intCast(u32, field_index);
444444 }
445445 // Auto-numbered enum. Convert `int_tag_val` to field index.
446 switch (ip.indexToKey(int_tag_val).int.storage) {
447 .u64 => |x| {
448 if (x >= self.names.len) return null;
449 return @intCast(u32, x);
450 },
451 .i64 => |x| {
452 if (x >= self.names.len or x < 0) return null;
453 return @intCast(u32, x);
454 },
455 .big_int => return null, // out of range
446 const field_index = switch (ip.indexToKey(int_tag_val).int.storage) {
447 inline .u64, .i64 => |x| std.math.cast(u32, x) orelse return null,
448 .big_int => |x| x.to(u32) catch return null,
456449 .lazy_align, .lazy_size => unreachable,
457 }
450 };
451 return if (field_index < self.names.len) field_index else null;
458452 }
459453 };
460454
test/behavior/enum.zig+15-5
......@@ -812,11 +812,6 @@ test "signed integer as enum tag" {
812812 try expect(@intFromEnum(SignedEnum.A2) == 1);
813813}
814814
815test "int to enum with signed tag type" {
816 const E = enum(i32) { a, b, c };
817 try expect(@intToEnum(E, 0) == .a);
818}
819
820815test "enum with one member and custom tag type" {
821816 const E = enum(u2) {
822817 One,
......@@ -1202,3 +1197,18 @@ test "enum tag from a local variable" {
12021197 const i = @enumFromInt(S.Int(u32), 0);
12031198 try std.testing.expect(@intFromEnum(i) == 0);
12041199}
1200
1201test "auto-numbered enum with signed tag type" {
1202 const E = enum(i32) { a, b };
1203
1204 try std.testing.expectEqual(@as(i32, 0), @intFromEnum(E.a));
1205 try std.testing.expectEqual(@as(i32, 1), @intFromEnum(E.b));
1206 try std.testing.expectEqual(E.a, @enumFromInt(E, 0));
1207 try std.testing.expectEqual(E.b, @enumFromInt(E, 1));
1208 try std.testing.expectEqual(E.a, @enumFromInt(E, @as(i32, 0)));
1209 try std.testing.expectEqual(E.b, @enumFromInt(E, @as(i32, 1)));
1210 try std.testing.expectEqual(E.a, @enumFromInt(E, @as(u32, 0)));
1211 try std.testing.expectEqual(E.b, @enumFromInt(E, @as(u32, 1)));
1212 try std.testing.expectEqualStrings("a", @tagName(E.a));
1213 try std.testing.expectEqualStrings("b", @tagName(E.b));
1214}