Skip to content

Commit 5412de7

Browse files
committed
Use the "prohibits isolated conformances" check for capture metatypes
When checking whether a capture of a metatype is Sendable, we had an incomplete and incorrect check for SendableMetatype conformance. Replace that with the proper "prohibits isolated conformances" check on the generic signature, which matches what we do on the caller side. Fixes issue #82905 / rdar://155399531.
1 parent 2211d9f commit 5412de7

File tree

2 files changed

+27
-24
lines changed

2 files changed

+27
-24
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,36 +3103,22 @@ namespace {
31033103
mayExecuteConcurrentlyWith(
31043104
localFunc.getAsDeclContext(), getDeclContext(),
31053105
/*includeSending*/true)) {
3106-
auto innermostGenericDC = localFunc.getAsDeclContext();
3107-
while (innermostGenericDC && !innermostGenericDC->isGenericContext())
3108-
innermostGenericDC = innermostGenericDC->getParent();
3109-
3110-
GenericSignature genericSig = innermostGenericDC
3111-
? innermostGenericDC->getGenericSignatureOfContext()
3112-
: GenericSignature();
3113-
31143106
for (const auto &capturedType :
31153107
localFunc.getCaptureInfo().getCapturedTypes()) {
3116-
unsigned genericDepth;
31173108
Type type = capturedType.getType();
31183109
if (auto archetype = type->getAs<ArchetypeType>()) {
3119-
genericDepth = archetype->getInterfaceType()->getRootGenericParam()
3120-
->getDepth();
3121-
} else if (type->isTypeParameter()) {
3122-
genericDepth = type->getRootGenericParam()->getDepth();
3110+
// If the generic signature of the environment prohibits this
3111+
// type to have an isolated conformance, there is nothing to
3112+
// diagnose.
3113+
Type interfaceType = archetype->getInterfaceType();
3114+
auto genericEnv = archetype->getGenericEnvironment();
3115+
auto genericSig = genericEnv->getGenericSignature();
3116+
if (genericSig->prohibitsIsolatedConformance(interfaceType))
3117+
continue;
31233118
} else {
31243119
continue;
31253120
}
31263121

3127-
// If the local function is generic and this is one of its generic
3128-
// parameters, ignore it.
3129-
if (genericSig.getNextDepth() > 0 &&
3130-
genericDepth >= genericSig.getNextDepth())
3131-
continue;
3132-
3133-
if (type->isTypeParameter() && innermostGenericDC)
3134-
type = innermostGenericDC->mapTypeIntoContext(type);
3135-
31363122
// Check that the metatype is sendable.
31373123
SendableCheckContext sendableContext(getDeclContext(), preconcurrency);
31383124
diagnoseNonSendableTypes(MetatypeType::get(type),

test/Concurrency/sendable_metatype_typecheck.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func testSendableExistential() {
2121
nonisolated func acceptMeta<T>(_: T.Type) { }
2222

2323
nonisolated func staticCallThroughMetaVal<T: Q>(_: T.Type) {
24-
let x = T.self // expected-warning{{capture of non-Sendable type 'T.Type' in an isolated closure}}
24+
let x = T.self
2525
Task.detached {
2626
x.g() // expected-warning{{capture of non-Sendable type 'T.Type' in an isolated closure}}
2727
}
@@ -35,7 +35,7 @@ nonisolated func captureThroughMetaValMoReqs<T>(_: T.Type) {
3535
}
3636

3737
nonisolated func passMetaVal<T: Q>(_: T.Type) {
38-
let x = T.self // expected-warning{{capture of non-Sendable type 'T.Type' in an isolated closure}}
38+
let x = T.self
3939
Task.detached {
4040
acceptMeta(x) // expected-warning{{capture of non-Sendable type}}
4141
}
@@ -188,3 +188,20 @@ func f<T: P>(_: T.Type) {
188188
}
189189
}
190190
}
191+
192+
func sendableSequence<S: AsyncSequence & Sendable>(_ s: S) throws {
193+
Task.detached {
194+
for try await i in s {
195+
print(i)
196+
}
197+
}
198+
}
199+
200+
func nonSendableSequence<S: AsyncSequence>(_ s: S) throws {
201+
Task.detached {
202+
for try await i in s { // expected-warning{{capture of non-Sendable type 'S.AsyncIterator.Type' in an isolated closure}}
203+
// expected-warning@-1{{capture of non-Sendable type 'S.Type' in an isolated closure}}
204+
print(i)
205+
}
206+
}
207+
}

0 commit comments

Comments
 (0)