@@ -1206,6 +1206,13 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
12061206 if (!protocol->existentialConformsToSelf ())
12071207 return ProtocolConformanceRef::forInvalid ();
12081208
1209+ // All existentials are Copyable.
1210+ if (protocol->isSpecificProtocol (KnownProtocolKind::Copyable)) {
1211+ return ProtocolConformanceRef (
1212+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), {},
1213+ BuiltinConformanceKind::Synthesized));
1214+ }
1215+
12091216 auto layout = type->getExistentialLayout ();
12101217
12111218 // Due to an IRGen limitation, witness tables cannot be passed from an
@@ -1362,8 +1369,10 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
13621369 return ProtocolConformanceRef (specialized);
13631370 }
13641371
1365- // Tuple type are Sendable when all of their element types are Sendable.
1366- if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1372+ // / For some known protocols (KPs) like Sendable and Copyable, a tuple type
1373+ // / conforms to the protocol KP when all of their element types conform to KP.
1374+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) ||
1375+ protocol->isSpecificProtocol (KnownProtocolKind::Copyable)) {
13671376
13681377 // Create the pieces for a generic tuple type (T1, T2, ... TN) and a
13691378 // generic signature <T1, T2, ..., TN>.
@@ -1389,9 +1398,9 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
13891398 BuiltinConformanceKind::Synthesized));
13901399 }
13911400
1392- // Form a generic conformance of (T1, T2, ..., TN): Sendable with signature
1393- // <T1, T2, ..., TN> and conditional requirements T1: Sendable ,
1394- // T2: Sendable , ..., TN: Sendable .
1401+ // Form a generic conformance of (T1, T2, ..., TN): KP with signature
1402+ // <T1, T2, ..., TN> and conditional requirements T1: KP ,
1403+ // T2: P , ..., TN: KP .
13951404 auto genericTupleType = TupleType::get (genericElements, ctx);
13961405 auto genericSig = GenericSignature::get (
13971406 genericParams, conditionalRequirements);
@@ -1440,24 +1449,33 @@ static bool isSendableFunctionType(const FunctionType *functionType) {
14401449// / appropriate.
14411450static ProtocolConformanceRef getBuiltinFunctionTypeConformance (
14421451 Type type, const FunctionType *functionType, ProtocolDecl *protocol) {
1452+ ASTContext &ctx = protocol->getASTContext ();
14431453 // @Sendable function types are Sendable.
14441454 if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) &&
14451455 isSendableFunctionType (functionType)) {
1446- ASTContext &ctx = protocol->getASTContext ();
14471456 return ProtocolConformanceRef (
14481457 ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
14491458 BuiltinConformanceKind::Synthesized));
14501459 }
14511460
1461+ // Functions cannot permanently destroy a move-only var/let
1462+ // that they capture, so it's safe to copy functions, like classes.
1463+ if (protocol->isSpecificProtocol (KnownProtocolKind::Copyable)) {
1464+ return ProtocolConformanceRef (
1465+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), {},
1466+ BuiltinConformanceKind::Synthesized));
1467+ }
1468+
14521469 return ProtocolConformanceRef::forMissingOrInvalid (type, protocol);
14531470}
14541471
14551472// / Synthesize a builtin metatype type conformance to the given protocol, if
14561473// / appropriate.
14571474static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance (
14581475 Type type, const AnyMetatypeType *metatypeType, ProtocolDecl *protocol) {
1459- // All metatypes are Sendable.
1460- if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1476+ // All metatypes are Sendable and Copyable
1477+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) ||
1478+ protocol->isSpecificProtocol (KnownProtocolKind::Copyable)) {
14611479 ASTContext &ctx = protocol->getASTContext ();
14621480 return ProtocolConformanceRef (
14631481 ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
@@ -1471,8 +1489,9 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
14711489// / appropriate.
14721490static ProtocolConformanceRef getBuiltinBuiltinTypeConformance (
14731491 Type type, const BuiltinType *builtinType, ProtocolDecl *protocol) {
1474- // All builtin are Sendable.
1475- if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1492+ // All builtin are Sendable and Copyable
1493+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) ||
1494+ protocol->isSpecificProtocol (KnownProtocolKind::Copyable)) {
14761495 ASTContext &ctx = protocol->getASTContext ();
14771496 return ProtocolConformanceRef (
14781497 ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
@@ -1527,6 +1546,10 @@ LookupConformanceInModuleRequest::evaluate(
15271546 // constraint and the superclass conforms to the protocol.
15281547 if (auto archetype = type->getAs <ArchetypeType>()) {
15291548
1549+ // All archetypes conform to Copyable since they represent a generic.
1550+ if (protocol->isSpecificProtocol (KnownProtocolKind::Copyable))
1551+ return ProtocolConformanceRef (protocol);
1552+
15301553 // The generic signature builder drops conformance requirements that are made
15311554 // redundant by a superclass requirement, so check for a concrete
15321555 // conformance first, since an abstract conformance might not be
@@ -1636,6 +1659,15 @@ LookupConformanceInModuleRequest::evaluate(
16361659 } else {
16371660 return ProtocolConformanceRef::forMissingOrInvalid (type, protocol);
16381661 }
1662+ } else if (protocol->isSpecificProtocol (KnownProtocolKind::Copyable)) {
1663+ // Only move-only nominals are not Copyable
1664+ if (nominal->isMoveOnly ()) {
1665+ return ProtocolConformanceRef::forInvalid ();
1666+ } else {
1667+ // FIXME: this should probably follow the Sendable case in that
1668+ // we should synthesize and append a ProtocolConformance to the `conformances` list.
1669+ return ProtocolConformanceRef (protocol);
1670+ }
16391671 } else {
16401672 // Was unable to infer the missing conformance.
16411673 return ProtocolConformanceRef::forMissingOrInvalid (type, protocol);
0 commit comments