| author | |
| committer | |
| log | 94bdde8327608af23771fbca8486c2e5c189fa1e |
| tree | 00cba8e7ac4f7af824723091e24ae9ab1095a4f6 |
| parent | 276f2e1b810aef048c3ce324e0977ba2d9ff8200 |
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/356642 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 | }; |
| 25544 | 25544 | ||
| 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 | } |
| 25551 | 25551 |
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); |