Sema: fix auto-numbered enums with signed tag types

Closes #16095
This commit is contained in:
Jacob Young
2023-06-20 11:40:14 -04:00
committed by Veikka Tuominen
parent 3267eb3a28
commit 8875efe548
2 changed files with 20 additions and 16 deletions

View File

@@ -443,18 +443,12 @@ pub const Key = union(enum) {
return @intCast(u32, field_index);
}
// Auto-numbered enum. Convert `int_tag_val` to field index.
switch (ip.indexToKey(int_tag_val).int.storage) {
.u64 => |x| {
if (x >= self.names.len) return null;
return @intCast(u32, x);
},
.i64 => |x| {
if (x >= self.names.len or x < 0) return null;
return @intCast(u32, x);
},
.big_int => return null, // out of range
const field_index = switch (ip.indexToKey(int_tag_val).int.storage) {
inline .u64, .i64 => |x| std.math.cast(u32, x) orelse return null,
.big_int => |x| x.to(u32) catch return null,
.lazy_align, .lazy_size => unreachable,
}
};
return if (field_index < self.names.len) field_index else null;
}
};

View File

@@ -812,11 +812,6 @@ test "signed integer as enum tag" {
try expect(@intFromEnum(SignedEnum.A2) == 1);
}
test "int to enum with signed tag type" {
const E = enum(i32) { a, b, c };
try expect(@intToEnum(E, 0) == .a);
}
test "enum with one member and custom tag type" {
const E = enum(u2) {
One,
@@ -1202,3 +1197,18 @@ test "enum tag from a local variable" {
const i = @enumFromInt(S.Int(u32), 0);
try std.testing.expect(@intFromEnum(i) == 0);
}
test "auto-numbered enum with signed tag type" {
const E = enum(i32) { a, b };
try std.testing.expectEqual(@as(i32, 0), @intFromEnum(E.a));
try std.testing.expectEqual(@as(i32, 1), @intFromEnum(E.b));
try std.testing.expectEqual(E.a, @enumFromInt(E, 0));
try std.testing.expectEqual(E.b, @enumFromInt(E, 1));
try std.testing.expectEqual(E.a, @enumFromInt(E, @as(i32, 0)));
try std.testing.expectEqual(E.b, @enumFromInt(E, @as(i32, 1)));
try std.testing.expectEqual(E.a, @enumFromInt(E, @as(u32, 0)));
try std.testing.expectEqual(E.b, @enumFromInt(E, @as(u32, 1)));
try std.testing.expectEqualStrings("a", @tagName(E.a));
try std.testing.expectEqualStrings("b", @tagName(E.b));
}