sema: reuse callee func_decl for non-inline calls, bump 80→84
Fix non-inline function call to reuse the callee's existing func_decl IP entry instead of creating a new one with func_inst as owner_nav. Ported from upstream Sema.zig analyzeCall: func_val references the resolved callee function, not a newly-created entry. The callee is looked up by name in the file namespace. If the nav's resolved_type already points to a func_decl (IP_KEY_FUNC), it's used directly. Otherwise, the func_type from resolved_type is used to construct and deduplicate the func_decl key. Also fixes the coercion dedup fix from the previous commit: switched semaCoerceIntRef from ipForceIntern to ipIntern now that skip_dedup handles cross-shard separation. Tests 80-83 now pass (call_inside_runtime_conditional, multi_func_call, runtime_conditional_with_early_return, field_access_chain). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user