Commit 1696e943ac

Tadeo Kondrak <me@tadeo.ca>
2020-04-28 19:14:47
Implement @typeInfo for @Frame()
Closes https://github.com/ziglang/zig/issues/3066
1 parent b7914d9
Changed files (4)
src/analyze.cpp
@@ -6021,6 +6021,19 @@ ZigValue *create_const_null(CodeGen *g, ZigType *type) {
     return const_val;
 }
 
+void init_const_fn(ZigValue *const_val, ZigFn *fn) {
+    const_val->special = ConstValSpecialStatic;
+    const_val->type = fn->type_entry;
+    const_val->data.x_ptr.special = ConstPtrSpecialFunction;
+    const_val->data.x_ptr.data.fn.fn_entry = fn;
+}
+
+ZigValue *create_const_fn(CodeGen *g, ZigFn *fn) {
+    ZigValue *const_val = g->pass1_arena->create<ZigValue>();
+    init_const_fn(const_val, fn);
+    return const_val;
+}
+
 void init_const_float(ZigValue *const_val, ZigType *type, double value) {
     const_val->special = ConstValSpecialStatic;
     const_val->type = type;
src/analyze.hpp
@@ -180,6 +180,9 @@ ZigValue *create_const_slice(CodeGen *g, ZigValue *array_val, size_t start, size
 void init_const_null(ZigValue *const_val, ZigType *type);
 ZigValue *create_const_null(CodeGen *g, ZigType *type);
 
+void init_const_fn(ZigValue *const_val, ZigFn *fn);
+ZigValue *create_const_fn(CodeGen *g, ZigFn *fn);
+
 ZigValue **alloc_const_vals_ptrs(CodeGen *g, size_t count);
 ZigValue **realloc_const_vals_ptrs(CodeGen *g, ZigValue **ptr, size_t old_count, size_t new_count);
 
src/ir.cpp
@@ -25166,9 +25166,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
                 break;
             }
         case ZigTypeIdFnFrame:
-            ir_add_error(ira, source_instr,
-                buf_sprintf("compiler bug: TODO @typeInfo for async function frames. https://github.com/ziglang/zig/issues/3066"));
-            return ErrorSemanticAnalyzeFail;
+            {
+                result = ira->codegen->pass1_arena->create<ZigValue>();
+                result->special = ConstValSpecialStatic;
+                result->type = ir_type_info_get_type(ira, "Frame", nullptr);
+                ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1);
+                result->data.x_struct.fields = fields;
+                ZigFn *fn = type_entry->data.frame.fn;
+                // function: var
+                ensure_field_index(result->type, "function", 0);
+                fields[0] = create_const_fn(ira->codegen, fn);
+                break;
+            }
     }
 
     assert(result != nullptr);
test/stage1/behavior/type_info.zig
@@ -202,7 +202,7 @@ fn testUnion() void {
     expect(typeinfo_info.Union.fields[4].enum_field != null);
     expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
     expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int));
-    expect(typeinfo_info.Union.decls.len == 20);
+    expect(typeinfo_info.Union.decls.len == 21);
 
     const TestNoTagUnion = union {
         Foo: void,
@@ -389,3 +389,16 @@ test "defaut value for a var-typed field" {
     const S = struct { x: var };
     expect(@typeInfo(S).Struct.fields[0].default_value == null);
 }
+
+fn add(a: i32, b: i32) i32 {
+    return a + b;
+}
+
+test "type info for async frames" {
+    switch (@typeInfo(@Frame(add))) {
+        .Frame => |frame| {
+            expect(frame.function == add);
+        },
+        else => unreachable,
+    }
+}