mirror of
https://github.com/ziglang/zig.git
synced 2025-12-17 11:43:16 +00:00
Sema: improve behavior of comptime_int backed enums
This commit is contained in:
parent
a9cdacff95
commit
f281f3d10e
@ -2565,7 +2565,7 @@ fn zirEnumDecl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (small.nonexhaustive) {
|
if (small.nonexhaustive and enum_obj.tag_ty.zigTypeTag() != .ComptimeInt) {
|
||||||
if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(sema.mod.getTarget())) {
|
if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(sema.mod.getTarget())) {
|
||||||
return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
|
return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
|
||||||
}
|
}
|
||||||
@ -20363,12 +20363,13 @@ fn validateRunTimeType(
|
|||||||
.Int,
|
.Int,
|
||||||
.Float,
|
.Float,
|
||||||
.ErrorSet,
|
.ErrorSet,
|
||||||
.Enum,
|
|
||||||
.Frame,
|
.Frame,
|
||||||
.AnyFrame,
|
.AnyFrame,
|
||||||
.Void,
|
.Void,
|
||||||
=> return true,
|
=> return true,
|
||||||
|
|
||||||
|
.Enum => return !(try sema.typeRequiresComptime(block, src, ty)),
|
||||||
|
|
||||||
.BoundFn,
|
.BoundFn,
|
||||||
.ComptimeFloat,
|
.ComptimeFloat,
|
||||||
.ComptimeInt,
|
.ComptimeInt,
|
||||||
@ -29049,7 +29050,7 @@ pub fn typeHasOnePossibleValue(
|
|||||||
},
|
},
|
||||||
.enum_nonexhaustive => {
|
.enum_nonexhaustive => {
|
||||||
const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
|
const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
|
||||||
if (!(try sema.typeHasRuntimeBits(block, src, tag_ty))) {
|
if (tag_ty.zigTypeTag() != .ComptimeInt and !(try sema.typeHasRuntimeBits(block, src, tag_ty))) {
|
||||||
return Value.zero;
|
return Value.zero;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -1175,3 +1175,10 @@ test "Non-exhaustive enum with nonstandard int size behaves correctly" {
|
|||||||
const E = enum(u15) { _ };
|
const E = enum(u15) { _ };
|
||||||
try expect(@sizeOf(E) == @sizeOf(u15));
|
try expect(@sizeOf(E) == @sizeOf(u15));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Non-exhaustive enum backed by comptime_int" {
|
||||||
|
const E = enum(comptime_int) { a, b, c, _ };
|
||||||
|
comptime var e: E = .a;
|
||||||
|
e = @intToEnum(E, 378089457309184723749);
|
||||||
|
try expect(@enumToInt(e) == 378089457309184723749);
|
||||||
|
}
|
||||||
|
|||||||
@ -690,7 +690,7 @@ test "union with only 1 field casted to its enum type which has enum value speci
|
|||||||
|
|
||||||
var e = Expr{ .Literal = Literal{ .Bool = true } };
|
var e = Expr{ .Literal = Literal{ .Bool = true } };
|
||||||
comptime try expect(Tag(ExprTag) == comptime_int);
|
comptime try expect(Tag(ExprTag) == comptime_int);
|
||||||
var t = @as(ExprTag, e);
|
comptime var t = @as(ExprTag, e);
|
||||||
try expect(t == Expr.Literal);
|
try expect(t == Expr.Literal);
|
||||||
try expect(@enumToInt(t) == 33);
|
try expect(@enumToInt(t) == 33);
|
||||||
comptime try expect(@enumToInt(t) == 33);
|
comptime try expect(@enumToInt(t) == 33);
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
pub export fn entry() void {
|
||||||
|
const E = enum(comptime_int) { a, b, c, _ };
|
||||||
|
var e: E = .a;
|
||||||
|
_ = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :3:12: error: variable of type 'tmp.entry.E' must be const or comptime
|
||||||
Loading…
x
Reference in New Issue
Block a user