Using the compiler with Xcode Version 13.3 (13E113) I noticed some interesting patterns when it comes to compiling enum definitions:
About indirect keyword
enum EnumA {
case one
case two(EnumA)
}
enum EnumB {
case one
case two([EnumB])
}
The compiler complains about adding indirect to EnumA, which makes sense. But why not for EnumB? Please refer the screenshot below. The difference of these two is that the type of the associated value in one is itself and another is array of itself.
The indirect keyword is only necessary if the enum is self-referential. EnumB isn't. The associated value is of type Array. That the array will contain instances of EnumB is not relevant.
This is broadly true for some definition of "recursive use." The real limitation here is that value types cannot have inline storage which is recursively referential, at any depth. The reason that Array doesn't cause issues is that Array stores its elements via an internal buffer which is allocated out-of-line of the value itself, and the inline storage for Array just holds a reference to the out-of-line storage.
See:
struct S {
var a: EnumA // error: value type 'S' cannot have a stored property that recursively contains it
}
enum EnumA {
case one
case two(S) // error: recursive enum 'EnumA' is not marked 'indirect'
}
Improved the accuracy of leak scanning in Instruments, Xcode’s memory graph debugger, and the leaks command line. The system now scans object references inside multi-payload enum cases more accurately, allowing more precise memory leak analysis and the identification of strong, weak, and unowned reference types. (33836721)
Thanks. That explains it. I was thinking if this is just for reminding users about the performance in memory handling, a warning might be enough instead of an error for it?