authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-02 12:13:55-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-02 12:16:23-07:00
log9af4cada73e43fb98e906a0ed79197963d1a05ac
treedb634dec75b5f79847dbfa799b613d47815bc0cd
parenta3f56154d08f25dbe2b6d15de30deda8a2d9ef33

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 files changed, 20 insertions(+), 5 deletions(-)

src/Sema.zig+20-5
......@@ -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;