Skip to content

Commit bb43642

Browse files
authored
Workaround for runtime returning wrong enum tag (#94)
Fix #72. In release builds, Swift <=5.7 may return the wrong tag for single-case enums that nest another enum. We can work around this by always returning "0" as the tag for single case enums.
1 parent 15bba50 commit bb43642

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ test-swift:
1313
--enable-test-discovery \
1414
--parallel
1515
swift test \
16-
-c release \
16+
-c release \
1717
--enable-test-discovery \
1818
--parallel
1919

Sources/CasePaths/EnumReflection.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,10 @@ private struct EnumMetadata: Metadata {
464464
}
465465

466466
func tag<Enum>(of value: Enum) -> UInt32 {
467-
withUnsafePointer(to: value) {
467+
// NB: Workaround for https://github.com/apple/swift/issues/61708
468+
guard self.typeDescriptor.emptyCaseCount + self.typeDescriptor.payloadCaseCount > 1
469+
else { return 0 }
470+
return withUnsafePointer(to: value) {
468471
self.valueWitnessTable.getEnumTag($0, self.ptr)
469472
}
470473
}

Tests/CasePathsTests/CasePathsTests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,25 @@ final class CasePathsTests: XCTestCase {
11701170
XCTAssertEqual(foo, .bar(84))
11711171
}
11721172

1173+
func testRegression_gh72() throws {
1174+
enum E1 {
1175+
case c1(E2)
1176+
}
1177+
1178+
enum E2 {
1179+
case c1(Bool)
1180+
case c2(Bool)
1181+
case c3(Any)
1182+
}
1183+
1184+
XCTAssertNotNil(
1185+
(/E1.c1).extract(from: .c1(.c1(true)))
1186+
)
1187+
XCTAssertNotNil(
1188+
(/E1.c1).extract(from: .c1(.c2(true)))
1189+
)
1190+
}
1191+
11731192
#if canImport(_Concurrency) && compiler(>=5.5.2)
11741193
func testConcurrency_SharedCasePath() async throws {
11751194
enum Enum { case payload(Int) }

0 commit comments

Comments
 (0)