Skip to content

Commit 74b54fe

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 d438c88 commit 74b54fe

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
@@ -3119,36 +3119,22 @@ namespace {
31193119
mayExecuteConcurrentlyWith(
31203120
localFunc.getAsDeclContext(), getDeclContext(),
31213121
/*includeSending*/true)) {
3122-
auto innermostGenericDC = localFunc.getAsDeclContext();
3123-
while (innermostGenericDC && !innermostGenericDC->isGenericContext())
3124-
innermostGenericDC = innermostGenericDC->getParent();
3125-
3126-
GenericSignature genericSig = innermostGenericDC
3127-
? innermostGenericDC->getGenericSignatureOfContext()
3128-
: GenericSignature();
3129-
31303122
for (const auto &capturedType :
31313123
localFunc.getCaptureInfo().getCapturedTypes()) {
3132-
unsigned genericDepth;
31333124
Type type = capturedType.getType();
31343125
if (auto archetype = type->getAs<ArchetypeType>()) {
3135-
genericDepth = archetype->getInterfaceType()->getRootGenericParam()
3136-
->getDepth();
3137-
} else if (type->isTypeParameter()) {
3138-
genericDepth = type->getRootGenericParam()->getDepth();
3126+
// If the generic signature of the environment prohibits this
3127+
// type to have an isolated conformance, there is nothing to
3128+
// diagnose.
3129+
Type interfaceType = archetype->getInterfaceType();
3130+
auto genericEnv = archetype->getGenericEnvironment();
3131+
auto genericSig = genericEnv->getGenericSignature();
3132+
if (genericSig->prohibitsIsolatedConformance(interfaceType))
3133+
continue;
31393134
} else {
31403135
continue;
31413136
}
31423137

3143-
// If the local function is generic and this is one of its generic
3144-
// parameters, ignore it.
3145-
if (genericSig.getNextDepth() > 0 &&
3146-
genericDepth >= genericSig.getNextDepth())
3147-
continue;
3148-
3149-
if (type->isTypeParameter() && innermostGenericDC)
3150-
type = innermostGenericDC->mapTypeIntoContext(type);
3151-
31523138
// Check that the metatype is sendable.
31533139
SendableCheckContext sendableContext(getDeclContext(), preconcurrency);
31543140
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)