commit 911f411886cd740db4939adb9eec05cffb655df0 (tree)
parent 7b27dc60f3d251d418ff80131d43730c6afe5964
Author: AdriĆ Arrufat <adria.arrufat@gmail.com>
Date: Fri, 20 Mar 2026 15:40:36 +0900
Sema: improve type validation in zirRoundCast
Diffstat:
| M | src/Sema.zig | | | 56 | ++++++++++++++++++++++++++++++++------------------------ |
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -20881,33 +20881,41 @@ 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,
- };
+ try sema.checkFloatType(block, operand_src, operand_scalar_ty);
- if (result_ref) |ref| return ref;
+ switch (dest_scalar_ty.zigTypeTag(zcu)) {
+ .float, .comptime_float => {
+ const coerced_operand = try sema.coerce(block, dest_ty, operand, operand_src);
- const air_tag: Air.Inst.Tag = switch (mode) {
- .round => .round,
- .floor => .floor,
- .ceil => .ceil,
- .truncate => .trunc_float,
- else => unreachable,
- };
+ 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,
+ };
- try sema.requireRuntimeBlock(block, operand_src, null);
- return block.addUnOp(air_tag, coerced_operand);
- }
+ if (result_ref) |ref| return ref;
- _ = try sema.checkIntType(block, src, dest_scalar_ty);
- try sema.checkFloatType(block, operand_src, operand_scalar_ty);
+ 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);
@@ -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);