| author | |
| committer | |
| log | 7f0642b5d3c67f93892430f502f4eadbe54f1989 |
| tree | 9c323487031224f7d169b419ecfb74c3eb3b7a9b |
| parent | 070282a96ec23fb41041843d5753608ec5090f8b |
| parent | 2cccd144914d8715894458f317fa4c3c572cdcad |
| signature |
Sema: error on ambiguous coercion of comptime float and ints3 files changed, 42 insertions(+), 4 deletions(-)
src/Sema.zig+15| ... | ... | @@ -11202,6 +11202,21 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 11202 | 11202 | const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs); |
| 11203 | 11203 | const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs); |
| 11204 | 11204 | |
| 11205 | if ((lhs_ty.zigTypeTag() == .ComptimeFloat and rhs_ty.zigTypeTag() == .ComptimeInt) or | |
| 11206 | (lhs_ty.zigTypeTag() == .ComptimeInt and rhs_ty.zigTypeTag() == .ComptimeFloat)) | |
| 11207 | { | |
| 11208 | // If it makes a difference whether we coerce to ints or floats before doing the division, error. | |
| 11209 | // If lhs % rhs is 0, it doesn't matter. | |
| 11210 | const lhs_val = maybe_lhs_val orelse unreachable; | |
| 11211 | const rhs_val = maybe_rhs_val orelse unreachable; | |
| 11212 | const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, target) catch unreachable; | |
| 11213 | if (rem.compareWithZero(.neq)) { | |
| 11214 | return sema.fail(block, src, "ambiguous coercion of division operands '{s}' and '{s}'; non-zero remainder '{}'", .{ | |
| 11215 | @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()), rem.fmtValue(resolved_type, sema.mod), | |
| 11216 | }); | |
| 11217 | } | |
| 11218 | } | |
| 11219 | ||
| 11205 | 11220 | // TODO: emit compile error when .div is used on integers and there would be an |
| 11206 | 11221 | // ambiguous result between div_floor and div_trunc. |
| 11207 | 11222 |
test/behavior/floatop.zig+4-4| ... | ... | @@ -194,8 +194,8 @@ fn testSin() !void { |
| 194 | 194 | const eps = epsForType(ty); |
| 195 | 195 | try expect(@sin(@as(ty, 0)) == 0); |
| 196 | 196 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi)), 0, eps)); |
| 197 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 2)), 1, eps)); | |
| 198 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 4)), 0.7071067811865475, eps)); | |
| 197 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 2.0)), 1, eps)); | |
| 198 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps)); | |
| 199 | 199 | } |
| 200 | 200 | |
| 201 | 201 | { |
| ... | ... | @@ -228,8 +228,8 @@ fn testCos() !void { |
| 228 | 228 | const eps = epsForType(ty); |
| 229 | 229 | try expect(@cos(@as(ty, 0)) == 1); |
| 230 | 230 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi)), -1, eps)); |
| 231 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 2)), 0, eps)); | |
| 232 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 4)), 0.7071067811865475, eps)); | |
| 231 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 2.0)), 0, eps)); | |
| 232 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps)); | |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | 235 | { |
test/cases/compile_errors/ambiguous_coercion_of_division_operands.zig created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | export fn entry1() void { | |
| 2 | var f: f32 = 54.0 / 5; | |
| 3 | _ = f; | |
| 4 | } | |
| 5 | export fn entry2() void { | |
| 6 | var f: f32 = 54 / 5.0; | |
| 7 | _ = f; | |
| 8 | } | |
| 9 | export fn entry3() void { | |
| 10 | var f: f32 = 55.0 / 5; | |
| 11 | _ = f; | |
| 12 | } | |
| 13 | export fn entry4() void { | |
| 14 | var f: f32 = 55 / 5.0; | |
| 15 | _ = f; | |
| 16 | } | |
| 17 | ||
| 18 | // error | |
| 19 | // backend=stage2 | |
| 20 | // target=native | |
| 21 | // | |
| 22 | // :2:23: error: ambiguous coercion of division operands 'comptime_float' and 'comptime_int'; non-zero remainder '4' | |
| 23 | // :6:21: error: ambiguous coercion of division operands 'comptime_int' and 'comptime_float'; non-zero remainder '4' |