Where can I find the spec for the generics, specifically the reasoning why swift went for passing generic arguments as (method) parameters and using the generic type size to calculate the offset of fields/size of types? (Compared to .net/c++/rust where there are distinct instantiations of every struct/class sub type)
There are two documents under docs folder in the swift repo that talk about Generics:
I think the point you are interested about is explained in this Implementation Model section.
Swift actually also has the ability to specialize generic functions, i.e. monomorphization.
By default, protocol witness tables are used:
Swift Witness Tables
Swift makes the interesting realization that by using dictionary passing and also putting the size of types and how to move, copy and free them into the tables, they can provide all the information required to work with any type in a uniform way without boxing them. This way Swift can implement generics without monomorphization and without allocating everything into a uniform representation! They still pay the cost of all the dynamic lookups that all boxing-family implementations pay, but they save on the allocation, memory and cache-incoherency costs. The Swift compiler also has the ability to specialize (monomorphize) and inline generics within a module and across modules with functions annotated
@inlinableto avoid these costs if it wants to, presumably using heuristics about how much it would bloat the code.
This functionality also explains how Swift can implement ABI stability in a way that allows adding and rearranging fields in
structs, although they provide a
@frozenattribute to opt out of dynamic lookups for performance reasons.
Excerpt from the excellent blog post "Models of Generics and Metaprogramming: Go, Rust, Swift, D and More", which is a comprehensive overview of approaches for implementing generics.
Slava and John’s 2017 LLVM Dev Meeting talk about the generics system also starts with a discussion of the reasons and presents a conceptual explanation of how it works. It’s oriented towards compiler engineers not necessarily familiar with Swift.
Very useful info. I'm (successfully) interacting with swift already for non generic types and methods from another programming language. Are there any docs on the witness table internals? Or alternatively places in the compiler to read to see how they are made up?