Commit 629c3108aa

Veikka Tuominen <git@vexu.eu>
2023-02-01 20:41:02
AstGen: fix orelse type coercion in call arguments
Closes #14506
1 parent 490addd
Changed files (2)
src
test
behavior
src/AstGen.zig
@@ -8721,6 +8721,7 @@ fn callExpr(
         defer arg_block.unstack();
 
         // `call_inst` is reused to provide the param type.
+        arg_block.rl_ty_inst = call_inst;
         const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
         _ = try arg_block.addBreak(.break_inline, call_index, arg_ref);
 
@@ -10869,7 +10870,12 @@ const GenZir = struct {
         // we emit ZIR for the block break instructions to have the result values,
         // and then rvalue() on that to pass the value to the result location.
         switch (parent_ri.rl) {
-            .ty, .coerced_ty => |ty_inst| {
+            .coerced_ty => |ty_inst| {
+                // Type coercion needs to happend before breaks.
+                gz.rl_ty_inst = ty_inst;
+                gz.break_result_info = .{ .rl = .{ .ty = ty_inst } };
+            },
+            .ty => |ty_inst| {
                 gz.rl_ty_inst = ty_inst;
                 gz.break_result_info = parent_ri;
             },
test/behavior/basic.zig
@@ -1125,3 +1125,21 @@ test "returning an opaque type from a function" {
     };
     try expect(S.foo(123).b == 123);
 }
+
+test "orelse coercion as function argument" {
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+    const Loc = struct { start: i32 = -1 };
+    const Container = struct {
+        a: ?Loc = null,
+        fn init(a: Loc) @This() {
+            return .{
+                .a = a,
+            };
+        }
+    };
+    var optional: ?Loc = .{};
+    var foo = Container.init(optional orelse .{});
+    try expect(foo.a.?.start == -1);
+}