@@ -989,10 +989,29 @@ ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
989989 getASTContext ().evaluator , request, ProtocolConformanceRef::forInvalid ());
990990}
991991
992+ // / Retrieve an invalid or missing conformance, as appropriate, when a
993+ // / legitimate conformance doesn't exist.
994+ static ProtocolConformanceRef getInvalidOrMissingConformance (
995+ Type type, ProtocolDecl *proto) {
996+ // Introduce "missing" conformances to Sendable, so that type checking
997+ // (and even code generation) can continue.
998+ ASTContext &ctx = proto->getASTContext ();
999+ if (proto->isSpecificProtocol (KnownProtocolKind::Sendable) &&
1000+ ctx.LangOpts .WarnConcurrency ) {
1001+ return ProtocolConformanceRef (
1002+ ctx.getBuiltinConformance (
1003+ type, proto, GenericSignature (), { },
1004+ BuiltinConformanceKind::Missing));
1005+ }
1006+
1007+ return ProtocolConformanceRef::forInvalid ();
1008+ }
1009+
9921010// / Synthesize a builtin tuple type conformance to the given protocol, if
9931011// / appropriate.
9941012static ProtocolConformanceRef getBuiltinTupleTypeConformance (
995- Type type, const TupleType *tupleType, ProtocolDecl *protocol) {
1013+ Type type, const TupleType *tupleType, ProtocolDecl *protocol,
1014+ ModuleDecl *module ) {
9961015 // Tuple type are Sendable when all of their element types are Sendable.
9971016 if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
9981017 ASTContext &ctx = protocol->getASTContext ();
@@ -1016,26 +1035,38 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
10161035 // If there were no generic parameters, just form the builtin conformance.
10171036 if (genericParams.empty ()) {
10181037 return ProtocolConformanceRef (
1019- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1038+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1039+ BuiltinConformanceKind::Synthesized));
10201040 }
10211041
10221042 // Form a generic conformance of (T1, T2, ..., TN): Sendable with signature
10231043 // <T1, T2, ..., TN> and conditional requirements T1: Sendable,
10241044 // T2: Sendable, ..., TN: Sendable.
10251045 auto genericTupleType = TupleType::get (genericElements, ctx);
1026- auto genericSig = GenericSignature::get (genericParams, { });
1046+ auto genericSig = GenericSignature::get (
1047+ genericParams, conditionalRequirements);
10271048 auto genericConformance = ctx.getBuiltinConformance (
1028- genericTupleType, protocol, genericSig, conditionalRequirements);
1049+ genericTupleType, protocol, genericSig, conditionalRequirements,
1050+ BuiltinConformanceKind::Synthesized);
10291051
10301052 // Compute the substitution map from the generic parameters of the
10311053 // generic conformance to actual types that were in the tuple type.
10321054 // Form a specialized conformance from that.
1033- auto subMap = SubstitutionMap::get (genericSig, typeSubstitutions, { });
1055+ auto subMap = SubstitutionMap::get (
1056+ genericSig, [&](SubstitutableType *type) {
1057+ if (auto gp = dyn_cast<GenericTypeParamType>(type)) {
1058+ if (gp->getDepth () == 0 )
1059+ return typeSubstitutions[gp->getIndex ()];
1060+ }
1061+
1062+ return Type (type);
1063+ },
1064+ LookUpConformanceInModule (module ));
10341065 return ProtocolConformanceRef (
10351066 ctx.getSpecializedConformance (type, genericConformance, subMap));
10361067 }
10371068
1038- return ProtocolConformanceRef::forInvalid ( );
1069+ return getInvalidOrMissingConformance (type, protocol );
10391070}
10401071
10411072// / Whether the given function type conforms to Sendable.
@@ -1064,10 +1095,11 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
10641095 isSendableFunctionType (functionType)) {
10651096 ASTContext &ctx = protocol->getASTContext ();
10661097 return ProtocolConformanceRef (
1067- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1098+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1099+ BuiltinConformanceKind::Synthesized));
10681100 }
10691101
1070- return ProtocolConformanceRef::forInvalid ( );
1102+ return getInvalidOrMissingConformance (type, protocol );
10711103}
10721104
10731105// / Synthesize a builtin metatype type conformance to the given protocol, if
@@ -1078,10 +1110,11 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
10781110 if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
10791111 ASTContext &ctx = protocol->getASTContext ();
10801112 return ProtocolConformanceRef (
1081- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1113+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1114+ BuiltinConformanceKind::Synthesized));
10821115 }
10831116
1084- return ProtocolConformanceRef::forInvalid ( );
1117+ return getInvalidOrMissingConformance (type, protocol );
10851118}
10861119
10871120// / Synthesize a builtin type conformance to the given protocol, if
@@ -1092,10 +1125,11 @@ static ProtocolConformanceRef getBuiltinBuiltinTypeConformance(
10921125 if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
10931126 ASTContext &ctx = protocol->getASTContext ();
10941127 return ProtocolConformanceRef (
1095- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1128+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1129+ BuiltinConformanceKind::Synthesized));
10961130 }
10971131
1098- return ProtocolConformanceRef::forInvalid ( );
1132+ return getInvalidOrMissingConformance (type, protocol );
10991133}
11001134
11011135ProtocolConformanceRef
@@ -1133,14 +1167,18 @@ LookupConformanceInModuleRequest::evaluate(
11331167 return ProtocolConformanceRef (protocol);
11341168 }
11351169
1136- return ProtocolConformanceRef::forInvalid ( );
1170+ return getInvalidOrMissingConformance (type, protocol );
11371171 }
11381172
11391173 // An existential conforms to a protocol if the protocol is listed in the
11401174 // existential's list of conformances and the existential conforms to
11411175 // itself.
1142- if (type->isExistentialType ())
1143- return mod->lookupExistentialConformance (type, protocol);
1176+ if (type->isExistentialType ()) {
1177+ auto result = mod->lookupExistentialConformance (type, protocol);
1178+ if (result.isInvalid ())
1179+ return getInvalidOrMissingConformance (type, protocol);
1180+ return result;
1181+ }
11441182
11451183 // Type variables have trivial conformances.
11461184 if (type->isTypeVariableOrMember ())
@@ -1154,7 +1192,7 @@ LookupConformanceInModuleRequest::evaluate(
11541192
11551193 // Tuple types can conform to protocols.
11561194 if (auto tupleType = type->getAs <TupleType>()) {
1157- return getBuiltinTupleTypeConformance (type, tupleType, protocol);
1195+ return getBuiltinTupleTypeConformance (type, tupleType, protocol, mod );
11581196 }
11591197
11601198 // Function types can conform to protocols.
@@ -1176,13 +1214,13 @@ LookupConformanceInModuleRequest::evaluate(
11761214
11771215 // If we don't have a nominal type, there are no conformances.
11781216 if (!nominal || isa<ProtocolDecl>(nominal))
1179- return ProtocolConformanceRef::forInvalid ( );
1217+ return getInvalidOrMissingConformance (type, protocol );
11801218
11811219 // Find the (unspecialized) conformance.
11821220 SmallVector<ProtocolConformance *, 2 > conformances;
11831221 if (!nominal->lookupConformance (mod, protocol, conformances)) {
11841222 if (!protocol->isSpecificProtocol (KnownProtocolKind::Sendable))
1185- return ProtocolConformanceRef::forInvalid ( );
1223+ return getInvalidOrMissingConformance (type, protocol );
11861224
11871225 // Try to infer Sendable conformance.
11881226 GetImplicitSendableRequest cvRequest{nominal};
@@ -1191,7 +1229,7 @@ LookupConformanceInModuleRequest::evaluate(
11911229 conformances.clear ();
11921230 conformances.push_back (conformance);
11931231 } else {
1194- return ProtocolConformanceRef::forInvalid ( );
1232+ return getInvalidOrMissingConformance (type, protocol );
11951233 }
11961234 }
11971235
0 commit comments