Skip to content

Commit fe8a277

Browse files
authored
Merge pull request #63898 from tshortli/allow-unavailable-witness-on-unavailable-type
2 parents 6c19201 + 9521764 commit fe8a277

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,23 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
16941694

16951695
if (match.Witness->getAttrs().isUnavailable(getASTContext()) &&
16961696
!requirement->getAttrs().isUnavailable(getASTContext())) {
1697-
return CheckKind::WitnessUnavailable;
1697+
auto nominalOrExtensionIsUnavailable = [&]() {
1698+
if (auto extension = dyn_cast<ExtensionDecl>(DC)) {
1699+
if (extension->getAttrs().isUnavailable(getASTContext()))
1700+
return true;
1701+
}
1702+
1703+
if (auto adoptingNominal = DC->getSelfNominalTypeDecl()) {
1704+
if (adoptingNominal->getAttrs().isUnavailable(getASTContext()))
1705+
return true;
1706+
}
1707+
1708+
return false;
1709+
};
1710+
1711+
// Allow unavailable nominals or extension to have unavailable witnesses.
1712+
if (!nominalOrExtensionIsUnavailable())
1713+
return CheckKind::WitnessUnavailable;
16981714
}
16991715

17001716
return CheckKind::Success;

test/decl/protocol/req/unavailable.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,28 @@ struct ConformsToP2 {
4141
extension ConformsToP2: P {} // expected-error{{type 'ConformsToP2' does not conform to protocol 'P'}}
4242
// expected-error@-1 {{unavailable instance method 'foo(bar:)' was used to satisfy a requirement of protocol 'P'}}
4343

44+
@available(*, unavailable)
45+
struct ConformsToP3: P {
46+
func foo(bar: Foo) { }
47+
}
48+
49+
// Ok, an unavailable decl should be allowed to witness a requirement when the
50+
// conforming type is itself unavailable.
51+
@available(*, unavailable)
52+
struct ConformsToP4: P {
53+
@available(*, unavailable)
54+
func foo(bar: Foo) { }
55+
}
56+
57+
struct ConformsToP5 {}
58+
59+
// Ok, an unavailable decl should be allowed to witness a requirement when the
60+
// conformance extension is itself unavailable.
61+
@available(*, unavailable)
62+
extension ConformsToP5: P {
63+
@available(*, unavailable)
64+
func foo(bar: Foo) { }
65+
}
4466

4567
// Include message string from @available attribute if provided
4668
protocol Unavail {

0 commit comments

Comments
 (0)