@@ -66,6 +66,15 @@ swift::collectExistentialConformances(CanType fromType,
66
66
return fromType->getASTContext ().AllocateCopy (conformances);
67
67
}
68
68
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
+
69
78
ProtocolConformanceRef
70
79
swift::lookupExistentialConformance (Type type, ProtocolDecl *protocol) {
71
80
ASTContext &ctx = protocol->getASTContext ();
@@ -146,6 +155,12 @@ swift::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
146
155
if (auto conformance = lookupSuperclassConformance (layout.getSuperclass ()))
147
156
return conformance;
148
157
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
+
149
164
// We didn't find our protocol in the existential's list; it doesn't
150
165
// conform.
151
166
return ProtocolConformanceRef::forInvalid ();
@@ -377,6 +392,48 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
377
392
return ProtocolConformanceRef::forMissingOrInvalid (type, protocol);
378
393
}
379
394
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
+
380
437
// / Synthesize a builtin metatype type conformance to the given protocol, if
381
438
// / appropriate.
382
439
static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance (
@@ -386,30 +443,11 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
386
443
// All metatypes are Copyable, Escapable, and BitwiseCopyable.
387
444
if (auto kp = protocol->getKnownProtocolKind ()) {
388
445
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
+
411
450
LLVM_FALLTHROUGH;
412
- }
413
451
414
452
case KnownProtocolKind::Copyable:
415
453
case KnownProtocolKind::Escapable:
0 commit comments