|
|
@@ -80,6 +80,14 @@ static auto CopyNameFromImportIR(Context& context,
|
|
|
return import_name_id;
|
|
|
}
|
|
|
|
|
|
+namespace {
|
|
|
+struct NamespaceResult {
|
|
|
+ SemIR::NameScopeId name_scope_id;
|
|
|
+ SemIR::InstId inst_id;
|
|
|
+ bool is_duplicate_of_namespace_in_current_package;
|
|
|
+};
|
|
|
+} // namespace
|
|
|
+
|
|
|
// Adds a namespace to the IR. The bool on return is true if there was a name
|
|
|
// conflict. diagnose_duplicate_namespace is used when handling a cross-package
|
|
|
// import, where an existing namespace is in the current package and the new
|
|
|
@@ -89,7 +97,7 @@ static auto AddNamespace(Context& context, SemIR::TypeId namespace_type_id,
|
|
|
SemIR::NameScopeId parent_scope_id,
|
|
|
bool diagnose_duplicate_namespace,
|
|
|
llvm::function_ref<SemIR::InstId()> make_import_id)
|
|
|
- -> std::tuple<SemIR::NameScopeId, SemIR::InstId, bool> {
|
|
|
+ -> NamespaceResult {
|
|
|
auto* parent_scope = &context.name_scopes().Get(parent_scope_id);
|
|
|
auto insert_result =
|
|
|
parent_scope->name_map.Insert(name_id, parent_scope->names.size());
|
|
|
@@ -159,13 +167,14 @@ static auto CacheCopiedNamespace(
|
|
|
|
|
|
// Copies a namespace from the import IR, returning its ID. This may diagnose
|
|
|
// name conflicts, but that won't change the result because namespaces supersede
|
|
|
-// other names in conflicts. copied_namespaces is optional.
|
|
|
+// other names in conflicts. The bool on return is true if there was a name
|
|
|
+// conflict. copied_namespaces is optional.
|
|
|
static auto CopySingleNameScopeFromImportIR(
|
|
|
Context& context, SemIR::TypeId namespace_type_id,
|
|
|
Map<SemIR::NameScopeId, SemIR::NameScopeId>* copied_namespaces,
|
|
|
SemIR::ImportIRId ir_id, SemIR::InstId import_inst_id,
|
|
|
SemIR::NameScopeId import_scope_id, SemIR::NameScopeId parent_scope_id,
|
|
|
- SemIR::NameId name_id) -> std::pair<SemIR::NameScopeId, SemIR::InstId> {
|
|
|
+ SemIR::NameId name_id) -> NamespaceResult {
|
|
|
// Produce the namespace for the entry.
|
|
|
auto make_import_id = [&]() {
|
|
|
auto entity_name_id = context.entity_names().Add(
|
|
|
@@ -182,19 +191,19 @@ static auto CopySingleNameScopeFromImportIR(
|
|
|
context.import_ref_ids().push_back(inst_id);
|
|
|
return inst_id;
|
|
|
};
|
|
|
- auto [namespace_scope_id, namespace_inst_id, _] =
|
|
|
+ NamespaceResult result =
|
|
|
AddNamespace(context, namespace_type_id, name_id, parent_scope_id,
|
|
|
/*diagnose_duplicate_namespace=*/false, make_import_id);
|
|
|
|
|
|
- auto namespace_const_id = context.constant_values().Get(namespace_inst_id);
|
|
|
+ auto namespace_const_id = context.constant_values().Get(result.inst_id);
|
|
|
context.import_ir_constant_values()[ir_id.index].Set(import_inst_id,
|
|
|
namespace_const_id);
|
|
|
|
|
|
if (copied_namespaces) {
|
|
|
CacheCopiedNamespace(*copied_namespaces, import_scope_id,
|
|
|
- namespace_scope_id);
|
|
|
+ result.name_scope_id);
|
|
|
}
|
|
|
- return {namespace_scope_id, namespace_inst_id};
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
// Copies ancestor name scopes from the import IR. Handles the parent traversal.
|
|
|
@@ -242,7 +251,7 @@ static auto CopyAncestorNameScopesFromImportIR(
|
|
|
CopySingleNameScopeFromImportIR(
|
|
|
context, namespace_type_id, &copied_namespaces, ir_id,
|
|
|
import_scope.inst_id, import_scope_id, scope_cursor, name_id)
|
|
|
- .first;
|
|
|
+ .name_scope_id;
|
|
|
}
|
|
|
|
|
|
return scope_cursor;
|
|
|
@@ -372,7 +381,7 @@ auto ImportApiFile(Context& context, SemIR::TypeId namespace_type_id,
|
|
|
SemIR::ImportIRId::ApiForImpl, todo_scope.api_inst_id,
|
|
|
todo_scope.api_scope_id, todo_scope.impl_parent_scope_id,
|
|
|
todo_scope.impl_name_id)
|
|
|
- .first;
|
|
|
+ .name_scope_id;
|
|
|
ImportScopeFromApiFile(context, api_sem_ir, todo_scope.api_scope_id,
|
|
|
impl_scope_id, todo_scopes);
|
|
|
}
|
|
|
@@ -436,13 +445,13 @@ auto ImportLibrariesFromOtherPackage(Context& context,
|
|
|
|
|
|
auto name_id = SemIR::NameId::ForIdentifier(package_id);
|
|
|
|
|
|
- auto [namespace_scope_id, namespace_inst_id, is_duplicate] = AddNamespace(
|
|
|
+ NamespaceResult result = AddNamespace(
|
|
|
context, namespace_type_id, name_id, SemIR::NameScopeId::Package,
|
|
|
/*diagnose_duplicate_namespace=*/true, [&] { return import_decl_id; });
|
|
|
- auto namespace_const_id = context.constant_values().Get(namespace_inst_id);
|
|
|
+ auto namespace_const_id = context.constant_values().Get(result.inst_id);
|
|
|
|
|
|
- auto& scope = context.name_scopes().Get(namespace_scope_id);
|
|
|
- scope.is_closed_import = !is_duplicate;
|
|
|
+ auto& scope = context.name_scopes().Get(result.name_scope_id);
|
|
|
+ scope.is_closed_import = !result.is_duplicate_of_namespace_in_current_package;
|
|
|
for (auto import_ir : import_irs) {
|
|
|
auto ir_id = AddImportIR(context, import_ir);
|
|
|
scope.import_ir_scopes.push_back({ir_id, SemIR::NameScopeId::Package});
|
|
|
@@ -500,13 +509,13 @@ static auto AddNamespaceFromOtherPackage(Context& context,
|
|
|
-> SemIR::InstId {
|
|
|
auto namespace_type_id =
|
|
|
context.GetBuiltinType(SemIR::BuiltinInstKind::NamespaceType);
|
|
|
- auto [new_scope_id, namespace_inst_id] = CopySingleNameScopeFromImportIR(
|
|
|
+ NamespaceResult result = CopySingleNameScopeFromImportIR(
|
|
|
context, namespace_type_id, /*copied_namespaces=*/nullptr, import_ir_id,
|
|
|
import_inst_id, import_ns.name_scope_id, parent_scope_id, name_id);
|
|
|
- context.name_scopes()
|
|
|
- .Get(new_scope_id)
|
|
|
- .import_ir_scopes.push_back({import_ir_id, import_ns.name_scope_id});
|
|
|
- return namespace_inst_id;
|
|
|
+ auto& scope = context.name_scopes().Get(result.name_scope_id);
|
|
|
+ scope.is_closed_import = !result.is_duplicate_of_namespace_in_current_package;
|
|
|
+ scope.import_ir_scopes.push_back({import_ir_id, import_ns.name_scope_id});
|
|
|
+ return result.inst_id;
|
|
|
}
|
|
|
|
|
|
auto ImportNameFromOtherPackage(
|