Add a comment explaining the extra comparison in raw_hash_set::operator==. Also add a small optimization to avoid the extra comparison in sets that use hash_default_eq as the key_equal functor.

Note that removing the comparison entirely causes the Table.Equality2 test case to fail.

PiperOrigin-RevId: 693447075
Change-Id: I769f75cf1cb27114455f1854e330c899cee55fc2
diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc
index 96d7744..68ea7a0 100644
--- a/absl/container/flat_hash_set_test.cc
+++ b/absl/container/flat_hash_set_test.cc
@@ -17,6 +17,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <string>
 #include <type_traits>
 #include <utility>
 #include <vector>
@@ -337,6 +338,19 @@
   EXPECT_THAT(s1, UnorderedElementsAre(2));
 }
 
+TEST(FlatHashSet, Equality) {
+  {
+    flat_hash_set<int> s1 = {1, 2, 3};
+    flat_hash_set<int> s2 = {1, 2, 3};
+    EXPECT_EQ(s1, s2);
+  }
+  {
+    flat_hash_set<std::string> s1 = {"a", "b", "c"};
+    flat_hash_set<std::string> s2 = {"a", "b", "c"};
+    EXPECT_EQ(s1, s2);
+  }
+}
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index cc693f6..76e12d7 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -3471,7 +3471,16 @@
     if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
     for (const value_type& elem : *outer) {
       auto it = PolicyTraits::apply(FindElement{*inner}, elem);
-      if (it == inner->end() || !(*it == elem)) return false;
+      if (it == inner->end()) return false;
+      // Note: we used key_equal to check for key equality in FindElement, but
+      // we may need to do an additional comparison using
+      // value_type::operator==. E.g. the keys could be equal and the
+      // mapped_types could be unequal in a map or even in a set, key_equal
+      // could ignore some fields that aren't ignored by operator==.
+      static constexpr bool kKeyEqIsValueEq =
+          std::is_same<key_type, value_type>::value &&
+          std::is_same<key_equal, hash_default_eq<key_type>>::value;
+      if (!kKeyEqIsValueEq && !(*it == elem)) return false;
     }
     return true;
   }