| author | |
| committer | |
| log | f281f3d10e4eaedc7c68afc4fcbbfd35e1f29a0f |
| tree | 3a28628a95126b07fe7fa17e12ff3cbab1e9df65 |
| parent | a9cdacff95a2a6f60945c7b2a299f9f66bd94ddb |
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 | } |
| 2567 | 2567 | ||
| 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, |
| 20371 | 20370 | ||
| 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 | |||
| 1179 | test "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 |
| 690 | 690 | ||
| 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 @@ | ||
| 1 | pub 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 | ||