From 0be24a87de86d86f24dbc95534aeda648d9991e8 Mon Sep 17 00:00:00 2001 From: IOKG04 Date: Fri, 19 Sep 2025 22:36:06 +0200 Subject: [PATCH 1/2] `@min` `@max` coerce comptime known arguments early fixes https://github.com/ziglang/zig/issues/25284 by giving explicit source locations to the now failable coercion(s). --- src/Sema.zig | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 385e1ae74a84..7d92cdc22215 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -24876,23 +24876,26 @@ fn analyzeMinMax( if (vector_len) |len| { // Vector case; apply `opFunc` to each element. if (elems_populated) { + const coerced_operand_val = Value.fromInterned((try sema.coerce(block, intermediate_ty, Air.internedToRef(operand_val.toIntern()), operand_src)).toInterned().?); for (elems, 0..@intCast(len)) |*elem, elem_idx| { - const new_elem = try operand_val.elemValue(pt, elem_idx); - elem.* = opFunc(.fromInterned(elem.*), new_elem, zcu).toIntern(); + elem.* = opFunc(.fromInterned(elem.*), try coerced_operand_val.elemValue(pt, elem_idx), zcu).toIntern(); } } else { elems_populated = true; + const coerced_operand_val = Value.fromInterned((try sema.coerce(block, intermediate_ty, Air.internedToRef(operand_val.toIntern()), operand_src)).toInterned().?); for (elems, 0..@intCast(len)) |*elem_out, elem_idx| { - elem_out.* = (try operand_val.elemValue(pt, elem_idx)).toIntern(); + elem_out.* = (try coerced_operand_val.elemValue(pt, elem_idx)).toIntern(); } } } else { // Scalar case; just apply `opFunc`. if (elems_populated) { - elems[0] = opFunc(.fromInterned(elems[0]), operand_val, zcu).toIntern(); + const coerced_operand_val = Value.fromInterned((try sema.coerce(block, intermediate_scalar_ty, Air.internedToRef(operand_val.toIntern()), operand_src)).toInterned().?); + elems[0] = opFunc(.fromInterned(elems[0]), coerced_operand_val, zcu).toIntern(); } else { elems_populated = true; - elems[0] = operand_val.toIntern(); + const coerced_operand_val = Value.fromInterned((try sema.coerce(block, intermediate_scalar_ty, Air.internedToRef(operand_val.toIntern()), operand_src)).toInterned().?); + elems[0] = coerced_operand_val.toIntern(); } } } @@ -24913,17 +24916,7 @@ fn analyzeMinMax( }; _ = runtime_src; // The result is runtime-known. - // Coerce each element to the intermediate scalar type, unless there were no comptime-known operands. if (!elems_populated) break :ct null; - for (elems) |*elem| { - if (Value.fromInterned(elem.*).isUndef(zcu)) { - elem.* = (try pt.undefValue(intermediate_scalar_ty)).toIntern(); - } else { - // This coercion will always succeed, because `intermediate_scalar_ty` can definitely hold all operands. - const coerced_ref = try sema.coerce(block, intermediate_scalar_ty, Air.internedToRef(elem.*), .unneeded); - elem.* = coerced_ref.toInterned().?; - } - } break :ct if (vector_len != null) try pt.aggregateValue(intermediate_ty, elems) else From 9e6d34711421fdaabc45dff2be899dd0b8c13719 Mon Sep 17 00:00:00 2001 From: IOKG04 Date: Thu, 25 Sep 2025 14:04:25 +0200 Subject: [PATCH 2/2] add test for `@min` `@max` coercion errors ...my pc might've crashed while running these tests, I hope it's unrelated to this code. ...but I also kind of hope it is this code, cause then I don't got hardware problems at least. --- ...minmax_comptime_arguents_not_coercible.zig | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/cases/compile_errors/minmax_comptime_arguents_not_coercible.zig diff --git a/test/cases/compile_errors/minmax_comptime_arguents_not_coercible.zig b/test/cases/compile_errors/minmax_comptime_arguents_not_coercible.zig new file mode 100644 index 000000000000..272347872da5 --- /dev/null +++ b/test/cases/compile_errors/minmax_comptime_arguents_not_coercible.zig @@ -0,0 +1,26 @@ +// zig fmt: off +comptime { _ = @min(@as(f32, 1.0), u32_max); } +comptime { _ = @max(@as(f32, 1.0), u32_max); } +comptime { _ = @min(@as(f32, 1.0), 1234, u32_max, 0.1); } +comptime { _ = @max(@as(f32, 1.0), 1234, u32_max, 0.1); } +comptime { + var f: f32 = 1.0; + _ = &f; + _ = @min(f, u32_max); +} +comptime { + var f: f32 = 1.0; + _ = &f; + _ = @max(f, u32_max); +} + +const u32_max: u32 = 4294967295; + +// error +// +// :2:36: error: type 'f32' cannot represent integer value '4294967295' +// :3:36: error: type 'f32' cannot represent integer value '4294967295' +// :4:42: error: type 'f32' cannot represent integer value '4294967295' +// :5:42: error: type 'f32' cannot represent integer value '4294967295' +// :9:17: error: type 'f32' cannot represent integer value '4294967295' +// :14:17: error: type 'f32' cannot represent integer value '4294967295'