AST: Narrow the filtering of unavailable conformances to Sendable only

Remove the allowUnavailable parameter to lookupConformance(), and instead
explicitly check the result for hasUnavailableConformance() in the places
where we used to pass 'false'.

Also, narrow down this check in those places to the Sendable protocol
only, fixing a regression with Hashable conformance synthesis.

Fixes rdar://problem/94460143.
This commit is contained in:
Slava Pestov
2022-06-14 21:07:30 -04:00
parent b04ae714f3
commit bd46bdaaaa
10 changed files with 77 additions and 50 deletions

View File

@@ -1020,9 +1020,13 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
// concretely.
if (auto superclass = layout.explicitSuperclass) {
if (auto result = lookupConformance(
superclass, protocol, /*allowMissing=*/false,
/*allowUnavailable=*/false))
superclass, protocol, /*allowMissing=*/false)) {
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) &&
result.hasUnavailableConformance())
result = ProtocolConformanceRef::forInvalid();
return result;
}
}
// Otherwise, the existential might conform abstractly.
@@ -1077,8 +1081,7 @@ ProtocolConformanceRef ProtocolConformanceRef::forMissingOrInvalid(
ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
ProtocolDecl *protocol,
bool allowMissing,
bool allowUnavailable) {
bool allowMissing) {
// If we are recursively checking for implicit conformance of a nominal
// type to Sendable, fail without evaluating this request. This
// squashes cycles.
@@ -1102,11 +1105,6 @@ ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
result.hasMissingConformance(this))
return ProtocolConformanceRef::forInvalid();
// If we aren't supposed to allow unavailable conformances but we have one,
// replace the result with an "invalid" result.
if (!allowUnavailable && result.hasUnavailableConformance())
return ProtocolConformanceRef::forInvalid();
return result;
}
@@ -1260,9 +1258,12 @@ LookupConformanceInModuleRequest::evaluate(
// able to be resolved by a substitution that makes the archetype
// concrete.
if (auto super = archetype->getSuperclass()) {
if (auto inheritedConformance = mod->lookupConformance(
super, protocol, /*allowMissing=*/false,
/*allowUnavailable=*/false)) {
auto inheritedConformance = mod->lookupConformance(
super, protocol, /*allowMissing=*/false);
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) &&
inheritedConformance.hasUnavailableConformance())
inheritedConformance = ProtocolConformanceRef::forInvalid();
if (inheritedConformance) {
return ProtocolConformanceRef(ctx.getInheritedConformance(
type, inheritedConformance.getConcrete()));
}