So now that Swift is ABI-stable on Darwin platforms, we can get all kinds of information by knowing the layout of type metadata. This is essentially what this library does.
For example, we could write a function that tells whether two generic types are the same nominal type:
func sameNominalTypes(_ lhs: Any.Type, _ rhs: Any.Type) -> Bool {
let lhsMetadataPtr = unsafeBitCast(lhs, to: UnsafePointer<Int>.self)
let rhsMetadataPtr = unsafeBitCast(rhs, to: UnsafePointer<Int>.self)
return lhsMetadataPtr.successor().pointee == rhsMetadataPtr.successor().pointee
}
assert(sameNominalTypes(Array<Int>.self, Array<String>.self))
assert(!sameNominalTypes(Array<Int>.self, Optional<Int>.self))
Here we're taking advantage of the fact that metatype value is just a pointer to the type metadata, and that the nominal type descriptor pointer is stored at offset 1 in the metadata record.
So the question is can we rely on this on non-Darwin platforms, and if not, is there a better way to do this? Right now it works, but I'm not sure this won't change, since ABI stability is not guaranteed on non-Darwin platforms.
Maybe there are some functions in the Swift runtime to do this kind of querying?