Skip to content

Ensure that Sendable is inherited properly, take 3. #40488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3095,15 +3095,15 @@ class SynthesizeMainFunctionRequest
/// the Sendable protocol.
class GetImplicitSendableRequest :
public SimpleRequest<GetImplicitSendableRequest,
NormalProtocolConformance *(NominalTypeDecl *),
ProtocolConformance *(NominalTypeDecl *),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

NormalProtocolConformance *evaluate(
ProtocolConformance *evaluate(
Evaluator &evaluator, NominalTypeDecl *nominal) const;

public:
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ SWIFT_REQUEST(TypeChecker, SimpleDidSetRequest,
SWIFT_REQUEST(TypeChecker, SynthesizeMainFunctionRequest,
FuncDecl *(Decl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, GetImplicitSendableRequest,
NormalProtocolConformance *(NominalTypeDecl *),
ProtocolConformance *(NominalTypeDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, RenamedDeclRequest,
ValueDecl *(const ValueDecl *),
Expand Down
31 changes: 18 additions & 13 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3855,7 +3855,7 @@ bool swift::checkSendableConformance(
return checkSendableInstanceStorage(nominal, conformanceDC, check);
}

NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
ProtocolConformance *GetImplicitSendableRequest::evaluate(
Evaluator &evaluator, NominalTypeDecl *nominal) const {
// Protocols never get implicit Sendable conformances.
if (isa<ProtocolDecl>(nominal))
Expand Down Expand Up @@ -3900,14 +3900,14 @@ NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
return nullptr;
}

ASTContext &ctx = nominal->getASTContext();
auto proto = ctx.getProtocol(KnownProtocolKind::Sendable);
if (!proto)
return nullptr;

// Local function to form the implicit conformance.
auto formConformance = [&](const DeclAttribute *attrMakingUnavailable)
-> NormalProtocolConformance * {
ASTContext &ctx = nominal->getASTContext();
auto proto = ctx.getProtocol(KnownProtocolKind::Sendable);
if (!proto)
return nullptr;

DeclContext *conformanceDC = nominal;
if (attrMakingUnavailable) {
llvm::VersionTuple NoVersion;
Expand Down Expand Up @@ -3959,17 +3959,22 @@ NormalProtocolConformance *GetImplicitSendableRequest::evaluate(

// A non-protocol type with a global actor is implicitly Sendable.
if (nominal->getGlobalActorAttr()) {
// If this is a class, check the superclass. We won't infer Sendable
// if the superclass is already Sendable, to avoid introducing redundant
// conformances.
// If this is a class, check the superclass. If it's already Sendable,
// form an inherited conformance.
if (classDecl) {
if (Type superclass = classDecl->getSuperclass()) {
auto classModule = classDecl->getParentModule();
if (TypeChecker::conformsToKnownProtocol(
if (auto inheritedConformance = TypeChecker::conformsToProtocol(
classDecl->mapTypeIntoContext(superclass),
KnownProtocolKind::Sendable,
classModule, /*allowMissing=*/false))
return nullptr;
proto, classModule, /*allowMissing=*/false)) {
inheritedConformance = inheritedConformance
.mapConformanceOutOfContext();
if (inheritedConformance.isConcrete()) {
return ctx.getInheritedConformance(
nominal->getDeclaredInterfaceType(),
inheritedConformance.getConcrete());
}
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions test/ClangImporter/objc_async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,14 @@ func testMirrored(instance: ClassWithAsync) async {
}
}

@MainActor class MyView: NXView {
func f() {
Task {
await self.g()
}
}

func g() async { }
}

} // SwiftStdlib 5.5