Skip to content

Commit 13ebc61

Browse files
committed
Sema: fix auto-numbered enums with signed tag types
Closes #16095
1 parent 45fad89 commit 13ebc61

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/InternPool.zig

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -812,11 +812,6 @@ test "signed integer as enum tag" {
812812
try expect(@intFromEnum(SignedEnum.A2) == 1);
813813
}
814814

815-
test "int to enum with signed tag type" {
816-
const E = enum(i32) { a, b, c };
817-
try expect(@intToEnum(E, 0) == .a);
818-
}
819-
820815
test "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+
1201+
test "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+
}

0 commit comments

Comments
 (0)