diff --git a/stage0/corpus.zig b/stage0/corpus.zig index 9082af643a..3341d77bb1 100644 --- a/stage0/corpus.zig +++ b/stage0/corpus.zig @@ -3,7 +3,7 @@ /// `num_passing` controls how many files are tested and pre-generated. /// Both build.zig and stages_test.zig import this file. /// To enable more tests: just increment `num_passing`. -pub const num_passing: usize = 80; +pub const num_passing: usize = 84; pub const files = [_][]const u8{ "stage0/sema_tests/empty.zig", diff --git a/stage0/sema.c b/stage0/sema.c index 6ead655c2e..8e29458093 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -6606,21 +6606,54 @@ static AirInstRef zirCall( } } - // Intern a function type with the resolved return type. - InternPoolKey ft_key; - memset(&ft_key, 0, sizeof(ft_key)); - ft_key.tag = IP_KEY_FUNC_TYPE; - ft_key.data.func_type.return_type = ret_ty; - ft_key.data.func_type.param_count = runtime_args_count; - InternPoolIndex func_type_ip = ipIntern(sema->ip, ft_key); - - // Intern a function value (unique per ZIR func inst). - InternPoolKey fv_key; - memset(&fv_key, 0, sizeof(fv_key)); - fv_key.tag = IP_KEY_FUNC; - fv_key.data.func_decl.owner_nav = func_inst; - fv_key.data.func_decl.ty = func_type_ip; - InternPoolIndex func_val_ip = ipIntern(sema->ip, fv_key); + // Use the callee's existing func_decl. Ported from upstream + // Sema.zig analyzeCall: func_val is the resolved callee, not + // a newly-created func entry. Look up the callee's nav by name + // in the file namespace, then use its existing func_decl. + InternPoolIndex func_val_ip = IP_INDEX_NONE; + { + uint32_t callee_nav = UINT32_MAX; + if (callee_name_idx != 0 + && sema->zcu->root_file_idx != UINT32_MAX) { + const char* cname + = (const char*)&sema->code.string_bytes[callee_name_idx]; + uint32_t rns + = sema->zcu->file_namespaces[sema->zcu->root_file_idx]; + callee_nav = findNavInNamespace(sema, rns, cname); + } + if (callee_nav != UINT32_MAX) { + const Nav* cn = ipGetNav(sema->ip, callee_nav); + InternPoolIndex resolved = cn->resolved_type; + // If resolved points to a func_decl, use it directly. + // If it points to a func_type, construct the func_decl + // key and look it up. + if (resolved != IP_INDEX_NONE + && sema->ip->items[resolved].tag == IP_KEY_FUNC) { + func_val_ip = resolved; + } else if (resolved != IP_INDEX_NONE) { + InternPoolKey fv_key; + memset(&fv_key, 0, sizeof(fv_key)); + fv_key.tag = IP_KEY_FUNC; + fv_key.data.func_decl.owner_nav = callee_nav; + fv_key.data.func_decl.ty = resolved; + func_val_ip = ipIntern(sema->ip, fv_key); + } + } else { + // Fallback: create with func_inst as nav. + InternPoolKey ft_key; + memset(&ft_key, 0, sizeof(ft_key)); + ft_key.tag = IP_KEY_FUNC_TYPE; + ft_key.data.func_type.return_type = ret_ty; + ft_key.data.func_type.param_count = runtime_args_count; + InternPoolIndex func_type_ip = ipForceIntern(sema->ip, ft_key); + InternPoolKey fv_key; + memset(&fv_key, 0, sizeof(fv_key)); + fv_key.tag = IP_KEY_FUNC; + fv_key.data.func_decl.owner_nav = func_inst; + fv_key.data.func_decl.ty = func_type_ip; + func_val_ip = ipIntern(sema->ip, fv_key); + } + } // Emit CALL extra: {args_len, arg_refs[0..args_len]}. uint32_t call_extra = semaAddExtra(sema, runtime_args_count);