There’s a lot of talk in the non-exhaustive enum discussion about the source 
transition. So let me suggest a possible solution: @static imports.

Basically, it seems to me like resilience is going to introduce a lot of 
indirection, both in generated instructions and in the language. I think that 
making resilience opt-in on a declaration-by-declaration basis would make it 
difficult for average programmers to get right, so I support the idea of making 
Swift libraries resilient-by-default with opt-out abilities when it is obvious 
from the perspective of the library author that it should be so.

However, Apps are not libraries. Whereas libraries are a kind of theoretical 
block of code, and you naturally want them to be adaptable to different 
circumstances, Apps are the concrete things which actually use them. They might 
have a different perspective on what can be allowed to be non-resilient. Just 
like an App may be built to be compatible with a particular version of a 
library, I think it’s reasonable for it to be built expecting other “flavours” 
of the library, too - including a non-resilient flavour. We already kind of 
have something like this: executables can import modules as @testable, and 
those modules are required to be built with the “-enable-testing” flag.

My suggestion is that we create a new kind of import mode, "@static import" and 
some corresponding compiler flag. When you import a module using @static, you 
tell the compiler that your App requires exactly the module which it is being 
compiled alongside. When compiling your regular, resilient-by-default Swift 
libraries with the special flag, they will be transformed to fix them at their 
current version and provide later stages of the compiler as much information as 
if it was within the same module (i.e. applying final, @exhaustive, providing 
complete SIL, etc). App code will not be able to access “internal” members of 
the @static library (even though the compiler can see them). We might allow the 
same attribute to be applied to static libraries from C, which can be similarly 
freed of resilience concerns.

That would help ease code migration - for this and future resilience-related 
changes - because you’ll basically get the Swift 4 behaviour back for libraries 
which you control.

// Regular imports. We don’t control these libraries.
import Foundation
import UIKit
// Static imports. We control these; they will be embedded in the final product 
in some way. Everything is @exhaustive!
@static import MyDataModel
@static import SharedUIElements

- Karl
swift-evolution mailing list

Reply via email to