Refactor implicit Self param into a member on SemIR::Function (#4928)

This ensures the data is available for more uses (specifically for
diagnosing virtual/abstract/impl functions on non-instance methods).

It still doesn't quite address the TODO to move the Self param search
all the way back to the param walk in all cases. To do that in the case
that still has a separate search loop, I think we'd have to change
`Check::NameComponent` to carry this information (as it carries the
implicit_param_patterns-id) - though there's comments in NameComponent
suggesting it shouldn't carry function-specific things like
`call_params_id` and `return_slot_pattern_id` - so I wasn't sure if it
was suitable to add more there, but I can - possibly in a follow-up
change.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
David Blaikie
2025-02-13 19:07:17 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent e70f9cd71d
commit aa71f31787
4 changed files with 39 additions and 18 deletions
+19 -1
View File
@@ -125,6 +125,7 @@ static auto MergeFunctionRedecl(Context& context,
// match IDs in the signature.
prev_function.MergeDefinition(new_function);
prev_function.return_slot_pattern_id = new_function.return_slot_pattern_id;
prev_function.self_param_id = new_function.self_param_id;
}
if (prev_import_ir_id.has_value()) {
ReplacePrevInstForMerge(context, new_function.parent_scope_id,
@@ -258,13 +259,30 @@ static auto BuildFunctionDecl(Context& context,
auto decl_id =
context.AddPlaceholderInst(SemIR::LocIdAndInst(node_id, function_decl));
// Find self parameter pattern.
// TODO: Do this during initial traversal of implicit params.
auto self_param_id = SemIR::InstId::None;
auto implicit_param_patterns =
context.inst_blocks().GetOrEmpty(name.implicit_param_patterns_id);
if (const auto* i =
llvm::find_if(implicit_param_patterns,
[&](auto implicit_param_id) {
return SemIR::Function::GetNameFromPatternId(
context.sem_ir(), implicit_param_id) ==
SemIR::NameId::SelfValue;
});
i != implicit_param_patterns.end()) {
self_param_id = *i;
}
// Build the function entity. This will be merged into an existing function if
// there is one, or otherwise added to the function store.
auto function_info =
SemIR::Function{{name_context.MakeEntityWithParamsBase(
name, decl_id, is_extern, introducer.extern_library)},
{.return_slot_pattern_id = name.return_slot_pattern_id,
.virtual_modifier = virtual_modifier}};
.virtual_modifier = virtual_modifier,
.self_param_id = self_param_id}};
if (is_definition) {
function_info.definition_id = decl_id;
}