@@ -989,6 +989,115 @@ ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
989989 getASTContext ().evaluator , request, ProtocolConformanceRef::forInvalid ());
990990}
991991
992+ // / Synthesize a builtin tuple type conformance to the given protocol, if
993+ // / appropriate.
994+ static ProtocolConformanceRef getBuiltinTupleTypeConformance (
995+ Type type, const TupleType *tupleType, ProtocolDecl *protocol) {
996+ // Tuple type are Sendable when all of their element types are Sendable.
997+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
998+ ASTContext &ctx = protocol->getASTContext ();
999+
1000+ // Create the pieces for a generic tuple type (T1, T2, ... TN) and a
1001+ // generic signature <T1, T2, ..., TN>.
1002+ SmallVector<GenericTypeParamType *, 4 > genericParams;
1003+ SmallVector<Type, 4 > typeSubstitutions;
1004+ SmallVector<TupleTypeElt, 4 > genericElements;
1005+ SmallVector<Requirement, 4 > conditionalRequirements;
1006+ for (const auto &elt : tupleType->getElements ()) {
1007+ auto genericParam = GenericTypeParamType::get (0 , genericParams.size (), ctx);
1008+ genericParams.push_back (genericParam);
1009+ typeSubstitutions.push_back (elt.getRawType ());
1010+ genericElements.push_back (elt.getWithType (genericParam));
1011+ conditionalRequirements.push_back (
1012+ Requirement (RequirementKind::Conformance, genericParam,
1013+ protocol->getDeclaredType ()));
1014+ }
1015+
1016+ // If there were no generic parameters, just form the builtin conformance.
1017+ if (genericParams.empty ()) {
1018+ return ProtocolConformanceRef (
1019+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1020+ }
1021+
1022+ // Form a generic conformance of (T1, T2, ..., TN): Sendable with signature
1023+ // <T1, T2, ..., TN> and conditional requirements T1: Sendable,
1024+ // T2: Sendable, ..., TN: Sendable.
1025+ auto genericTupleType = TupleType::get (genericElements, ctx);
1026+ auto genericSig = GenericSignature::get (genericParams, { });
1027+ auto genericConformance = ctx.getBuiltinConformance (
1028+ genericTupleType, protocol, genericSig, conditionalRequirements);
1029+
1030+ // Compute the substitution map from the generic parameters of the
1031+ // generic conformance to actual types that were in the tuple type.
1032+ // Form a specialized conformance from that.
1033+ auto subMap = SubstitutionMap::get (genericSig, typeSubstitutions, { });
1034+ return ProtocolConformanceRef (
1035+ ctx.getSpecializedConformance (type, genericConformance, subMap));
1036+ }
1037+
1038+ return ProtocolConformanceRef::forInvalid ();
1039+ }
1040+
1041+ // / Whether the given function type conforms to Sendable.
1042+ static bool isSendableFunctionType (const FunctionType *functionType) {
1043+ if (functionType->isSendable ())
1044+ return true ;
1045+
1046+ // C and thin function types have no captures, so they are Sendable.
1047+ switch (functionType->getExtInfo ().getRepresentation ()) {
1048+ case FunctionTypeRepresentation::Block:
1049+ case FunctionTypeRepresentation::Swift:
1050+ return false ;
1051+
1052+ case FunctionTypeRepresentation::CFunctionPointer:
1053+ case FunctionTypeRepresentation::Thin:
1054+ return true ;
1055+ }
1056+ }
1057+
1058+ // / Synthesize a builtin function type conformance to the given protocol, if
1059+ // / appropriate.
1060+ static ProtocolConformanceRef getBuiltinFunctionTypeConformance (
1061+ Type type, const FunctionType *functionType, ProtocolDecl *protocol) {
1062+ // @Sendable function types are Sendable.
1063+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) &&
1064+ isSendableFunctionType (functionType)) {
1065+ ASTContext &ctx = protocol->getASTContext ();
1066+ return ProtocolConformanceRef (
1067+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1068+ }
1069+
1070+ return ProtocolConformanceRef::forInvalid ();
1071+ }
1072+
1073+ // / Synthesize a builtin metatype type conformance to the given protocol, if
1074+ // / appropriate.
1075+ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance (
1076+ Type type, const AnyMetatypeType *metatypeType, ProtocolDecl *protocol) {
1077+ // All metatypes are Sendable.
1078+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1079+ ASTContext &ctx = protocol->getASTContext ();
1080+ return ProtocolConformanceRef (
1081+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1082+ }
1083+
1084+ return ProtocolConformanceRef::forInvalid ();
1085+ }
1086+
1087+ // / Synthesize a builtin type conformance to the given protocol, if
1088+ // / appropriate.
1089+ static ProtocolConformanceRef getBuiltinBuiltinTypeConformance (
1090+ Type type, const BuiltinType *builtinType, ProtocolDecl *protocol) {
1091+ // All builtin are Sendable.
1092+ if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1093+ ASTContext &ctx = protocol->getASTContext ();
1094+ return ProtocolConformanceRef (
1095+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1096+ }
1097+
1098+ return ProtocolConformanceRef::forInvalid ();
1099+ }
1100+
9921101ProtocolConformanceRef
9931102LookupConformanceInModuleRequest::evaluate (
9941103 Evaluator &evaluator, LookupConformanceDescriptor desc) const {
@@ -1043,6 +1152,26 @@ LookupConformanceInModuleRequest::evaluate(
10431152 if (type->is <UnresolvedType>() || type->is <PlaceholderType>())
10441153 return ProtocolConformanceRef (protocol);
10451154
1155+ // Tuple types can conform to protocols.
1156+ if (auto tupleType = type->getAs <TupleType>()) {
1157+ return getBuiltinTupleTypeConformance (type, tupleType, protocol);
1158+ }
1159+
1160+ // Function types can conform to protocols.
1161+ if (auto functionType = type->getAs <FunctionType>()) {
1162+ return getBuiltinFunctionTypeConformance (type, functionType, protocol);
1163+ }
1164+
1165+ // Metatypes can conform to protocols.
1166+ if (auto metatypeType = type->getAs <AnyMetatypeType>()) {
1167+ return getBuiltinMetaTypeTypeConformance (type, metatypeType, protocol);
1168+ }
1169+
1170+ // Builtin types can conform to protocols.
1171+ if (auto builtinType = type->getAs <BuiltinType>()) {
1172+ return getBuiltinBuiltinTypeConformance (type, builtinType, protocol);
1173+ }
1174+
10461175 auto nominal = type->getAnyNominal ();
10471176
10481177 // If we don't have a nominal type, there are no conformances.
0 commit comments