Commit 6a4df2778e

Andrew Kelley <andrew@ziglang.org>
2022-07-27 23:44:37
AstGen: fix ref instruction injection for functions
For the expressions regarding return type, alignment, parameter type, etc.
1 parent 401abd7
Changed files (2)
src
test
behavior
src/AstGen.zig
@@ -10282,11 +10282,11 @@ const GenZir = struct {
             try astgen.extra.ensureUnusedCapacity(
                 gpa,
                 @typeInfo(Zir.Inst.FuncFancy).Struct.fields.len +
-                    fancyFnExprExtraLen(align_body, args.align_ref) +
-                    fancyFnExprExtraLen(addrspace_body, args.addrspace_ref) +
-                    fancyFnExprExtraLen(section_body, args.section_ref) +
-                    fancyFnExprExtraLen(cc_body, args.cc_ref) +
-                    fancyFnExprExtraLen(ret_body, ret_ref) +
+                    fancyFnExprExtraLen(astgen, align_body, args.align_ref) +
+                    fancyFnExprExtraLen(astgen, addrspace_body, args.addrspace_ref) +
+                    fancyFnExprExtraLen(astgen, section_body, args.section_ref) +
+                    fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +
+                    fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
                     body_len + src_locs.len +
                     @boolToInt(args.lib_name != 0) +
                     @boolToInt(args.noalias_bits != 0),
@@ -10322,36 +10322,36 @@ const GenZir = struct {
 
             const zir_datas = astgen.instructions.items(.data);
             if (align_body.len != 0) {
-                astgen.extra.appendAssumeCapacity(@intCast(u32, align_body.len));
-                astgen.extra.appendSliceAssumeCapacity(align_body);
+                astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
+                astgen.appendBodyWithFixups(align_body);
                 zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index;
             } else if (args.align_ref != .none) {
                 astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));
             }
             if (addrspace_body.len != 0) {
-                astgen.extra.appendAssumeCapacity(@intCast(u32, addrspace_body.len));
-                astgen.extra.appendSliceAssumeCapacity(addrspace_body);
+                astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
+                astgen.appendBodyWithFixups(addrspace_body);
                 zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index;
             } else if (args.addrspace_ref != .none) {
                 astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));
             }
             if (section_body.len != 0) {
-                astgen.extra.appendAssumeCapacity(@intCast(u32, section_body.len));
-                astgen.extra.appendSliceAssumeCapacity(section_body);
+                astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
+                astgen.appendBodyWithFixups(section_body);
                 zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index;
             } else if (args.section_ref != .none) {
                 astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));
             }
             if (cc_body.len != 0) {
-                astgen.extra.appendAssumeCapacity(@intCast(u32, cc_body.len));
-                astgen.extra.appendSliceAssumeCapacity(cc_body);
+                astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
+                astgen.appendBodyWithFixups(cc_body);
                 zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index;
             } else if (args.cc_ref != .none) {
                 astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));
             }
             if (ret_body.len != 0) {
-                astgen.extra.appendAssumeCapacity(@intCast(u32, ret_body.len));
-                astgen.extra.appendSliceAssumeCapacity(ret_body);
+                astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
+                astgen.appendBodyWithFixups(ret_body);
                 zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
             } else if (ret_ref != .none) {
                 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
@@ -10389,11 +10389,12 @@ const GenZir = struct {
             try astgen.extra.ensureUnusedCapacity(
                 gpa,
                 @typeInfo(Zir.Inst.Func).Struct.fields.len + 1 +
-                    @maximum(ret_body.len, @boolToInt(ret_ref != .none)) +
+                    fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
                     body_len + src_locs.len,
             );
+
             const ret_body_len = if (ret_body.len != 0)
-                @intCast(u32, ret_body.len)
+                countBodyLenAfterFixups(astgen, ret_body)
             else
                 @boolToInt(ret_ref != .none);
 
@@ -10404,7 +10405,7 @@ const GenZir = struct {
             });
             const zir_datas = astgen.instructions.items(.data);
             if (ret_body.len != 0) {
-                astgen.extra.appendSliceAssumeCapacity(ret_body);
+                astgen.appendBodyWithFixups(ret_body);
                 zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
             } else if (ret_ref != .none) {
                 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
@@ -10435,10 +10436,10 @@ const GenZir = struct {
         }
     }
 
-    fn fancyFnExprExtraLen(body: []Zir.Inst.Index, ref: Zir.Inst.Ref) usize {
+    fn fancyFnExprExtraLen(astgen: *AstGen, body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 {
         // In the case of non-empty body, there is one for the body length,
         // and then one for each instruction.
-        return body.len + @boolToInt(ref != .none);
+        return countBodyLenAfterFixups(astgen, body) + @boolToInt(ref != .none);
     }
 
     fn addVar(gz: *GenZir, args: struct {
test/behavior/fn.zig
@@ -408,3 +408,17 @@ test "function with inferred error set but returning no error" {
     const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
     try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
 }
+
+test "import passed byref to function in return type" {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn get() @import("std").ArrayListUnmanaged(i32) {
+            var x: @import("std").ArrayListUnmanaged(i32) = .{};
+            return x;
+        }
+    };
+    var list = S.get();
+    try expect(list.items.len == 0);
+}