Просмотр исходного кода

Change `DeclNameStack::LookupOrAddName()` to return `SemIR::ScopeLookupResult` instead of a `pair` (#4852)

This makes the lookup API more consistent and would make it easier to
add poisoning location.
Part of #4622.
Boaz Brickner 1 год назад
Родитель
Сommit
f4e19f4390

+ 4 - 4
toolchain/check/decl_name_stack.cpp

@@ -186,15 +186,15 @@ auto DeclNameStack::AddNameOrDiagnose(NameContext name_context,
 auto DeclNameStack::LookupOrAddName(NameContext name_context,
                                     SemIR::InstId target_id,
                                     SemIR::AccessKind access_kind)
-    -> std::pair<SemIR::InstId, bool> {
+    -> SemIR::ScopeLookupResult {
   if (name_context.state == NameContext::State::Poisoned) {
-    return {SemIR::InstId::None, true};
+    return SemIR::ScopeLookupResult::MakePoisoned();
   }
   if (auto id = name_context.prev_inst_id(); id.has_value()) {
-    return {id, false};
+    return SemIR::ScopeLookupResult::MakeFound(id, access_kind);
   }
   AddName(name_context, target_id, access_kind);
-  return {SemIR::InstId::None, false};
+  return SemIR::ScopeLookupResult::MakeNotFound();
 }
 
 // Push a scope corresponding to a name qualifier. For example, for

+ 2 - 4
toolchain/check/decl_name_stack.h

@@ -238,12 +238,10 @@ class DeclNameStack {
                          SemIR::AccessKind access_kind) -> void;
 
   // Adds a name to name lookup if neither already declared nor poisoned in this
-  // scope. If declared, returns the existing `InstId` and false. If poisoned,
-  // returns `None` and true.
-  // TODO: Return the poisoning instruction if poisoned.
+  // scope.
   auto LookupOrAddName(NameContext name_context, SemIR::InstId target_id,
                        SemIR::AccessKind access_kind)
-      -> std::pair<SemIR::InstId, bool>;
+      -> SemIR::ScopeLookupResult;
 
  private:
   // Returns a name context corresponding to an empty name.

+ 7 - 4
toolchain/check/handle_class.cpp

@@ -105,18 +105,21 @@ static auto MergeOrAddName(Context& context, Parse::AnyClassDeclId node_id,
                            SemIR::ClassDecl& class_decl,
                            SemIR::Class& class_info, bool is_definition,
                            SemIR::AccessKind access_kind) -> void {
-  auto [prev_id, is_poisoned] = context.decl_name_stack().LookupOrAddName(
-      name_context, class_decl_id, access_kind);
-  if (is_poisoned) {
+  SemIR::ScopeLookupResult lookup_result =
+      context.decl_name_stack().LookupOrAddName(name_context, class_decl_id,
+                                                access_kind);
+  if (lookup_result.is_poisoned()) {
     // This is a declaration of a poisoned name.
     context.DiagnosePoisonedName(class_decl_id);
     return;
   }
 
-  if (!prev_id.has_value()) {
+  if (!lookup_result.is_found()) {
     return;
   }
 
+  SemIR::InstId prev_id = lookup_result.target_inst_id();
+
   auto prev_class_id = SemIR::ClassId::None;
   auto prev_import_ir_id = SemIR::ImportIRId::None;
   auto prev = context.insts().Get(prev_id);

+ 7 - 4
toolchain/check/handle_interface.cpp

@@ -59,12 +59,15 @@ static auto BuildInterfaceDecl(Context& context,
       SemIR::LibraryNameId::None)};
 
   // Check whether this is a redeclaration.
-  auto [existing_id, is_poisoned] = context.decl_name_stack().LookupOrAddName(
-      name_context, interface_decl_id, introducer.modifier_set.GetAccessKind());
-  if (is_poisoned) {
+  SemIR::ScopeLookupResult lookup_result =
+      context.decl_name_stack().LookupOrAddName(
+          name_context, interface_decl_id,
+          introducer.modifier_set.GetAccessKind());
+  if (lookup_result.is_poisoned()) {
     // This is a declaration of a poisoned name.
     context.DiagnosePoisonedName(interface_decl_id);
-  } else if (existing_id.has_value()) {
+  } else if (lookup_result.is_found()) {
+    SemIR::InstId existing_id = lookup_result.target_inst_id();
     if (auto existing_interface_decl =
             context.insts().Get(existing_id).TryAs<SemIR::InterfaceDecl>()) {
       auto existing_interface =

+ 4 - 3
toolchain/check/handle_namespace.cpp

@@ -42,12 +42,13 @@ auto HandleParseNode(Context& context, Parse::NamespaceId node_id) -> bool {
   auto namespace_id =
       context.AddPlaceholderInst(SemIR::LocIdAndInst(node_id, namespace_inst));
 
-  auto [existing_inst_id, is_poisoned] =
+  SemIR::ScopeLookupResult lookup_result =
       context.decl_name_stack().LookupOrAddName(name_context, namespace_id,
                                                 SemIR::AccessKind::Public);
-  if (is_poisoned) {
+  if (lookup_result.is_poisoned()) {
     context.DiagnosePoisonedName(namespace_id);
-  } else if (existing_inst_id.has_value()) {
+  } else if (lookup_result.is_found()) {
+    SemIR::InstId existing_inst_id = lookup_result.target_inst_id();
     if (auto existing =
             context.insts().TryGetAs<SemIR::Namespace>(existing_inst_id)) {
       // If there's a name conflict with a namespace, "merge" by using the