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(...@@ -20787,14 +20787,14 @@ fn cmpNumeric(
20787 sema: *Sema,20787 sema: *Sema,
20788 block: *Block,20788 block: *Block,
20789 src: LazySrcLoc,20789 src: LazySrcLoc,
20790 lhs: Air.Inst.Ref,20790 uncasted_lhs: Air.Inst.Ref,
20791 rhs: Air.Inst.Ref,20791 uncasted_rhs: Air.Inst.Ref,
20792 op: std.math.CompareOperator,20792 op: std.math.CompareOperator,
20793 lhs_src: LazySrcLoc,20793 lhs_src: LazySrcLoc,
20794 rhs_src: LazySrcLoc,20794 rhs_src: LazySrcLoc,
20795) CompileError!Air.Inst.Ref {20795) CompileError!Air.Inst.Ref {
20796 const lhs_ty = sema.typeOf(lhs);20796 const lhs_ty = sema.typeOf(uncasted_lhs);
20797 const rhs_ty = sema.typeOf(rhs);20797 const rhs_ty = sema.typeOf(uncasted_rhs);
2079820798
20799 assert(lhs_ty.isNumeric());20799 assert(lhs_ty.isNumeric());
20800 assert(rhs_ty.isNumeric());20800 assert(rhs_ty.isNumeric());
...@@ -20803,6 +20803,19 @@ fn cmpNumeric(...@@ -20803,6 +20803,19 @@ fn cmpNumeric(
20803 const rhs_ty_tag = rhs_ty.zigTypeTag();20803 const rhs_ty_tag = rhs_ty.zigTypeTag();
20804 const target = sema.mod.getTarget();20804 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
20806 const runtime_src: LazySrcLoc = src: {20819 const runtime_src: LazySrcLoc = src: {
20807 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {20820 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
20808 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {20821 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
...@@ -20845,8 +20858,10 @@ fn cmpNumeric(...@@ -20845,8 +20858,10 @@ fn cmpNumeric(
20845 .Float, .ComptimeFloat => true,20858 .Float, .ComptimeFloat => true,
20846 else => false,20859 else => false,
20847 };20860 };
20861
20848 if (lhs_is_float and rhs_is_float) {20862 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.
20850 const dest_ty = x: {20865 const dest_ty = x: {
20851 if (lhs_ty_tag == .ComptimeFloat) {20866 if (lhs_ty_tag == .ComptimeFloat) {
20852 break :x rhs_ty;20867 break :x rhs_ty;