Skip to content

Commit abf9934

Browse files
committed
Sema: fix auto-numbered enums with signed tag types
Closes ziglang#16095
1 parent 6a493c8 commit abf9934

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,3 +1202,18 @@ test "enum tag from a local variable" {
12021202
const i = @intToEnum(S.Int(u32), 0);
12031203
try std.testing.expect(@enumToInt(i) == 0);
12041204
}
1205+
1206+
test "auto-numbered enum with signed tag type" {
1207+
const E = enum(i32) { a, b };
1208+
1209+
try std.testing.expectEqual(@as(i32, 0), @enumToInt(E.a));
1210+
try std.testing.expectEqual(@as(i32, 1), @enumToInt(E.b));
1211+
try std.testing.expectEqual(E.a, @intToEnum(E, 0));
1212+
try std.testing.expectEqual(E.b, @intToEnum(E, 1));
1213+
try std.testing.expectEqual(E.a, @intToEnum(E, @as(i32, 0)));
1214+
try std.testing.expectEqual(E.b, @intToEnum(E, @as(i32, 1)));
1215+
try std.testing.expectEqual(E.a, @intToEnum(E, @as(u32, 0)));
1216+
try std.testing.expectEqual(E.b, @intToEnum(E, @as(u32, 1)));
1217+
try std.testing.expectEqualStrings("a", @tagName(E.a));
1218+
try std.testing.expectEqualStrings("b", @tagName(E.b));
1219+
}

0 commit comments

Comments
 (0)