xamarin / binding-tools-for-swift

MIT License
160 stars 21 forks source link

[parser] support for any keyword #774

Closed stephen-hawley closed 1 year ago

stephen-hawley commented 1 year ago

Swift added the any keyword to the language. It gets used whenever a type is a boxed protocol (aka, existential container) and by default, the swift compiler will generate any for any type that would get bound into an existential container. The reasoning behind this, I've read, is that putting in any draws attention to this so that when you're using it, you realize that there is a cost to using this type.

What is the cost? An existential container is a variable sized struct that contains a fixed-sized payload of 3 machine words, followed by a pointer to the type metadata for the value in the payload. This is then followed by 0 or more protocol witness table pointers. What is a witness table? It's a vtable -a table of function pointers that go to methods- that is sits separate from a type.

The cost is in allocating (if needed) the existential container, copying (with reference counting) the value into the payload OR allocating room on the heap for a copy of the value , copying (with reference counting) and then putting the pointer to the value into the payload. So, no, it's not free. I do not, however, see how the use of any does anything to draw attention to the cost other than to add syntactic clutter to the language.

public func doSomething (a: any SomeProtocol) { }

By comparison, you could also write equivalent code that is nearly equivalent to this like so:

public func doSomething<T:SomeProtocol> (a: T) { }

This uses a different ABI as there is no existential container and the type metadata pointer and protocol witness table(s) get passed in implicit arguments.

In order to do this I:

Added a unit test.