@@ -28733,17 +28733,36 @@ fn coerceExtra(
28733
28733
break :int;
28734
28734
};
28735
28735
const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, pt, .sema);
28736
- // TODO implement this compile error
28737
- //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);
28738
- //if (!int_again_val.eql(val, inst_ty, zcu)) {
28739
- // return sema.fail(
28740
- // block,
28741
- // inst_src,
28742
- // "type '{f}' cannot represent integer value '{f}'",
28743
- // .{ dest_ty.fmt(pt), val },
28744
- // );
28745
- //}
28746
- return Air.internedToRef(result_val.toIntern());
28736
+ const fits: bool = switch (ip.indexToKey(result_val.toIntern())) {
28737
+ else => unreachable,
28738
+ .undef => true,
28739
+ .float => |float| fits: {
28740
+ var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
28741
+ const operand_big_int = val.toBigInt(&buffer, zcu);
28742
+ switch (float.storage) {
28743
+ inline else => |x| {
28744
+ if (!std.math.isFinite(x)) break :fits false;
28745
+ var result_big_int: std.math.big.int.Mutable = .{
28746
+ .limbs = try sema.arena.alloc(std.math.big.Limb, std.math.big.int.calcLimbLen(x)),
28747
+ .len = undefined,
28748
+ .positive = undefined,
28749
+ };
28750
+ switch (result_big_int.setFloat(x, .nearest_even)) {
28751
+ .inexact => break :fits false,
28752
+ .exact => {},
28753
+ }
28754
+ break :fits result_big_int.toConst().eql(operand_big_int);
28755
+ },
28756
+ }
28757
+ },
28758
+ };
28759
+ if (!fits) return sema.fail(
28760
+ block,
28761
+ inst_src,
28762
+ "type '{f}' cannot represent integer value '{f}'",
28763
+ .{ dest_ty.fmt(pt), val.fmtValue(pt) },
28764
+ );
28765
+ return .fromValue(result_val);
28747
28766
},
28748
28767
else => {},
28749
28768
},
0 commit comments