authorgravatar for rue.nolastname@protonmail.comRue04 <rue.nolastname@protonmail.com> 2026-08-08 09:49:12+02:00
committergravatar for services@mlugg.co.ukmlugg <services@mlugg.co.uk> 2026-08-08 09:49:12+02:00
log94bdde8327608af23771fbca8486c2e5c189fa1e
tree00cba8e7ac4f7af824723091e24ae9ab1095a4f6
parent276f2e1b810aef048c3ce324e0977ba2d9ff8200

Sema: fix incorrect compile error for `@as(u32, @trunc(@floor(runtime_float)))`

If I had to guess, `Sema.zirRoundOpType` was probably written when `@trunc` etc. could only have a float as their destination type. As a result, for the ints they can cast to now, they'd expect the expression inside them to be a `comptime_float`, which made `@trunc(@floor(runtime_float))` or `@trunc(@floatFromInt(runtime_int))` impossible. By changing the returned type in this case to be generic poison, showing we don't know the expected type as *any* float can be converted to an int, `@trunc(@floor(runtime_float))` lowers to effectively `@floor(runtime_float)` and `@trunc(@floatFromInt(runtime_int))` throws the expected error that `@floatFromInt`'s result type is unknown here. Fixes: https://codeberg.org/ziglang/zig/issues/32111 Co-authored-by: rue04 <rue04@rue04.de> Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35664

2 files changed, 6 insertions(+), 4 deletions(-)

src/Sema.zig+4-4
......@@ -25542,10 +25542,10 @@ fn zirRoundOpType(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
2554225542 return .generic_poison_type;
2554325543 };
2554425544
25545 const float_ty = dest_ty.optEuBaseType(zcu);
25546 switch (float_ty.scalarType(zcu).zigTypeTag(zcu)) {
25547 .float, .comptime_float => return .fromType(float_ty),
25548 else => return .comptime_float_type,
25545 const dest_base_ty = dest_ty.optEuBaseType(zcu);
25546 switch (dest_base_ty.scalarType(zcu).zigTypeTag(zcu)) {
25547 .float, .comptime_float => return .fromType(dest_base_ty),
25548 else => return .generic_poison_type,
2554925549 }
2555025550}
2555125551
test/behavior/cast.zig+2
......@@ -120,6 +120,7 @@ test "@floatFromInt" {
120120 try expect(@as(i32, @floor(f)) == k);
121121 try expect(@as(i32, @ceil(f)) == k);
122122 try expect(@as(i32, @trunc(f)) == k);
123 try expect(@as(i32, @trunc(@floor(f))) == k);
123124 }
124125 };
125126 try S.doTheTest();
......@@ -197,6 +198,7 @@ test "@floatFromInt(f80)" {
197198 try expect(@as(Int, @floor(f)) == k);
198199 try expect(@as(Int, @ceil(f)) == k);
199200 try expect(@as(Int, @trunc(f)) == k);
201 try expect(@as(Int, @trunc(@floor(f))) == k);
200202 }
201203 };
202204 try S.doTheTest(i31);