Skip to content

Commit 7356fe8

Browse files
committed
[ConformanceLookup] Don't allow skipping inherited unavailable conformances
in favor of explicit available ones. The type checker does not support the notion of multiple protocol conformances; there can only be one conformance, and if that conformance is unavailable, you cannot specify your own available conformance. This is important for Sendable checking; if a framework specifies that a type is explicitly not Sendable with an unavailable Sendable conformance, clients cannot ignore Sendable violations involving that type. If a superclass wants to allow subclasses to add a Sendable conformance, it should not declare an unavailable Sendable conformance.
1 parent 86f3fe1 commit 7356fe8

File tree

2 files changed

+13
-12
lines changed

2 files changed

+13
-12
lines changed

lib/AST/ConformanceLookupTable.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,6 @@ void ConformanceLookupTable::inheritConformances(ClassDecl *classDecl,
259259
auto addInheritedConformance = [&](ConformanceEntry *entry) {
260260
auto protocol = entry->getProtocol();
261261

262-
// Don't add unavailable conformances.
263-
if (auto dc = entry->Source.getDeclContext()) {
264-
if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
265-
if (AvailableAttr::isUnavailable(ext))
266-
return;
267-
}
268-
}
269-
270262
// Don't add redundant conformances here. This is merely an
271263
// optimization; resolveConformances() would zap the duplicates
272264
// anyway.
@@ -628,6 +620,14 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances(
628620

629621
// Allow replacement of an explicit conformance to a marker protocol.
630622
// (This permits redundant explicit declarations of `Sendable`.)
623+
//
624+
// FIXME: We need to warn on attempts to make an unavailable Sendable
625+
// conformance available, which does not work.
626+
//
627+
// We probably also want to warn if there is an existing, explicit
628+
// conformance, so clients are prompted to remove retroactive unchecked
629+
// Sendable conformances when the proper Sendable conformance is added
630+
// in the original module.
631631
return (kind == ConformanceEntryKind::Explicit
632632
&& entry->getProtocol()->isMarkerProtocol());
633633
};
@@ -879,8 +879,6 @@ DeclContext *ConformanceLookupTable::getConformingContext(
879879
return nullptr;
880880
auto inheritedConformance = ModuleDecl::lookupConformance(
881881
superclassTy, protocol, /*allowMissing=*/false);
882-
if (inheritedConformance.hasUnavailableConformance())
883-
inheritedConformance = ProtocolConformanceRef::forInvalid();
884882
if (inheritedConformance)
885883
return superclassDecl;
886884
} while ((superclassDecl = superclassDecl->getSuperclassDecl()));

test/Concurrency/sendable_checking.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ public actor MyActor: MyProto {
102102
}
103103

104104
// Make sure the generic signature doesn't minimize away Sendable requirements.
105-
@_nonSendable class NSClass { }
105+
class NSClass { }
106+
107+
@available(*, unavailable)
108+
extension NSClass: @unchecked Sendable {} // expected-note {{conformance of 'NSClass' to 'Sendable' has been explicitly marked unavailable here}}
106109

107110
struct WrapClass<T: NSClass> {
108111
var t: T
@@ -116,7 +119,7 @@ class SendableSubclass: NSClass, @unchecked Sendable { }
116119

117120
@available(SwiftStdlib 5.1, *)
118121
func testSubclassing(obj: SendableSubclass) async {
119-
acceptCV(obj) // okay!
122+
acceptCV(obj) // expected-warning {{conformance of 'NSClass' to 'Sendable' is unavailable; this is an error in the Swift 6 language mode}}
120123
}
121124

122125

0 commit comments

Comments
 (0)