Enumerating a parameter pack of metatype instances

Welp, it looks like ManagedBuffer isn’t going to work out for my needs, since I can’t figure out how to alter the parameter pack I pass to the Elements type parameter. And since ManagedRawBuffer doesn’t exist yet, that means I am left rolling my own storage based on UnsafeRawBufferPointer.

Since the layout can be determined dynamically, and I want to offer field-level access, I will need to store the offset of each field. @Slava_Pestov’s comment implied this might require writing a type-erased wrapper around Field.Type, since metatypes conforming to Field are not subtypes of the Field.Type existential. But the introduction of explicit any has given us the ability to spell a different type which seems to fit the bill:

protocol Field: BitwiseCopyable { }
struct FirstName: Field { }
struct LastName: Field { }

struct Table {
  let storage: UnsafeRawBufferPointer
  let fields: [any (Field.Type)]
  let offsets: [Int]

struct Table {
  // TODO: move this to a class so it can be refcounted (and ideally tail-allocated)
  var storage: UnsafeMutableRawBufferPointer
  var fields: [any (Field.Type)] = .init()
  var offsets: [Int]

  func _stride<F: Field>(of field: F.Type) -> (stride: Int) { MemoryLayout<F>.stride }

  init<each F: Field>(fields fieldTypes: repeat (each F).Type) {
    var lastFieldEnd = 0
    for fieldType in repeat each fieldTypes {
        fields.append(fieldType)
        let offset = lastFieldEnd // TODO: round up to respect alignment of this field type
        offsets.append(lastFieldEnd)
        lastFieldEnd += _stride(of: fieldType)
    }
    // TODO: compute offset of and initialize storage buffer
  }
} 

One surprise was the need to explicitly specify the type of fields. If I try to use type inference from the initialization expression, the compiler interprets any as referring to the SIMD.any function:

var fields = [any (Field.Type)]()
//                 ^ error: cannot convert value of type '(any Field.Type).Type' to expected argument type 'SIMDMask<Storage>'
//            ^ error: generic parameter 'Storage' could not be inferred
//            ^ error: cannot call value of non-function type '[Bool]'

Edit: one more weird thing… the _stride(of:) function doesn’t work. But I can fall back to the old approach of declaring static properties an extension on Field and calling them on an instance of any (Field.Type):

extension Field {
  var stride: Int { MemoryLayout<Self>.stride }
}

/* ... */

    init<each F: Field>(fields fieldTypes: repeat (each F).Type) {
        for fieldType in repeat each fieldTypes {
            lastFieldEnd += fieldType.stride // this works!
    }

I guess this is a bug in implicitly opened existentials?