| ... | @@ -7372,9 +7372,23 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -7372,9 +7372,23 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7372 | return sema.addConstant(dest_ty, int_val); | 7372 | return sema.addConstant(dest_ty, int_val); |
| 7373 | } | 7373 | } |
| 7374 | | 7374 | |
| | 7375 | if (try sema.typeHasOnePossibleValue(block, operand_src, dest_ty)) |opv| { |
| | 7376 | const result = try sema.addConstant(dest_ty, opv); |
| | 7377 | // The operand is runtime-known but the result is comptime-known. In |
| | 7378 | // this case we still need a safety check. |
| | 7379 | // TODO add a safety check here. we can't use is_named_enum_value - |
| | 7380 | // it needs to convert the enum back to int and make sure it equals the operand int. |
| | 7381 | return result; |
| | 7382 | } |
| | 7383 | |
| 7375 | try sema.requireRuntimeBlock(block, src, operand_src); | 7384 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 7376 | const result = try block.addTyOp(.intcast, dest_ty, operand); | 7385 | const result = try block.addTyOp(.intcast, dest_ty, operand); |
| 7377 | if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum() and sema.mod.comp.bin_file.options.use_llvm) { | 7386 | if (block.wantSafety() and |
| | 7387 | !dest_ty.isNonexhaustiveEnum() and |
| | 7388 | // TODO instead of "use_llvm", check a different condition so that backends |
| | 7389 | // can advertise themselves as supporting these extra AIR instructions for safety. |
| | 7390 | sema.mod.comp.bin_file.options.use_llvm) |
| | 7391 | { |
| 7378 | const ok = try block.addUnOp(.is_named_enum_value, result); | 7392 | const ok = try block.addUnOp(.is_named_enum_value, result); |
| 7379 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); | 7393 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); |
| 7380 | } | 7394 | } |