Skip to content

Commit 31074f3

Browse files
committed
Sema: Key the implied Sendable conformance behavior off of -swift-version instead of -strict-concurrency
Also add some comments to explain what in the world is going on with the new checks.
1 parent 374b71f commit 31074f3

File tree

5 files changed

+23
-3
lines changed

5 files changed

+23
-3
lines changed

lib/AST/ConformanceLookup.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,10 @@ LookupConformanceInModuleRequest::evaluate(
718718
auto *normalConf = cast<NormalProtocolConformance>(conformance);
719719
auto *conformanceDC = normalConf->getDeclContext();
720720

721+
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
722+
// a Sendable conformance. The implied conformance is unconditional so it uses
723+
// the generic signature of the nominal type and not the generic signature of
724+
// the extension that declared the (implying) conditional conformance.
721725
if (normalConf->getSourceKind() == ConformanceEntryKind::Implied &&
722726
normalConf->getProtocol()->isSpecificProtocol(KnownProtocolKind::Sendable)) {
723727
conformanceDC = conformanceDC->getSelfNominalTypeDecl();

lib/AST/ProtocolConformance.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,16 @@ GenericSignature ProtocolConformance::getGenericSignature() const {
230230
case ProtocolConformanceKind::Self:
231231
// If we have a normal or inherited protocol conformance, look for its
232232
// generic signature.
233+
234+
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
235+
// a Sendable conformance. The implied conformance is unconditional so it uses
236+
// the generic signature of the nominal type and not the generic signature of
237+
// the extension that declared the (implying) conditional conformance.
233238
if (getSourceKind() == ConformanceEntryKind::Implied &&
234239
getProtocol()->isSpecificProtocol(KnownProtocolKind::Sendable)) {
235240
return getDeclContext()->getSelfNominalTypeDecl()->getGenericSignature();
236241
}
242+
237243
return getDeclContext()->getGenericSignatureOfContext();
238244

239245
case ProtocolConformanceKind::Builtin:
@@ -409,6 +415,10 @@ ConditionalRequirementsRequest::evaluate(Evaluator &evaluator,
409415
return {};
410416
}
411417

418+
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
419+
// a Sendable conformance. We ask the conformance for its generic signature,
420+
// which will always be the generic signature of `ext` except in this case,
421+
// where it's the generic signature of the extended nominal.
412422
const auto extensionSig = NPC->getGenericSignature();
413423

414424
// The extension signature should be a superset of the type signature, meaning

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6040,6 +6040,10 @@ bool swift::checkSendableConformance(
60406040
}
60416041
}
60426042

6043+
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
6044+
// a Sendable conformance. The implied conformance is unconditional, so check
6045+
// the storage for sendability as if the conformance was declared on the nominal,
6046+
// and not some (possibly constrained) extension.
60436047
if (conformance->getSourceKind() == ConformanceEntryKind::Implied)
60446048
conformanceDC = nominal;
60456049
return checkSendableInstanceStorage(nominal, conformanceDC, check);

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2416,7 +2416,9 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
24162416

24172417
bool allowImpliedConditionalConformance = false;
24182418
if (Proto->isSpecificProtocol(KnownProtocolKind::Sendable)) {
2419-
if (Context.LangOpts.StrictConcurrencyLevel != StrictConcurrency::Complete)
2419+
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
2420+
// a Sendable conformance.
2421+
if (!Context.LangOpts.isSwiftVersionAtLeast(6))
24202422
allowImpliedConditionalConformance = true;
24212423
} else if (Proto->isMarkerProtocol()) {
24222424
allowImpliedConditionalConformance = true;

test/Concurrency/implied_sendable_conformance_swift5.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -swift-version 5
2-
// RUN: %target-swift-emit-silgen %s -swift-version 5
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -strict-concurrency=complete
2+
// RUN: %target-swift-emit-silgen %s -swift-version 5 -strict-concurrency=complete
33

44
protocol P: Sendable {}
55
protocol Q: Sendable {}

0 commit comments

Comments
 (0)