commit 326d51e30e9439ee7a4e2b0b44a186273312fa06 (tree)
parent 8538d0b27b5b2819d1c7018f10aa242ee826b270
Author: Motiejus <motiejus@jakstys.lt>
Date: Sat, 7 Mar 2026 08:08:28 +0000
sema: fix semaCoerce comptime_float → integer coercion
Add the float-to-integer coercion path: convert the float value to an
integer (truncating toward zero) and intern it with the target type.
Previously, comptime_float coercion to integer types was silently
ignored, returning the original float ref unchanged.
Also restructure the comptime_float case to explicitly separate
float→float from float→int paths.
Matches src/Sema.zig coerce: getCoerced(val, dst_ty) for float→int.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -711,17 +711,38 @@ static AirInstRef semaCoerce(
return ref;
if (src_ty == IP_INDEX_COMPTIME_INT_TYPE)
return semaCoerceIntRef(sema, ref, target_ty);
- // Comptime float → concrete float: re-intern with target type.
- // Ported from src/Sema.zig coerce comptime_float → float.
+ // Comptime float → concrete float or integer coercion.
+ // Ported from src/Sema.zig coerce comptime_float path.
if (src_ty == IP_INDEX_COMPTIME_FLOAT_TYPE && AIR_REF_IS_IP(ref)) {
InternPoolKey src_key = ipIndexToKey(sema->ip, AIR_REF_TO_IP(ref));
if (src_key.tag == IP_KEY_FLOAT) {
- InternPoolKey key;
- memset(&key, 0, sizeof(key));
- key.tag = IP_KEY_FLOAT;
- key.data.float_val.ty = target_ty;
- key.data.float_val.val = src_key.data.float_val.val;
- return AIR_REF_FROM_IP(ipIntern(sema->ip, key));
+ double fval = src_key.data.float_val.val;
+ // Float → concrete float: re-intern with target type.
+ if (floatBits(target_ty) > 0) {
+ InternPoolKey key;
+ memset(&key, 0, sizeof(key));
+ key.tag = IP_KEY_FLOAT;
+ key.data.float_val.ty = target_ty;
+ key.data.float_val.val = fval;
+ return AIR_REF_FROM_IP(ipIntern(sema->ip, key));
+ }
+ // Float → concrete integer: convert (truncate) float to int.
+ // Ported from src/Sema.zig coerce comptime_float → int path.
+ if (isIntegerType(sema->ip, target_ty)) {
+ int64_t ival = (int64_t)fval;
+ InternPoolKey key;
+ memset(&key, 0, sizeof(key));
+ key.tag = IP_KEY_INT;
+ key.data.int_val.ty = target_ty;
+ if (ival < 0) {
+ key.data.int_val.value_lo = (uint64_t)(-ival);
+ key.data.int_val.is_negative = true;
+ } else {
+ key.data.int_val.value_lo = (uint64_t)ival;
+ key.data.int_val.is_negative = false;
+ }
+ return AIR_REF_FROM_IP(ipIntern(sema->ip, key));
+ }
}
}
// Undefined coercion: re-intern undefined with the target type.