[Sema] initial overhaul of isNoncopyable

This implementation has the function execute a request to scan the
inheritance clause of non-protocol nominals for a `~Copyable`. For
protocols, we look in the requirement signature.

This isn't our final state, as the GenericEnvironment needs to be
queried in general to determine of a Type is noncopyable. So for now
checking for a `~Copyable` only makes sense for Decls.
This commit is contained in:
Kavon Farvardin
2023-09-25 14:15:59 -07:00
parent 578db55c4c
commit d5f2d54ca7
21 changed files with 349 additions and 48 deletions

View File

@@ -1681,12 +1681,12 @@ ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
ProtocolDecl *protocol,
bool allowMissing) {
// If we are recursively checking for implicit conformance of a nominal
// type to Sendable, fail without evaluating this request. This
// type to a KnownProtocol, fail without evaluating this request. This
// squashes cycles.
LookupConformanceInModuleRequest request{{this, type, protocol}};
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
if (auto kp = protocol->getKnownProtocolKind()) {
if (auto nominal = type->getAnyNominal()) {
GetImplicitSendableRequest icvRequest{nominal};
ImplicitKnownProtocolConformanceRequest icvRequest{nominal, *kp};
if (getASTContext().evaluator.hasActiveRequest(icvRequest) ||
getASTContext().evaluator.hasActiveRequest(request))
return ProtocolConformanceRef::forInvalid();
@@ -1972,7 +1972,8 @@ LookupConformanceInModuleRequest::evaluate(
if (!nominal->lookupConformance(protocol, conformances)) {
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
// Try to infer Sendable conformance.
GetImplicitSendableRequest cvRequest{nominal};
ImplicitKnownProtocolConformanceRequest
cvRequest{nominal, KnownProtocolKind::Sendable};
if (auto conformance = evaluateOrDefault(
ctx.evaluator, cvRequest, nullptr)) {
conformances.clear();
@@ -2001,16 +2002,15 @@ LookupConformanceInModuleRequest::evaluate(
return ProtocolConformanceRef::forMissingOrInvalid(type, protocol);
}
} else if (protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
// Only move-only nominals are not Copyable
if (nominal->isNoncopyable()) {
return ProtocolConformanceRef::forInvalid();
// Try to infer Copyable conformance.
ImplicitKnownProtocolConformanceRequest
cvRequest{nominal, KnownProtocolKind::Copyable};
if (auto conformance = evaluateOrDefault(
ctx.evaluator, cvRequest, nullptr)) {
conformances.clear();
conformances.push_back(conformance);
} else {
// Specifically do not create a concrete conformance to Copyable. At
// this stage, we don't even want Copyable to appear in swiftinterface
// files, which will happen for a marker protocol that's registered
// in a nominal type's conformance table. We can reconsider this
// decision later once there's a clearer picture of noncopyable generics
return ProtocolConformanceRef(protocol);
return ProtocolConformanceRef::forMissingOrInvalid(type, protocol);
}
} else {
// Was unable to infer the missing conformance.