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...@@ -25542,10 +25542,10 @@ fn zirRoundOpType(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
25542 return .generic_poison_type;25542 return .generic_poison_type;
25543 };25543 };
2554425544
25545 const float_ty = dest_ty.optEuBaseType(zcu);25545 const dest_base_ty = dest_ty.optEuBaseType(zcu);
25546 switch (float_ty.scalarType(zcu).zigTypeTag(zcu)) {25546 switch (dest_base_ty.scalarType(zcu).zigTypeTag(zcu)) {
25547 .float, .comptime_float => return .fromType(float_ty),25547 .float, .comptime_float => return .fromType(dest_base_ty),
25548 else => return .comptime_float_type,25548 else => return .generic_poison_type,
25549 }25549 }
25550}25550}
2555125551
test/behavior/cast.zig+2
...@@ -120,6 +120,7 @@ test "@floatFromInt" {...@@ -120,6 +120,7 @@ test "@floatFromInt" {
120 try expect(@as(i32, @floor(f)) == k);120 try expect(@as(i32, @floor(f)) == k);
121 try expect(@as(i32, @ceil(f)) == k);121 try expect(@as(i32, @ceil(f)) == k);
122 try expect(@as(i32, @trunc(f)) == k);122 try expect(@as(i32, @trunc(f)) == k);
123 try expect(@as(i32, @trunc(@floor(f))) == k);
123 }124 }
124 };125 };
125 try S.doTheTest();126 try S.doTheTest();
...@@ -197,6 +198,7 @@ test "@floatFromInt(f80)" {...@@ -197,6 +198,7 @@ test "@floatFromInt(f80)" {
197 try expect(@as(Int, @floor(f)) == k);198 try expect(@as(Int, @floor(f)) == k);
198 try expect(@as(Int, @ceil(f)) == k);199 try expect(@as(Int, @ceil(f)) == k);
199 try expect(@as(Int, @trunc(f)) == k);200 try expect(@as(Int, @trunc(f)) == k);
201 try expect(@as(Int, @trunc(@floor(f))) == k);
200 }202 }
201 };203 };
202 try S.doTheTest(i31);204 try S.doTheTest(i31);