diff --git a/src/analyze.cpp b/src/analyze.cpp index d1702738083c687c402034a562e995e7d2cf0c22..5eb0205dfb88eb610de5b64cb982eb3d9b32ee8c 100644 --- a/src/analyze.cpp +++ b/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(); + 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; diff --git a/src/analyze.hpp b/src/analyze.hpp index ae010c87e1f04508f827b0ec3b94f75ddc3010ed..a92d7ec1de6b1005d52cca1cd04e553b08bda2f5 100644 --- a/src/analyze.hpp +++ b/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); diff --git a/src/ir.cpp b/src/ir.cpp index f37f91088a2ef2dc0be409f10a3c1b690b8a5353..0111a33f34b83d2eb340516013ce6d246b943532 100644 --- a/src/ir.cpp +++ b/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(); + 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); diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index c897276f8392dbc7ff730131a17592b8cbf27cb2..41301f290d9e5bccdff9813a480ccba47b4ca498 100644 --- a/test/stage1/behavior/type_info.zig +++ b/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, + } +}