From 911f411886cd740db4939adb9eec05cffb655df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Fri, 20 Mar 2026 15:40:36 +0900 Subject: [PATCH] Sema: improve type validation in zirRoundCast --- src/Sema.zig | 62 +++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 129b410886..aa9f47d4ea 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20881,34 +20881,42 @@ fn zirRoundCast( const dest_scalar_ty = dest_ty.scalarType(zcu); const operand_scalar_ty = operand_ty.scalarType(zcu); - if (dest_scalar_ty.zigTypeTag(zcu) == .float or dest_scalar_ty.zigTypeTag(zcu) == .comptime_float) { - const coerced_operand = try sema.coerce(block, dest_ty, operand, operand_src); - - const result_ref = switch (mode) { - .round => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.round), - .floor => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.floor), - .ceil => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.ceil), - .truncate => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.trunc), - else => unreachable, - }; - - if (result_ref) |ref| return ref; - - const air_tag: Air.Inst.Tag = switch (mode) { - .round => .round, - .floor => .floor, - .ceil => .ceil, - .truncate => .trunc_float, - else => unreachable, - }; - - try sema.requireRuntimeBlock(block, operand_src, null); - return block.addUnOp(air_tag, coerced_operand); - } - - _ = try sema.checkIntType(block, src, dest_scalar_ty); try sema.checkFloatType(block, operand_src, operand_scalar_ty); + switch (dest_scalar_ty.zigTypeTag(zcu)) { + .float, .comptime_float => { + const coerced_operand = try sema.coerce(block, dest_ty, operand, operand_src); + + const result_ref = switch (mode) { + .round => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.round), + .floor => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.floor), + .ceil => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.ceil), + .truncate => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.trunc), + .exact => unreachable, + }; + + if (result_ref) |ref| return ref; + + const air_tag: Air.Inst.Tag = switch (mode) { + .round => .round, + .floor => .floor, + .ceil => .ceil, + .truncate => .trunc_float, + .exact => unreachable, + }; + + try sema.requireRuntimeBlock(block, operand_src, null); + return block.addUnOp(air_tag, coerced_operand); + }, + .int, .comptime_int => {}, + else => return sema.fail( + block, + src, + "expected integer, float, or vector of either integers or floats, found '{f}'", + .{dest_ty.fmt(pt)}, + ), + } + if (sema.resolveValue(operand)) |operand_val| { const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, mode); return Air.internedToRef(result_val.toIntern()); @@ -20948,7 +20956,7 @@ fn zirRoundCast( .round => .round, .floor => .floor, .ceil => .ceil, - else => unreachable, + .truncate, .exact => unreachable, }; const rounded_op = try block.addUnOp(op_tag, operand);