   /// Insert a new entry for an element at `index`.
   @inlinable
   @inline(__always)
-  internal func insert(_ index: Index) {
-    _sanityCheck(!isOccupied(index))
-    words[index.word].uncheckedInsert(index.bit)
+  internal func insert(_ bucket: Bucket) {
+    _sanityCheck(!isOccupied(bucket))
+    words[bucket.word].uncheckedInsert(bucket.bit)
   }
 
   @inlinable

  internal func clear() {
    if bucketCount < Word.capacity {
      // We have only a single partial word. Set all out of bounds bits, so that
      // `index(after:)` and `nextHole(atOrAfter:)` works correctly without a
      // special case.
      words[0] = Word.allBits.subtracting(elementsBelow: bucketCount)
    } else {
      words.assign(repeating: .empty, count: wordCount)

  @inline(__always)
  @inlinable
  internal func delete<D: _HashTableDelegate>(
    at bucket: Bucket,
    with delegate: D
  ) {
    _sanityCheck(isOccupied(bucket))

    // If we've put a hole in a chain of contiguous elements, some element after
    // the hole may belong where the new hole is.

    var hole = bucket
    var candidate = self.bucket(wrappedAfter: hole)

    guard _isOccupied(candidate) else {
      // Fast path: Don't get the first bucket when there's nothing to do.
