Skip to content

Commit 9af4cad

Browse files
committed
Sema: coerce comptime_float to fixed-width float
Instead of doing heterogeneous comparison at comptime. This makes the following test pass (as it already does for stage1): ```zig test { const x: f64 = 12.34; expect(x == 12.34); } ``` There is already behavior test coverage for this, however, other bugs in `std.fmt.parseFloat` are masking the failures. From a language specification perspective, this makes sense because it makes comptime comparisons with comptime_float work the same way they work with runtime comparisons.
1 parent a3f5615 commit 9af4cad

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/Sema.zig

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20787,14 +20787,14 @@ fn cmpNumeric(
2078720787
sema: *Sema,
2078820788
block: *Block,
2078920789
src: LazySrcLoc,
20790-
lhs: Air.Inst.Ref,
20791-
rhs: Air.Inst.Ref,
20790+
uncasted_lhs: Air.Inst.Ref,
20791+
uncasted_rhs: Air.Inst.Ref,
2079220792
op: std.math.CompareOperator,
2079320793
lhs_src: LazySrcLoc,
2079420794
rhs_src: LazySrcLoc,
2079520795
) CompileError!Air.Inst.Ref {
20796-
const lhs_ty = sema.typeOf(lhs);
20797-
const rhs_ty = sema.typeOf(rhs);
20796+
const lhs_ty = sema.typeOf(uncasted_lhs);
20797+
const rhs_ty = sema.typeOf(uncasted_rhs);
2079820798

2079920799
assert(lhs_ty.isNumeric());
2080020800
assert(rhs_ty.isNumeric());
@@ -20803,6 +20803,19 @@ fn cmpNumeric(
2080320803
const rhs_ty_tag = rhs_ty.zigTypeTag();
2080420804
const target = sema.mod.getTarget();
2080520805

20806+
// One exception to heterogeneous comparison: comptime_float needs to
20807+
// coerce to fixed-width float.
20808+
20809+
const lhs = if (lhs_ty_tag == .ComptimeFloat and rhs_ty_tag == .Float)
20810+
try sema.coerce(block, rhs_ty, uncasted_lhs, lhs_src)
20811+
else
20812+
uncasted_lhs;
20813+
20814+
const rhs = if (lhs_ty_tag == .Float and rhs_ty_tag == .ComptimeFloat)
20815+
try sema.coerce(block, lhs_ty, uncasted_rhs, rhs_src)
20816+
else
20817+
uncasted_rhs;
20818+
2080620819
const runtime_src: LazySrcLoc = src: {
2080720820
if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
2080820821
if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
@@ -20845,8 +20858,10 @@ fn cmpNumeric(
2084520858
.Float, .ComptimeFloat => true,
2084620859
else => false,
2084720860
};
20861+
2084820862
if (lhs_is_float and rhs_is_float) {
20849-
// Implicit cast the smaller one to the larger one.
20863+
// Smaller fixed-width floats coerce to larger fixed-width floats.
20864+
// comptime_float coerces to fixed-width float.
2085020865
const dest_ty = x: {
2085120866
if (lhs_ty_tag == .ComptimeFloat) {
2085220867
break :x rhs_ty;

0 commit comments

Comments
 (0)