AST: Tweak ConformanceLookupTable::compareConformances() some more

If two conformances imply a conformance to the same marker
protocol, don't diagnose redundancy if they differ by
unavailability. Instead, allow the more available conformance
to win.

This allows declaring a type that conforms to a protocol
that inherits from SendableMetatype, followed by an
unavailable Sendable conformance on the same type.

Fixes rdar://152509409.
This commit is contained in:
Slava Pestov
2025-06-23 22:53:50 -04:00
parent 64a8c58466
commit 8d30df5327
2 changed files with 13 additions and 3 deletions

View File

@@ -615,9 +615,10 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances(
rhs->getDeclContext()->isAlwaysAvailableConformanceContext()) {
// Diagnose conflicting marker protocol conformances that differ in
// un-availability.
diagnoseSuperseded = (lhs->getProtocol()->isMarkerProtocol() &&
isUnavailable(lhs->getDeclContext()) !=
isUnavailable(rhs->getDeclContext()));
diagnoseSuperseded =
(lhs->getProtocol()->isMarkerProtocol() &&
isUnavailable(lhs->getDeclContext()) != isUnavailable(rhs->getDeclContext()) &&
(lhsKind != ConformanceEntryKind::Implied || rhsKind != ConformanceEntryKind::Implied));
return (lhs->getDeclContext()->isAlwaysAvailableConformanceContext()
? Ordering::Before

View File

@@ -57,3 +57,12 @@ extension Conformer2: Derived1 {
extension Conformer2: Derived2 {
func f() {} // expected-note {{'f()' declared here}}
}
protocol P: MarkerBase {}
struct Conformer3: P {}
@available(*, unavailable)
extension Conformer3: MarkerDerived1 {}
takesMarkerBase(Conformer3.self)