Repository: carbon-language/carbon-lang
File: toolchain/check/decl_name_stack.cpp (C++)

Code before:
                "scoped entity");
            context_->emitter().Emit(name_context.loc_id,
                                     QualifiedDeclOutsideScopeEntity);
          }
        }

        // Exports are only tracked when the declaration is at the file-level
        // scope. Otherwise, it's in some other entity, such as a class.
        if (access_kind == SemIR::AccessKind::Public &&
            name_context.initial_scope_index == ScopeIndex::Package) {
          context_->AddExport(target_id);
        }

        auto add_scope = [&] {
          int index = name_scope.names.size();
          name_scope.names.push_back(
              {.name_id = name_context.unresolved_name_id,
               .inst_id = target_id,
               .access_kind = access_kind});
          return index;
        };
        auto result = name_scope.name_map.Insert(
            name_context.unresolved_name_id, add_scope);
        CARBON_CHECK(
            result.is_inserted(),
            "Duplicate names should have been resolved previously: {0} in {1}",
            name_context.unresolved_name_id, name_context.parent_scope_id);
      }
      break;

    default:
      CARBON_FATAL("Should not be calling AddName");
      break;
  }
}

auto DeclNameStack::AddNameOrDiagnoseDuplicate(NameContext name_context,
                                               SemIR::InstId target_id,
                                               SemIR::AccessKind access_kind)
    -> void {
  if (auto id = name_context.prev_inst_id(); id.is_valid()) {
    context_->DiagnoseDuplicateName(target_id, id);
  } else {
    AddName(name_context, target_id, access_kind);
  }
}

auto DeclNameStack::LookupOrAddName(NameContext name_context,
                                    SemIR::InstId target_id,
                                    SemIR::AccessKind access_kind)
    -> SemIR::InstId {

Review comment (bug):
I was going to approve, but I see the diagnostic is changed. 
The diagnostic on duplicate entry before:
`"Duplicate names should have been resolved previously: {unresolved_name_id} in {parent_scope_id}"`
The diagnostic on duplicate now:
`"Failed to add required name: {unresolved_name_id}"`

Maybe that's fine, or maybe we should pass in the parent scope id, not sure so I'll let someone else review.



Code after:
                "scoped entity");
            context_->emitter().Emit(name_context.loc_id,
                                     QualifiedDeclOutsideScopeEntity);
          }
        }

        // Exports are only tracked when the declaration is at the file-level
        // scope. Otherwise, it's in some other entity, such as a class.
        if (access_kind == SemIR::AccessKind::Public &&
            name_context.initial_scope_index == ScopeIndex::Package) {
          context_->AddExport(target_id);
        }

        name_scope.AddRequired({.name_id = name_context.unresolved_name_id,
                                .inst_id = target_id,
                                .access_kind = access_kind});
      }
      break;

    default:
      CARBON_FATAL("Should not be calling AddName");
      break;
  }
}

auto DeclNameStack::AddNameOrDiagnoseDuplicate(NameContext name_context,
                                               SemIR::InstId target_id,
                                               SemIR::AccessKind access_kind)
    -> void {
  if (auto id = name_context.prev_inst_id(); id.is_valid()) {
    context_->DiagnoseDuplicateName(target_id, id);
  } else {
    AddName(name_context, target_id, access_kind);
  }
}

auto DeclNameStack::LookupOrAddName(NameContext name_context,
                                    SemIR::InstId target_id,
                                    SemIR::AccessKind access_kind)
    -> SemIR::InstId {
  if (auto id = name_context.prev_inst_id(); id.is_valid()) {
    return id;
  }
  AddName(name_context, target_id, access_kind);
  return SemIR::InstId::Invalid;
}

// Push a scope corresponding to a name qualifier. For example, for
// `fn Class(T:! type).F(n: i32)` we will push the scope for `Class(T:! type)`
// between the scope containing the declaration of `T` and the scope
// containing the declaration of `n`.