Commit f0176eec4a

Andrew Kelley <andrew@ziglang.org>
2021-08-21 02:44:03
stage2: support comptime fn call returning type
...when the field type expressions reference locals as well as comptime function parameters.
1 parent 6c55d85
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -2623,7 +2623,18 @@ fn analyzeCall(
         defer sema.fn_ret_ty = parent_fn_ret_ty;
 
         _ = try sema.analyzeBody(&child_block, fn_info.body);
-        break :res try sema.analyzeBlockBody(block, call_src, &child_block, merges);
+        const result = try sema.analyzeBlockBody(block, call_src, &child_block, merges);
+
+        // Much like in `Module.semaDecl`, if the result is a struct or union type,
+        // we need to resolve the field type expressions right here, right now, while
+        // the child `Sema` is still available, with the AIR instruction map intact,
+        // because the field type expressions may reference into it.
+        if (sema.typeOf(result).zigTypeTag() == .Type) {
+            const ty = try sema.analyzeAsType(&child_block, call_src, result);
+            try sema.resolveDeclFields(&child_block, call_src, ty);
+        }
+
+        break :res result;
     } else if (func_ty_info.is_generic) res: {
         const func_val = try sema.resolveConstValue(block, func_src, func);
         const module_fn = func_val.castTag(.function).?.data;
test/behavior/generics.zig
@@ -78,3 +78,21 @@ fn max_i32(a: i32, b: i32) i32 {
 fn max_f64(a: f64, b: f64) f64 {
     return max_anytype(a, b);
 }
+
+test "type constructed by comptime function call" {
+    var l: List(10) = undefined;
+    l.array[0] = 10;
+    l.array[1] = 11;
+    l.array[2] = 12;
+    const ptr = @ptrCast([*]u8, &l.array);
+    try expect(ptr[0] == 10);
+    try expect(ptr[1] == 11);
+    try expect(ptr[2] == 12);
+}
+
+fn List(comptime L: usize) type {
+    var T = u8;
+    return struct {
+        array: [L]T,
+    };
+}