Skip to content

Commit 7f0642b

Browse files
authored
Merge pull request #12397 from martinhath/issue-12364
Sema: error on ambiguous coercion of comptime float and ints
2 parents 070282a + 2cccd14 commit 7f0642b

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

src/Sema.zig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11202,6 +11202,21 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1120211202
const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs);
1120311203
const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs);
1120411204

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+
1120511220
// TODO: emit compile error when .div is used on integers and there would be an
1120611221
// ambiguous result between div_floor and div_trunc.
1120711222

test/behavior/floatop.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ fn testSin() !void {
194194
const eps = epsForType(ty);
195195
try expect(@sin(@as(ty, 0)) == 0);
196196
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));
199199
}
200200

201201
{
@@ -228,8 +228,8 @@ fn testCos() !void {
228228
const eps = epsForType(ty);
229229
try expect(@cos(@as(ty, 0)) == 1);
230230
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));
233233
}
234234

235235
{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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'

0 commit comments

Comments
 (0)