When merging functions, detect uses of imports prior to a redecl. (#3836)

LookupNameInDecl is only called from DeclNameStack, but I'm adding
mark_imports_used there because it feels more consistent. Not sure if we
want a better API boundary. I admit I'm also suspicious of its call to
LookupInCurrentScope but maybe it's okay due to how imports work.

I was choosing to print multiple diagnostics when a declaration is
previously used _and_ doesn't match because I think the "previously
used" is more important, but the "doesn't match" may give an additional
hint about why it didn't work.

The merge.h utility function is because I think we can follow a similar
model for identifying errors with other declarations: classes,
interfaces, etc.
This commit is contained in:
Jon Ross-Perkins
2024-04-02 17:44:55 +00:00
committed by GitHub
parent f8c8861e5f
commit dffe4a36de
14 changed files with 471 additions and 96 deletions
+5 -10
View File
@@ -8,6 +8,7 @@
#include "toolchain/check/decl_state.h"
#include "toolchain/check/function.h"
#include "toolchain/check/interface.h"
#include "toolchain/check/merge.h"
#include "toolchain/check/modifiers.h"
#include "toolchain/parse/tree_node_diagnostic_converter.h"
#include "toolchain/sem_ir/builtin_function_kind.h"
@@ -168,19 +169,13 @@ static auto BuildFunctionDecl(Context& context,
auto prev_id =
context.decl_name_stack().LookupOrAddName(name_context, lookup_result_id);
if (prev_id.is_valid()) {
auto prev_inst = context.insts().Get(prev_id);
bool prev_is_import = false;
auto prev_inst = ResolvePrevInstForMerge(context, node_id, prev_id);
if (prev_inst.Is<SemIR::ImportRefUsed>()) {
prev_inst =
context.insts().Get(context.constant_values().Get(prev_id).inst_id());
prev_is_import = true;
}
if (auto existing_function_decl = prev_inst.TryAs<SemIR::FunctionDecl>()) {
if (auto existing_function_decl =
prev_inst.inst.TryAs<SemIR::FunctionDecl>()) {
if (MergeFunctionRedecl(context, node_id, function_info, is_definition,
existing_function_decl->function_id,
prev_is_import)) {
prev_inst.is_import)) {
// When merging, use the existing function rather than adding a new one.
function_decl.function_id = existing_function_decl->function_id;
}