mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Sema: fix runtime int to enum with one possible value
This commit is contained in:
parent
d0a5ad0e4c
commit
7c7d9e13d7
16
src/Sema.zig
16
src/Sema.zig
@ -7372,9 +7372,23 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
|||||||
return sema.addConstant(dest_ty, int_val);
|
return sema.addConstant(dest_ty, int_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (try sema.typeHasOnePossibleValue(block, operand_src, dest_ty)) |opv| {
|
||||||
|
const result = try sema.addConstant(dest_ty, opv);
|
||||||
|
// The operand is runtime-known but the result is comptime-known. In
|
||||||
|
// this case we still need a safety check.
|
||||||
|
// TODO add a safety check here. we can't use is_named_enum_value -
|
||||||
|
// it needs to convert the enum back to int and make sure it equals the operand int.
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||||
const result = try block.addTyOp(.intcast, dest_ty, operand);
|
const result = try block.addTyOp(.intcast, dest_ty, operand);
|
||||||
if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum() and sema.mod.comp.bin_file.options.use_llvm) {
|
if (block.wantSafety() and
|
||||||
|
!dest_ty.isNonexhaustiveEnum() and
|
||||||
|
// TODO instead of "use_llvm", check a different condition so that backends
|
||||||
|
// can advertise themselves as supporting these extra AIR instructions for safety.
|
||||||
|
sema.mod.comp.bin_file.options.use_llvm)
|
||||||
|
{
|
||||||
const ok = try block.addUnOp(.is_named_enum_value, result);
|
const ok = try block.addUnOp(.is_named_enum_value, result);
|
||||||
try sema.addSafetyCheck(block, ok, .invalid_enum_value);
|
try sema.addSafetyCheck(block, ok, .invalid_enum_value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1169,3 +1169,11 @@ 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 "runtime int to enum with one possible value" {
|
||||||
|
const E = enum { one };
|
||||||
|
var runtime: usize = 0;
|
||||||
|
if (@intToEnum(E, runtime) != .one) {
|
||||||
|
@compileError("test failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user