Skip to content

Commit f4135f9

Browse files
committed
[Conformance lookup table] Prefer synthesized conformances to deserialized ones.
When a conformance can either be synthesized or implied, we tend to prefer implied. However, if the implied conformance comes from a deserialized conformance, it will lead to an incomplete conformance and cause a crash. This is a narrow fix for SR-6105 / rdar://problem/34911378.
1 parent 6db9cc8 commit f4135f9

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

lib/AST/ConformanceLookupTable.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,14 +448,23 @@ bool ConformanceLookupTable::addProtocol(NominalTypeDecl *nominal,
448448
return false;
449449

450450
case ConformanceEntryKind::Implied:
451-
// An implied conformance is better than a synthesized one.
452451
// Ignore implied circular protocol inheritance
453-
if (kind == ConformanceEntryKind::Synthesized ||
454-
existingEntry->getProtocol() == protocol)
452+
if (existingEntry->getProtocol() == protocol)
455453
return false;
454+
455+
// An implied conformance is better than a synthesized one, unless
456+
// the implied conformance was deserialized.
457+
if (kind == ConformanceEntryKind::Synthesized &&
458+
existingEntry->getDeclContext()->getParentSourceFile() == nullptr)
459+
return false;
460+
456461
break;
457462

458463
case ConformanceEntryKind::Synthesized:
464+
// An implied conformance is better unless it was deserialized.
465+
if (dc->getParentSourceFile() == nullptr)
466+
return false;
467+
459468
break;
460469
}
461470
}

test/Serialization/Inputs/use_imported_enums.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,25 @@ import Foundation
77
@inline(__always) @_transparent public func compareImportedEnumToSelf(_ e: NSRuncingMode) -> Bool {
88
return compareToSelf(e)
99
}
10+
11+
// SR-6105
12+
open class EVC<EnumType : EVT> where EnumType.RawValue : Hashable {
13+
}
14+
15+
public protocol EVT : RawRepresentable {
16+
associatedtype Wrapper
17+
associatedtype Constructor
18+
}
19+
20+
open class EVO<EnumType> {
21+
}
22+
23+
final public class CSWrapperConstructorClass : EVC<ByteCountFormatter.CountStyle> {
24+
}
25+
26+
final public class CSWrapperClass : EVO<ByteCountFormatter.CountStyle> {
27+
}
28+
extension ByteCountFormatter.CountStyle : EVT {
29+
public typealias Wrapper = CSWrapperClass
30+
public typealias Constructor = CSWrapperConstructorClass
31+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
4+
// FIXME: BEGIN -enable-source-import hackaround
5+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %clang-importer-sdk-path/swift-modules/CoreGraphics.swift
6+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %clang-importer-sdk-path/swift-modules/Foundation.swift
7+
// FIXME: END -enable-source-import hackaround
8+
9+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t/UsesImportedEnums-a.swiftmodule -parse-as-library %S/Inputs/use_imported_enums.swift -module-name UsesImportedEnums
10+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -merge-modules -module-name UsesImportedEnums -emit-module -o %t/UsesImportedEnums.swiftmodule %t/UsesImportedEnums-a.swiftmodule
11+
12+
// REQUIRES: objc_interop

0 commit comments

Comments
 (0)