Resilient Enum Strategy

While Investigating swift source code and enums memory allocation, I found ResilientEnumImplStrategy. I see that it has llvm_unreachable("resilient enums are always indirect") in many methods.

Is it some future strategy for enums with indirect cases?

1 Like

Those methods are placeholders because they should never actually be invoked. All resilient types have their underlying layout abstracted from the client code, and should use the value witness operations from the ResilientTypeInfo template, all of which dynamically dispatch through the type's value witness table. On the implementation's side, within the module that defines the enum, the compiler will always choose one of the other concrete implementation strategies for the enum, which will be used to generate the type metadata and value witnesses for the type that clients from other modules can dispatch into. This allows the originating module to add new enum cases, which may fundamentally change the underlying layout strategy the compiler chooses for the enum, while retaining ABI compatibility with existing clients.

1 Like

Hm, I guess I dont't really understand what resilient type is. And what exactly do you mean by the client and module? For example, is my swift project a client and some imported interop ObjC/C++ library a module? Or can you provide a right example?

1 Like

No, I guess it is about generics, which size is unknown during compilation.

A resilient type is a type whose ABI can evolve separately from whatever code we're currently compiling. Currently that means (1) it's defined in a different module and (2) that module was built with resilience enabled. The most important place that happens is on Apple platforms with types defined in OS frameworks, but in principle any library could enable resilience.

The effect on the compiler is similar to that of unspecialized generics: the compiler cannot assume anything statically about the layout of the type.

4 Likes

Thanks! Things is much clearer now.

1 Like