-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
Description
I could understand that
Enumerations imported using the NS_ENUM macro won’t fail when you initialize one with a raw value that does not correspond to an enumeration case. This characteristic facilitates compatibility with C, which allows any value to be stored in an enumeration, including values used internally but not exposed in headers.
However, we should not allow that for NS_CLOSED_ENUM because it is unsafe and causes unexpected crashes.
For example:
typedef NS_ENUM(NSInteger, IntEnum) {
IntEnumZero,
IntEnumOne,
};Since it is imported as non-frozen enum so I have to handle @unknown default anyway.
if let ie = IntEnum(rawValue: 100) {
switch ie {
case .zero:
print("zero")
case .one:
print("one")
@unknown default:
print("unknown")
}
}However, if I define it as NS_CLOSED_ENUM:
typedef NS_CLOSED_ENUM(NSInteger, IntEnum) {
IntEnumZero,
IntEnumOne,
};It should be imported as frozen enum and only those raw values declared in the enum definition should convert successfully to the enum. Unfortunately, that’s not the case and it causes crash:
if let ie = IntEnum(rawValue: 100) {
switch ie {
case .zero:
print("zero")
case .one: // Thread 1: Fatal error: unexpected enum case 'IntEnum(rawValue: 100)'
print("one")
}
}Reproduction
typedef NS_CLOSED_ENUM(NSInteger, IntEnum) {
IntEnumZero,
IntEnumOne,
};if let ie = IntEnum(rawValue: 100) {
switch ie {
case .zero:
print("zero")
case .one: // Thread 1: Fatal error: unexpected enum case 'IntEnum(rawValue: 100)'
print("one")
}
}Stack dump
#0 0x0000000193dab0dc in _swift_runtime_on_report ()
#1 0x0000000193e91d08 in _swift_stdlib_reportFatalError ()
#2 0x0000000193ec398c in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, flags: Swift.UInt32) -> Swift.Never ()
#3 0x0000000193e9f378 in _assertionFailure ()
#4 0x0000000193ec4734 in _diagnoseUnexpectedEnumCaseValue ()
Expected behavior
IntEnum(rawValue: 100) returns nil
Environment
swift-driver version: 1.127.14.1 Apple Swift version 6.2.1 (swiftlang-6.2.1.4.8 clang-1700.4.4.1)
Additional information
No response