Skip to content

Commit 61e9074

Browse files
committed
Ensure that Sendable is inherited properly, take 3.
Extend the implicit Sendable request to produce an inherited conformance when queried, rather than depending on the conformance lookup table to always have the right entries. This acknowledges that implicit Sendable needs to happen more at the type checking level than the name-binding level, which is needed to eliminate cyclic dependencies.
1 parent 529bbec commit 61e9074

File tree

4 files changed

+31
-16
lines changed

4 files changed

+31
-16
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,15 +3095,15 @@ class SynthesizeMainFunctionRequest
30953095
/// the Sendable protocol.
30963096
class GetImplicitSendableRequest :
30973097
public SimpleRequest<GetImplicitSendableRequest,
3098-
NormalProtocolConformance *(NominalTypeDecl *),
3098+
ProtocolConformance *(NominalTypeDecl *),
30993099
RequestFlags::Cached> {
31003100
public:
31013101
using SimpleRequest::SimpleRequest;
31023102

31033103
private:
31043104
friend SimpleRequest;
31053105

3106-
NormalProtocolConformance *evaluate(
3106+
ProtocolConformance *evaluate(
31073107
Evaluator &evaluator, NominalTypeDecl *nominal) const;
31083108

31093109
public:

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ SWIFT_REQUEST(TypeChecker, SimpleDidSetRequest,
354354
SWIFT_REQUEST(TypeChecker, SynthesizeMainFunctionRequest,
355355
FuncDecl *(Decl *), Cached, NoLocationInfo)
356356
SWIFT_REQUEST(TypeChecker, GetImplicitSendableRequest,
357-
NormalProtocolConformance *(NominalTypeDecl *),
357+
ProtocolConformance *(NominalTypeDecl *),
358358
Cached, NoLocationInfo)
359359
SWIFT_REQUEST(TypeChecker, RenamedDeclRequest,
360360
ValueDecl *(const ValueDecl *),

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3855,7 +3855,7 @@ bool swift::checkSendableConformance(
38553855
return checkSendableInstanceStorage(nominal, conformanceDC, check);
38563856
}
38573857

3858-
NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
3858+
ProtocolConformance *GetImplicitSendableRequest::evaluate(
38593859
Evaluator &evaluator, NominalTypeDecl *nominal) const {
38603860
// Protocols never get implicit Sendable conformances.
38613861
if (isa<ProtocolDecl>(nominal))
@@ -3900,14 +3900,14 @@ NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
39003900
return nullptr;
39013901
}
39023902

3903+
ASTContext &ctx = nominal->getASTContext();
3904+
auto proto = ctx.getProtocol(KnownProtocolKind::Sendable);
3905+
if (!proto)
3906+
return nullptr;
3907+
39033908
// Local function to form the implicit conformance.
39043909
auto formConformance = [&](const DeclAttribute *attrMakingUnavailable)
39053910
-> NormalProtocolConformance * {
3906-
ASTContext &ctx = nominal->getASTContext();
3907-
auto proto = ctx.getProtocol(KnownProtocolKind::Sendable);
3908-
if (!proto)
3909-
return nullptr;
3910-
39113911
DeclContext *conformanceDC = nominal;
39123912
if (attrMakingUnavailable) {
39133913
llvm::VersionTuple NoVersion;
@@ -3959,17 +3959,22 @@ NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
39593959

39603960
// A non-protocol type with a global actor is implicitly Sendable.
39613961
if (nominal->getGlobalActorAttr()) {
3962-
// If this is a class, check the superclass. We won't infer Sendable
3963-
// if the superclass is already Sendable, to avoid introducing redundant
3964-
// conformances.
3962+
// If this is a class, check the superclass. If it's already Sendable,
3963+
// form an inherited conformance.
39653964
if (classDecl) {
39663965
if (Type superclass = classDecl->getSuperclass()) {
39673966
auto classModule = classDecl->getParentModule();
3968-
if (TypeChecker::conformsToKnownProtocol(
3967+
if (auto inheritedConformance = TypeChecker::conformsToProtocol(
39693968
classDecl->mapTypeIntoContext(superclass),
3970-
KnownProtocolKind::Sendable,
3971-
classModule, /*allowMissing=*/false))
3972-
return nullptr;
3969+
proto, classModule, /*allowMissing=*/false)) {
3970+
inheritedConformance = inheritedConformance
3971+
.mapConformanceOutOfContext();
3972+
if (inheritedConformance.isConcrete()) {
3973+
return ctx.getInheritedConformance(
3974+
nominal->getDeclaredInterfaceType(),
3975+
inheritedConformance.getConcrete());
3976+
}
3977+
}
39733978
}
39743979
}
39753980

test/ClangImporter/objc_async.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,14 @@ func testMirrored(instance: ClassWithAsync) async {
218218
}
219219
}
220220

221+
@MainActor class MyView: NXView {
222+
func f() {
223+
Task {
224+
await self.g()
225+
}
226+
}
227+
228+
func g() async { }
229+
}
230+
221231
} // SwiftStdlib 5.5

0 commit comments

Comments
 (0)