For unit-testing purposes, I'm investigating one very hacky idea which involves creating Swift types dynamically in the runtime. I was able to make it work (more testing needed) as a function returning existential type:
@_silgen_name("WrittenInC_asBar")
func asBar<T: Foo>(_ foo: T) -> any Bar
extern "C" void WrittenInC_asBar(
SWIFT_INDIRECT_RESULT ExistentialValue * result,
swift::OpaqueValue * foo,
swift::Metadata * fooType,
swift::WitnessTable const * fooWitness
) SWIFT_CC(swift) {
/// actual implementation
}
But that is not ideal for the intended use cases. Ideally, I would like to ship it as a function with opaque return type, so that returned value could be used with generic types without extra steps. For every single T
type of the result is always the same, so logically it makes sense.
@_silgen_name("WrittenInC_asBar")
func asBar<T: Foo>(_ foo: T) -> some Bar
AFAICS, opaque return type is described as a mangled name. In my case the type would be produced by a function. Is there an encoding of the mangled name that would describe the type by a pointer to metatype factory function?
Ideally I want a function of signature (any Foo.Type) -> any Bar.Type
- taking both metadata and witness table as an input. But if not, I guess I could live with (Any.Type) -> Any.Type
too - either by finding witness for Foo
in the runtime, or by splitting creation process in two phases.