Avoid using common().slot_array() in raw_hash_set.h to benefit from the separate storage assumption.

Also remove the TODO about templating out of line functions on whether the allocator is default or not.

Note: we don't currently observe codegen diffs from this change, but presumably it could be an improvement in the future.
PiperOrigin-RevId: 1007354258
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index a97bab2..3a5a1ca 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1393,16 +1393,18 @@
 
   void set_control(ctrl_t* c) { heap_or_soo_.control().set(c); }
 
-  // Note: we can't use slots() because Qt defines "slots" as a macro.
   // Returns pointer to the slots of a table with explicit capacity that must be
   // equal to the actual capacity of the table.
   // Table must be large.
-  void* slot_array(size_t capacity) const {
-    ABSL_SWISSTABLE_ASSERT(capacity == this->capacity());
+  // Note: we can't use `slots()` because Qt defines `slots` as a macro.
+  // Note: we take `ctrl` as a parameter so that raw_hash_set can benefit from
+  // the separate storage assumption.
+  void* slot_array(ctrl_t* ctrl, size_t capacity) const {
+    ABSL_SWISSTABLE_ASSERT(ctrl == this->control());
     ABSL_ASSUME(capacity > kMaxSmallCapacity);
-    ctrl_t* ctrl = control();
     return ctrl + NumControlBytesForLargeTable(capacity);
   }
+  void* slot_array(size_t cap) const { return slot_array(control(), cap); }
   // Returns pointer to the single slot of a table with capacity 1.
   void* single_non_soo_slot() const {
     ABSL_SWISSTABLE_ASSERT(capacity() == 1);
@@ -4112,15 +4114,18 @@
       // With this assumption, the second lookup avoids reloading capacity.
       // Note: for custom allocators, `this` may be part of the same allocation
       // as the control bytes so we cannot make this assumption.
-      // TODO(ezb): we could move this assumption into CommonFields::control()
+      // Note: we could move this assumption into CommonFields::control()
       // if we template the type-erased functions on whether the allocator is
-      // default or not.
+      // default or not, but it adds a lot of complexity, and we can avoid
+      // reloads in raw_hash_set.cc functions in other ways.
       ABSL_SWISSTABLE_ASSUME_SEPARATE_STORAGE(ctrl, this);
     }
     return ctrl;
   }
   slot_type* slot_array(size_t capacity) const {
-    return static_cast<slot_type*>(common().slot_array(capacity));
+    // Note: we don't use common().slot_array(capacity) here because it misses
+    // the separate storage assumption in raw_hash_set::control().
+    return static_cast<slot_type*>(common().slot_array(control(), capacity));
   }
   slot_type* soo_slot() {
     ABSL_SWISSTABLE_ASSERT(is_soo());
@@ -4133,8 +4138,8 @@
   }
   slot_type* single_slot() {
     ABSL_SWISSTABLE_ASSERT(is_small());
-    // Note: we don't use common().single_non_soo_slot() here because
-    // control() is more efficient (due to separate storage assume).
+    // Note: we don't use common().single_non_soo_slot() here because it misses
+    // the separate storage assumption in raw_hash_set::control().
     return SooEnabled() ? soo_slot() : to_slot(control());
   }
   const slot_type* single_slot() const {