mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
We need to arrange enum type metadata in a way where a client can fish out generic parameters without knowing if we have a payload size or not. The payload size is only used inside the module that defined the enum, and may change if new cases are added. So put the generic parameters first before the payload size, and don't crash when an EnumMetadataScanner is used with a resilient enum.
206 lines
4.3 KiB
Swift
206 lines
4.3 KiB
Swift
import resilient_struct
|
|
|
|
// Fixed-layout enum with resilient members
|
|
@_fixed_layout public enum SimpleShape {
|
|
case KleinBottle
|
|
case Triangle(Size)
|
|
}
|
|
|
|
// Fixed-layout enum with resilient members
|
|
@_fixed_layout public enum Shape {
|
|
case Point
|
|
case Rect(Size)
|
|
case RoundedRect(Size, Size)
|
|
}
|
|
|
|
// Fixed-layout enum with indirect resilient members
|
|
@_fixed_layout public enum FunnyShape {
|
|
indirect case Parallelogram(Size)
|
|
indirect case Trapezoid(Size)
|
|
}
|
|
|
|
// The enum payload has fixed layout inside this module, but
|
|
// resilient layout outside. Make sure we emit the payload
|
|
// size in the metadata.
|
|
|
|
public struct Color {
|
|
public let r: Int, g: Int, b: Int
|
|
|
|
public init(r: Int, g: Int, b: Int) {
|
|
self.r = r
|
|
self.g = g
|
|
self.b = b
|
|
}
|
|
}
|
|
|
|
@_fixed_layout public enum CustomColor {
|
|
case Black
|
|
case White
|
|
case Custom(Color)
|
|
case Bespoke(Color, Color)
|
|
}
|
|
|
|
// Resilient enum
|
|
public enum Medium {
|
|
// Indirect case
|
|
indirect case Pamphlet(Medium) // -1
|
|
|
|
// Case with resilient payload
|
|
case Postcard(Size) // -2
|
|
|
|
// Empty cases
|
|
case Paper // 0
|
|
case Canvas // 1
|
|
}
|
|
|
|
// Indirect resilient enum
|
|
public indirect enum IndirectApproach {
|
|
case Angle(Double) // -1
|
|
}
|
|
|
|
// Resilient enum with resilient empty payload case
|
|
public struct EmptyStruct {
|
|
public init() {}
|
|
}
|
|
|
|
public enum ResilientEnumWithEmptyCase {
|
|
case A // 0
|
|
case B // 1
|
|
case Empty(EmptyStruct) // -1
|
|
}
|
|
|
|
public func getResilientEnumWithEmptyCase() -> [ResilientEnumWithEmptyCase] {
|
|
return [.A, .B, .Empty(EmptyStruct())]
|
|
}
|
|
|
|
// Specific enum implementations for executable tests
|
|
public enum ResilientEmptyEnum {
|
|
case X
|
|
}
|
|
|
|
public enum ResilientSingletonEnum {
|
|
case X(AnyObject)
|
|
}
|
|
|
|
public enum ResilientSingletonGenericEnum<T> {
|
|
case X(T)
|
|
}
|
|
|
|
public enum ResilientNoPayloadEnum {
|
|
case A
|
|
case B
|
|
case C
|
|
}
|
|
|
|
public enum ResilientSinglePayloadEnum {
|
|
case X(AnyObject) // -1
|
|
case A // 0
|
|
case B // 1
|
|
case C // 2
|
|
}
|
|
|
|
public enum ResilientSinglePayloadGenericEnum<T> {
|
|
case X(T) // -1
|
|
case A // 0
|
|
case B // 1
|
|
case C // 2
|
|
}
|
|
|
|
public class ArtClass {
|
|
public init() {}
|
|
}
|
|
|
|
public enum ResilientMultiPayloadEnum {
|
|
case A
|
|
case B
|
|
case C
|
|
case X(Int)
|
|
case Y(Int)
|
|
}
|
|
|
|
public func makeResilientMultiPayloadEnum(_ n: Int, i: Int)
|
|
-> ResilientMultiPayloadEnum {
|
|
switch i {
|
|
case 0:
|
|
return .A
|
|
case 1:
|
|
return .B
|
|
case 2:
|
|
return .C
|
|
case 3:
|
|
return .X(n)
|
|
case 4:
|
|
return .Y(n)
|
|
default:
|
|
while true {}
|
|
}
|
|
}
|
|
|
|
public enum ResilientMultiPayloadEnumSpareBits {
|
|
case A // 0
|
|
case B // 1
|
|
case C // 2
|
|
case X(ArtClass) // -1
|
|
case Y(ArtClass) // -2
|
|
}
|
|
|
|
public func makeResilientMultiPayloadEnumSpareBits(_ o: ArtClass, i: Int)
|
|
-> ResilientMultiPayloadEnumSpareBits {
|
|
switch i {
|
|
case 0:
|
|
return .A
|
|
case 1:
|
|
return .B
|
|
case 2:
|
|
return .C
|
|
case 3:
|
|
return .X(o)
|
|
case 4:
|
|
return .Y(o)
|
|
default:
|
|
while true {}
|
|
}
|
|
}
|
|
|
|
public typealias SevenSpareBits = (Bool, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
|
|
|
|
public enum ResilientMultiPayloadEnumSpareBitsAndExtraBits {
|
|
// On 64-bit little endian, 7 spare bits at the LSB end
|
|
case P1(SevenSpareBits)
|
|
// On 64-bit, 8 spare bits at the MSB end and 3 at the LSB end
|
|
case P2(ArtClass)
|
|
case P3(ArtClass)
|
|
case P4(ArtClass)
|
|
case P5(ArtClass)
|
|
case P6(ArtClass)
|
|
case P7(ArtClass)
|
|
case P8(ArtClass)
|
|
}
|
|
|
|
public enum ResilientMultiPayloadGenericEnum<T> {
|
|
case A // 0
|
|
case B // 1
|
|
case C // 2
|
|
case X(T) // -1
|
|
case Y(T) // -2
|
|
}
|
|
|
|
public enum ResilientMultiPayloadGenericEnumFixedSize<T> {
|
|
case A // 0
|
|
case B // 1
|
|
case C // 2
|
|
case X(Int) // -1
|
|
case Y(Int) // -2
|
|
}
|
|
|
|
public enum ResilientIndirectEnum {
|
|
// 0
|
|
case Base
|
|
|
|
// -1
|
|
indirect case A(ResilientIndirectEnum)
|
|
|
|
// -2
|
|
indirect case B(ResilientIndirectEnum, ResilientIndirectEnum)
|
|
}
|