| author | |
| committer | |
| log | e6b73be870a39f4da7a08a40da23e38b5e9613da |
| tree | b21b81ecc4867273bf864988a8d63bb27b12b6c2 |
| parent | 2769215b9037bb1f407e07887d4d21957ce1a9e0 |
When analyzing the `as` ZIR instruction, an assertion would trip if the
result type was a var args function argument. The fix is simple: inline
a little bit of the `resolveType` logic into `analyzeAs` to make it
detect this situation - which it was already attempting to do.
Closes #161972 files changed, 19 insertions(+), 2 deletions(-)
src/Sema.zig+10-2| ... | @@ -9846,11 +9846,19 @@ fn analyzeAs( | ... | @@ -9846,11 +9846,19 @@ fn analyzeAs( |
| 9846 | const mod = sema.mod; | 9846 | const mod = sema.mod; |
| 9847 | const operand = try sema.resolveInst(zir_operand); | 9847 | const operand = try sema.resolveInst(zir_operand); |
| 9848 | if (zir_dest_type == .var_args_param_type) return operand; | 9848 | if (zir_dest_type == .var_args_param_type) return operand; |
| 9849 | const dest_ty = sema.resolveType(block, src, zir_dest_type) catch |err| switch (err) { | 9849 | const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) { |
| 9850 | error.GenericPoison => return operand, | 9850 | error.GenericPoison => return operand, |
| 9851 | else => |e| return e, | 9851 | else => |e| return e, |
| 9852 | }; | 9852 | }; |
| 9853 | if (dest_ty.zigTypeTag(mod) == .NoReturn) { | 9853 | if (operand_air_inst == .var_args_param_type) return operand; |
| 9854 | const dest_ty = sema.analyzeAsType(block, src, operand_air_inst) catch |err| switch (err) { | ||
| 9855 | error.GenericPoison => return operand, | ||
| 9856 | else => |e| return e, | ||
| 9857 | }; | ||
| 9858 | const dest_ty_tag = dest_ty.zigTypeTagOrPoison(mod) catch |err| switch (err) { | ||
| 9859 | error.GenericPoison => return operand, | ||
| 9860 | }; | ||
| 9861 | if (dest_ty_tag == .NoReturn) { | ||
| 9854 | return sema.fail(block, src, "cannot cast to noreturn", .{}); | 9862 | return sema.fail(block, src, "cannot cast to noreturn", .{}); |
| 9855 | } | 9863 | } |
| 9856 | const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index| | 9864 | const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index| |
test/behavior/var_args.zig+9| ... | @@ -150,6 +150,15 @@ test "simple variadic function" { | ... | @@ -150,6 +150,15 @@ test "simple variadic function" { |
| 150 | try std.testing.expectEqual(@as(c_int, 0), S.add(0)); | 150 | try std.testing.expectEqual(@as(c_int, 0), S.add(0)); |
| 151 | try std.testing.expectEqual(@as(c_int, 1), S.add(1, @as(c_int, 1))); | 151 | try std.testing.expectEqual(@as(c_int, 1), S.add(1, @as(c_int, 1))); |
| 152 | try std.testing.expectEqual(@as(c_int, 3), S.add(2, @as(c_int, 1), @as(c_int, 2))); | 152 | try std.testing.expectEqual(@as(c_int, 3), S.add(2, @as(c_int, 1), @as(c_int, 2))); |
| 153 | |||
| 154 | { | ||
| 155 | // Test type coercion of a var args argument. | ||
| 156 | // Originally reported at https://github.com/ziglang/zig/issues/16197 | ||
| 157 | var runtime: bool = true; | ||
| 158 | var a: i32 = 1; | ||
| 159 | var b: i32 = 2; | ||
| 160 | try expect(1 == S.add(1, if (runtime) a else b)); | ||
| 161 | } | ||
| 153 | } | 162 | } |
| 154 | 163 | ||
| 155 | test "variadic functions" { | 164 | test "variadic functions" { |