authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-02 16:08:20+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-02 17:57:11+03:00
logf281f3d10e4eaedc7c68afc4fcbbfd35e1f29a0f
tree3a28628a95126b07fe7fa17e12ff3cbab1e9df65
parenta9cdacff95a2a6f60945c7b2a299f9f66bd94ddb

Sema: improve behavior of comptime_int backed enums


4 files changed, 23 insertions(+), 4 deletions(-)

src/Sema.zig+4-3
...@@ -2565,7 +2565,7 @@ fn zirEnumDecl(...@@ -2565,7 +2565,7 @@ fn zirEnumDecl(
2565 }2565 }
2566 }2566 }
25672567
2568 if (small.nonexhaustive) {2568 if (small.nonexhaustive and enum_obj.tag_ty.zigTypeTag() != .ComptimeInt) {
2569 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(sema.mod.getTarget())) {2569 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(sema.mod.getTarget())) {
2570 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});2570 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
2571 }2571 }
...@@ -20363,12 +20363,13 @@ fn validateRunTimeType(...@@ -20363,12 +20363,13 @@ fn validateRunTimeType(
20363 .Int,20363 .Int,
20364 .Float,20364 .Float,
20365 .ErrorSet,20365 .ErrorSet,
20366 .Enum,
20367 .Frame,20366 .Frame,
20368 .AnyFrame,20367 .AnyFrame,
20369 .Void,20368 .Void,
20370 => return true,20369 => return true,
2037120370
20371 .Enum => return !(try sema.typeRequiresComptime(block, src, ty)),
20372
20372 .BoundFn,20373 .BoundFn,
20373 .ComptimeFloat,20374 .ComptimeFloat,
20374 .ComptimeInt,20375 .ComptimeInt,
...@@ -29049,7 +29050,7 @@ pub fn typeHasOnePossibleValue(...@@ -29049,7 +29050,7 @@ pub fn typeHasOnePossibleValue(
29049 },29050 },
29050 .enum_nonexhaustive => {29051 .enum_nonexhaustive => {
29051 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;29052 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
29052 if (!(try sema.typeHasRuntimeBits(block, src, tag_ty))) {29053 if (tag_ty.zigTypeTag() != .ComptimeInt and !(try sema.typeHasRuntimeBits(block, src, tag_ty))) {
29053 return Value.zero;29054 return Value.zero;
29054 } else {29055 } else {
29055 return null;29056 return null;
test/behavior/enum.zig+7
...@@ -1175,3 +1175,10 @@ test "Non-exhaustive enum with nonstandard int size behaves correctly" {...@@ -1175,3 +1175,10 @@ test "Non-exhaustive enum with nonstandard int size behaves correctly" {
1175 const E = enum(u15) { _ };1175 const E = enum(u15) { _ };
1176 try expect(@sizeOf(E) == @sizeOf(u15));1176 try expect(@sizeOf(E) == @sizeOf(u15));
1177}1177}
1178
1179test "Non-exhaustive enum backed by comptime_int" {
1180 const E = enum(comptime_int) { a, b, c, _ };
1181 comptime var e: E = .a;
1182 e = @intToEnum(E, 378089457309184723749);
1183 try expect(@enumToInt(e) == 378089457309184723749);
1184}
test/behavior/union.zig+1-1
...@@ -690,7 +690,7 @@ test "union with only 1 field casted to its enum type which has enum value speci...@@ -690,7 +690,7 @@ test "union with only 1 field casted to its enum type which has enum value speci
690690
691 var e = Expr{ .Literal = Literal{ .Bool = true } };691 var e = Expr{ .Literal = Literal{ .Bool = true } };
692 comptime try expect(Tag(ExprTag) == comptime_int);692 comptime try expect(Tag(ExprTag) == comptime_int);
693 var t = @as(ExprTag, e);693 comptime var t = @as(ExprTag, e);
694 try expect(t == Expr.Literal);694 try expect(t == Expr.Literal);
695 try expect(@enumToInt(t) == 33);695 try expect(@enumToInt(t) == 33);
696 comptime try expect(@enumToInt(t) == 33);696 comptime try expect(@enumToInt(t) == 33);
test/cases/compile_errors/enum_backed_by_comptime_int_must_be_comptime.zig created+11
...@@ -0,0 +1,11 @@
1pub export fn entry() void {
2 const E = enum(comptime_int) { a, b, c, _ };
3 var e: E = .a;
4 _ = e;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :3:12: error: variable of type 'tmp.entry.E' must be const or comptime