Skip to content

rawValue initialization of imported closed enums should check cases #81696

Open
@zackbach

Description

@zackbach

Description

C enums marked as __attribute__((enum_extensibility(closed))) (or using NS_CLOSED_ENUM) will be imported as @frozen Swift enums, not requiring default branches for switches. However, constructing such enums with init?(rawValue:) will not fail. Switching on such enums will reproducibly trap at runtime with "unexpected enum case while switching".

Reproduction

enum __attribute__((enum_extensibility(closed))) ClosedEnum {
  A0, A1
};
// import the ClosedEnum from C
let neither = ClosedEnum(rawValue: 2);
switch neither {
  case .A0:
    print("A0");
  case .A1:
    print("A1");
  case .none:
    print("none");
}

Stack dump

$ swift run
Building for debugging...
[1/1] Write swift-version-327D651943494526.txt
Build of product 'SLib' complete! (0.10s)
true
Fatal error: unexpected enum case while switching on value of type 'Optional<ClosedEnum>'

💣 Program crashed: System trap at 0x00000001a51c15f8

Thread 0 crashed:

0 SLib_main + 956 in SLib at tmp/Sources/SLib/main.swift:40:8

    38│   case .A0:
    39│     print("A0");
    40│   case .A1:                                                                                                                                                                                              
      │        ▲
    41│     print("A1");
    42│   case .none:

Backtrace took 0.10s

Expected behavior

init?(rawValue:) should produce nil when given rawValues which do not correspond to the values associated with the enumerators listed in the imported enum's definition. This is consistent with Swift's behavior for initializing enums. According to old documentation, this "probably should" happening.

Environment

$ swiftc -version
Apple Swift version 6.1 (swift-6.1-RELEASE)
Target: arm64-apple-macosx15.0

Additional information

I came across this bug while playing around with -strict-memory-safety on Apple Swift version 6.2-dev (LLVM 81ab6d9f7e4810f, Swift 9cc1947527bacea). It seems important to ensure safe interoperability.

This documentation explicitly talks about how imported enums interacting with switch exhaustiveness checks is hazardous in the presence of unexpected bit patterns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions