Hi, everyone! It's about time we give an update on module stability. TLDR: it's looking good.
We've gotten our new stable module interface format up and working in the form of the ".swiftinterface" files you can see in a downloadable toolchain. The contents of these files is pretty much following the plan I laid out in "Plan for module stability", which is good! Though there are a few extra things in that file format that aren't found in normal source files (mostly around struct fields, as predicted way back in July).
By default, the interface files will be used whenever the corresponding "compiled module" (.swiftmodule file) is either absent or unusable. We have an environment variable that can change this preference for debugging purposes, but we don't expect anyone to need that in real life. Other than that, there's nothing special about using them; just have them show up in your search path wherever you'd currently use a .swiftmodule. (That includes both the "flat" layout "MyLibrary.swiftinterface" and the "target-specific" layout "MyLibrary.swiftmodule/x86_64-apple-macos.swiftinterface".)
There is still one big limitation: .swiftinterface files require
-enable-library-evolution, the flag that Ben mentions in "Pitch: Library Evolution for Stable ABIs". Why? It's again because of those pesky stored properties: without
-enable-library-evolution, the compiler has to be able to describe the layout of every type at compile time, but that might depend on private types that aren't present in the interface. We have ideas about describing type layout without actually mentioning concrete types, but it's tricky. (I'll write more about this in a later post; someone remind me to do that in a week or something.)
This limitation means that interface files can't yet be used for cross-module dependency analysis. But they're close! And that's a possibility even without implementing something that you can read back in; it just has to be something that changes whenever the layout of a public type changes. That's probably not something that we'll pick up in 5.1, though.
As mentioned in the original post, these interfaces aren't meant to support
@testable import, nor can they take the place of the serialized ASTs in compiled modules for debugging purposes, because they don't contain information about non-public, non-
@usableFromInlinedeclarations. @Adrian_Prantl and others on Apple's LLDB team have been working on separate approaches to reduce the debugger's reliance on having the compiled modules in exactly the same form as they were when an app or library was built, but they're mostly separate from this.
As brought up in the original thread, we plan to limit this format to Swift 5 mode (i.e. no Swift 4 or Swift 4.2) just to cut down on the input space in the first release. I haven't actually put this restriction in yet, but I don't expect it to be burdensome since Swift 5 is much closer to 4 and 4.2 than, say, 4 was to 3. (We don't talk about 3 from 2.)
Oh, and we've been testing this in the main repository by building overlay interfaces to the old compiled module format. Within Apple, we've tried building various projects against those interfaces, as well as converting pieces of larger projects to generate interfaces as well.
I think that's about it! Any questions?
P.S. Final terminology: "module interface" (.swiftinterface file, the new thing) and "compiled module" (.swiftmodule file, the old thing, still useful, also our cached format as described in the original post)