Skip to content

Commit 053847a

Browse files
authored
Merge pull request #42034 from DougGregor/implicit-sendable-require
Ensure that lookup of Sendable always considers superclass Sendable.
2 parents 68bb691 + 0dab1b7 commit 053847a

File tree

3 files changed

+40
-17
lines changed

3 files changed

+40
-17
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4550,27 +4550,27 @@ ProtocolConformance *GetImplicitSendableRequest::evaluate(
45504550
return conformance;
45514551
};
45524552

4553-
// A non-protocol type with a global actor is implicitly Sendable.
4554-
if (nominal->getGlobalActorAttr()) {
4555-
// If this is a class, check the superclass. If it's already Sendable,
4556-
// form an inherited conformance.
4557-
if (classDecl) {
4558-
if (Type superclass = classDecl->getSuperclass()) {
4559-
auto classModule = classDecl->getParentModule();
4560-
if (auto inheritedConformance = TypeChecker::conformsToProtocol(
4561-
classDecl->mapTypeIntoContext(superclass),
4562-
proto, classModule, /*allowMissing=*/false)) {
4563-
inheritedConformance = inheritedConformance
4564-
.mapConformanceOutOfContext();
4565-
if (inheritedConformance.isConcrete()) {
4566-
return ctx.getInheritedConformance(
4567-
nominal->getDeclaredInterfaceType(),
4568-
inheritedConformance.getConcrete());
4569-
}
4553+
// If this is a class, check the superclass. If it's already Sendable,
4554+
// form an inherited conformance.
4555+
if (classDecl) {
4556+
if (Type superclass = classDecl->getSuperclass()) {
4557+
auto classModule = classDecl->getParentModule();
4558+
if (auto inheritedConformance = TypeChecker::conformsToProtocol(
4559+
classDecl->mapTypeIntoContext(superclass),
4560+
proto, classModule, /*allowMissing=*/false)) {
4561+
inheritedConformance = inheritedConformance
4562+
.mapConformanceOutOfContext();
4563+
if (inheritedConformance.isConcrete()) {
4564+
return ctx.getInheritedConformance(
4565+
nominal->getDeclaredInterfaceType(),
4566+
inheritedConformance.getConcrete());
45704567
}
45714568
}
45724569
}
4570+
}
45734571

4572+
// A non-protocol type with a global actor is implicitly Sendable.
4573+
if (nominal->getGlobalActorAttr()) {
45744574
// Form the implicit conformance to Sendable.
45754575
return formConformance(nullptr);
45764576
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules %s -verify -parse-as-library -require-explicit-sendable
2+
3+
// REQUIRES: objc_interop
4+
// REQUIRES: concurrency
5+
import Foundation
6+
import ObjCConcurrency
7+
8+
open class X: NXView { }
9+
open class Y: X { }
10+
11+
12+
open class Z: NSObject { } // expected-warning{{public class 'Z' does not specify whether it is 'Sendable' or not}}
13+
// expected-note@-1{{add '@unchecked Sendable' conformance to class 'Z' if this type manually implements concurrency safety}}
14+
// expected-note@-2{{make class 'Z' explicitly non-Sendable to suppress this warning}}

test/Concurrency/require-explicit-sendable.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,12 @@ struct S11: Sendable {
9999
}
100100

101101
@_nonSendable public struct S12 { }
102+
103+
// Don't complain about global-actor-qualified classes or their subclasses.
104+
@MainActor
105+
open class TestThing {}
106+
open class TestSubThing : TestThing {}
107+
108+
@MainActor(unsafe)
109+
open class TestThing2 {}
110+
open class TestSubThing2 : TestThing2 {}

0 commit comments

Comments
 (0)