@@ -66,6 +66,15 @@ swift::collectExistentialConformances(CanType fromType,
6666 return fromType->getASTContext ().AllocateCopy (conformances);
6767}
6868
69+ static bool containsNonMarkerProtocols (ArrayRef<ProtocolDecl *> protocols) {
70+ for (auto proto : protocols) {
71+ if (!proto->isMarkerProtocol ())
72+ return true ;
73+ }
74+
75+ return false ;
76+ }
77+
6978ProtocolConformanceRef
7079swift::lookupExistentialConformance (Type type, ProtocolDecl *protocol) {
7180 ASTContext &ctx = protocol->getASTContext ();
@@ -146,6 +155,12 @@ swift::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
146155 if (auto conformance = lookupSuperclassConformance (layout.getSuperclass ()))
147156 return conformance;
148157
158+ // If the protocol is SendableMetatype, and there are no non-marker protocol
159+ // requirements, allow it via self-conformance.
160+ if (protocol->isSpecificProtocol (KnownProtocolKind::SendableMetatype) &&
161+ !containsNonMarkerProtocols (layout.getProtocols ()))
162+ return ProtocolConformanceRef (ctx.getSelfConformance (protocol));
163+
149164 // We didn't find our protocol in the existential's list; it doesn't
150165 // conform.
151166 return ProtocolConformanceRef::forInvalid ();
@@ -377,6 +392,48 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
377392 return ProtocolConformanceRef::forMissingOrInvalid (type, protocol);
378393}
379394
395+ // / Given the instance type of a metatype, determine whether the metatype is
396+ // / Sendable.
397+ // /
398+ // Metatypes are generally Sendable, but with isolated conformances we
399+ // cannot assume that metatypes based on type parameters are Sendable.
400+ // Therefore, check for conformance to SendableMetatype.
401+ static bool metatypeWithInstanceTypeIsSendable (Type instanceType) {
402+ ASTContext &ctx = instanceType->getASTContext ();
403+
404+ // If we don't have the SendableMetatype protocol at all, just assume all
405+ // metatypes are Sendable.
406+ auto sendableMetatypeProto =
407+ ctx.getProtocol (KnownProtocolKind::SendableMetatype);
408+ if (!sendableMetatypeProto)
409+ return true ;
410+
411+ // If the instance type is a type parameter, it is not necessarily
412+ // SendableMetatype. There will need to be a SendableMetatype requirement,
413+ // but we do not have the generic environment to check that.
414+ if (instanceType->isTypeParameter ())
415+ return false ;
416+
417+ // If the instance type conforms to SendableMetatype, then its
418+ // metatype is Sendable.
419+ auto instanceConformance = lookupConformance (
420+ instanceType, sendableMetatypeProto);
421+ if (!instanceConformance.isInvalid () &&
422+ !instanceConformance.hasMissingConformance ())
423+ return true ;
424+
425+ // If this is an archetype that is non-SendableMetatype, but there are no
426+ // non-marker protocol requirements that could carry conformances, treat
427+ // the metatype as Sendable.
428+ if (auto archetype = instanceType->getAs <ArchetypeType>()) {
429+ if (!containsNonMarkerProtocols (archetype->getConformsTo ()))
430+ return true ;
431+ }
432+
433+ // The instance type is non-Sendable.
434+ return false ;
435+ }
436+
380437// / Synthesize a builtin metatype type conformance to the given protocol, if
381438// / appropriate.
382439static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance (
@@ -386,30 +443,11 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
386443 // All metatypes are Copyable, Escapable, and BitwiseCopyable.
387444 if (auto kp = protocol->getKnownProtocolKind ()) {
388445 switch (*kp) {
389- case KnownProtocolKind::Sendable: {
390- // Metatypes are generally Sendable, but with isolated conformances we
391- // cannot assume that metatypes based on type parameters are Sendable.
392- // Therefore, check for conformance to SendableMetatype.
393- auto sendableMetatypeProto =
394- ctx.getProtocol (KnownProtocolKind::SendableMetatype);
395- if (sendableMetatypeProto) {
396- Type instanceType = metatypeType->getInstanceType ();
397-
398- // If the instance type is a type parameter, it is not necessarily
399- // Sendable. There will need to be a Sendable requirement.
400- if (instanceType->isTypeParameter ())
401- break ;
402-
403- // If the instance type conforms to SendableMetatype, then its
404- // metatype is Sendable.
405- auto instanceConformance = lookupConformance (
406- instanceType, sendableMetatypeProto);
407- if (instanceConformance.isInvalid () ||
408- instanceConformance.hasMissingConformance ())
409- break ;
410- }
446+ case KnownProtocolKind::Sendable:
447+ if (!metatypeWithInstanceTypeIsSendable (metatypeType->getInstanceType ()))
448+ break ;
449+
411450 LLVM_FALLTHROUGH;
412- }
413451
414452 case KnownProtocolKind::Copyable:
415453 case KnownProtocolKind::Escapable:
0 commit comments