@@ -970,8 +970,14 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
970
970
return ProtocolConformanceRef::forInvalid ();
971
971
}
972
972
973
+ // / Whether we should create missing conformances to the given protocol.
974
+ static bool shouldCreateMissingConformances (ProtocolDecl *proto) {
975
+ return proto->isSpecificProtocol (KnownProtocolKind::Sendable);
976
+ }
977
+
973
978
ProtocolConformanceRef ModuleDecl::lookupConformance (Type type,
974
- ProtocolDecl *protocol) {
979
+ ProtocolDecl *protocol,
980
+ bool allowMissing) {
975
981
// If we are recursively checking for implicit conformance of a nominal
976
982
// type to Sendable, fail without evaluating this request. This
977
983
// squashes cycles.
@@ -985,14 +991,41 @@ ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
985
991
}
986
992
}
987
993
988
- return evaluateOrDefault (
994
+ auto result = evaluateOrDefault (
989
995
getASTContext ().evaluator , request, ProtocolConformanceRef::forInvalid ());
996
+
997
+ // If we aren't supposed to allow missing conformances through for this
998
+ // protocol, replace the result with an "invalid" result.
999
+ if (!allowMissing &&
1000
+ shouldCreateMissingConformances (protocol) &&
1001
+ result.hasMissingConformance (this ))
1002
+ return ProtocolConformanceRef::forInvalid ();
1003
+
1004
+ return result;
1005
+ }
1006
+
1007
+ // / Retrieve an invalid or missing conformance, as appropriate, when a
1008
+ // / legitimate conformance doesn't exist.
1009
+ static ProtocolConformanceRef getInvalidOrMissingConformance (
1010
+ Type type, ProtocolDecl *proto) {
1011
+ // Introduce "missing" conformances when appropriate, so that type checking
1012
+ // (and even code generation) can continue.
1013
+ ASTContext &ctx = proto->getASTContext ();
1014
+ if (shouldCreateMissingConformances (proto)) {
1015
+ return ProtocolConformanceRef (
1016
+ ctx.getBuiltinConformance (
1017
+ type, proto, GenericSignature (), { },
1018
+ BuiltinConformanceKind::Missing));
1019
+ }
1020
+
1021
+ return ProtocolConformanceRef::forInvalid ();
990
1022
}
991
1023
992
1024
// / Synthesize a builtin tuple type conformance to the given protocol, if
993
1025
// / appropriate.
994
1026
static ProtocolConformanceRef getBuiltinTupleTypeConformance (
995
- Type type, const TupleType *tupleType, ProtocolDecl *protocol) {
1027
+ Type type, const TupleType *tupleType, ProtocolDecl *protocol,
1028
+ ModuleDecl *module ) {
996
1029
// Tuple type are Sendable when all of their element types are Sendable.
997
1030
if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
998
1031
ASTContext &ctx = protocol->getASTContext ();
@@ -1016,26 +1049,38 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
1016
1049
// If there were no generic parameters, just form the builtin conformance.
1017
1050
if (genericParams.empty ()) {
1018
1051
return ProtocolConformanceRef (
1019
- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1052
+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1053
+ BuiltinConformanceKind::Synthesized));
1020
1054
}
1021
1055
1022
1056
// Form a generic conformance of (T1, T2, ..., TN): Sendable with signature
1023
1057
// <T1, T2, ..., TN> and conditional requirements T1: Sendable,
1024
1058
// T2: Sendable, ..., TN: Sendable.
1025
1059
auto genericTupleType = TupleType::get (genericElements, ctx);
1026
- auto genericSig = GenericSignature::get (genericParams, { });
1060
+ auto genericSig = GenericSignature::get (
1061
+ genericParams, conditionalRequirements);
1027
1062
auto genericConformance = ctx.getBuiltinConformance (
1028
- genericTupleType, protocol, genericSig, conditionalRequirements);
1063
+ genericTupleType, protocol, genericSig, conditionalRequirements,
1064
+ BuiltinConformanceKind::Synthesized);
1029
1065
1030
1066
// Compute the substitution map from the generic parameters of the
1031
1067
// generic conformance to actual types that were in the tuple type.
1032
1068
// Form a specialized conformance from that.
1033
- auto subMap = SubstitutionMap::get (genericSig, typeSubstitutions, { });
1069
+ auto subMap = SubstitutionMap::get (
1070
+ genericSig, [&](SubstitutableType *type) {
1071
+ if (auto gp = dyn_cast<GenericTypeParamType>(type)) {
1072
+ if (gp->getDepth () == 0 )
1073
+ return typeSubstitutions[gp->getIndex ()];
1074
+ }
1075
+
1076
+ return Type (type);
1077
+ },
1078
+ LookUpConformanceInModule (module ));
1034
1079
return ProtocolConformanceRef (
1035
1080
ctx.getSpecializedConformance (type, genericConformance, subMap));
1036
1081
}
1037
1082
1038
- return ProtocolConformanceRef::forInvalid ( );
1083
+ return getInvalidOrMissingConformance (type, protocol );
1039
1084
}
1040
1085
1041
1086
// / Whether the given function type conforms to Sendable.
@@ -1064,10 +1109,11 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
1064
1109
isSendableFunctionType (functionType)) {
1065
1110
ASTContext &ctx = protocol->getASTContext ();
1066
1111
return ProtocolConformanceRef (
1067
- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1112
+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1113
+ BuiltinConformanceKind::Synthesized));
1068
1114
}
1069
1115
1070
- return ProtocolConformanceRef::forInvalid ( );
1116
+ return getInvalidOrMissingConformance (type, protocol );
1071
1117
}
1072
1118
1073
1119
// / Synthesize a builtin metatype type conformance to the given protocol, if
@@ -1078,10 +1124,11 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
1078
1124
if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1079
1125
ASTContext &ctx = protocol->getASTContext ();
1080
1126
return ProtocolConformanceRef (
1081
- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1127
+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1128
+ BuiltinConformanceKind::Synthesized));
1082
1129
}
1083
1130
1084
- return ProtocolConformanceRef::forInvalid ( );
1131
+ return getInvalidOrMissingConformance (type, protocol );
1085
1132
}
1086
1133
1087
1134
// / Synthesize a builtin type conformance to the given protocol, if
@@ -1092,10 +1139,11 @@ static ProtocolConformanceRef getBuiltinBuiltinTypeConformance(
1092
1139
if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable)) {
1093
1140
ASTContext &ctx = protocol->getASTContext ();
1094
1141
return ProtocolConformanceRef (
1095
- ctx.getBuiltinConformance (type, protocol, GenericSignature (), { }));
1142
+ ctx.getBuiltinConformance (type, protocol, GenericSignature (), { },
1143
+ BuiltinConformanceKind::Synthesized));
1096
1144
}
1097
1145
1098
- return ProtocolConformanceRef::forInvalid ( );
1146
+ return getInvalidOrMissingConformance (type, protocol );
1099
1147
}
1100
1148
1101
1149
ProtocolConformanceRef
@@ -1133,14 +1181,18 @@ LookupConformanceInModuleRequest::evaluate(
1133
1181
return ProtocolConformanceRef (protocol);
1134
1182
}
1135
1183
1136
- return ProtocolConformanceRef::forInvalid ( );
1184
+ return getInvalidOrMissingConformance (type, protocol );
1137
1185
}
1138
1186
1139
1187
// An existential conforms to a protocol if the protocol is listed in the
1140
1188
// existential's list of conformances and the existential conforms to
1141
1189
// itself.
1142
- if (type->isExistentialType ())
1143
- return mod->lookupExistentialConformance (type, protocol);
1190
+ if (type->isExistentialType ()) {
1191
+ auto result = mod->lookupExistentialConformance (type, protocol);
1192
+ if (result.isInvalid ())
1193
+ return getInvalidOrMissingConformance (type, protocol);
1194
+ return result;
1195
+ }
1144
1196
1145
1197
// Type variables have trivial conformances.
1146
1198
if (type->isTypeVariableOrMember ())
@@ -1154,7 +1206,7 @@ LookupConformanceInModuleRequest::evaluate(
1154
1206
1155
1207
// Tuple types can conform to protocols.
1156
1208
if (auto tupleType = type->getAs <TupleType>()) {
1157
- return getBuiltinTupleTypeConformance (type, tupleType, protocol);
1209
+ return getBuiltinTupleTypeConformance (type, tupleType, protocol, mod );
1158
1210
}
1159
1211
1160
1212
// Function types can conform to protocols.
@@ -1176,13 +1228,13 @@ LookupConformanceInModuleRequest::evaluate(
1176
1228
1177
1229
// If we don't have a nominal type, there are no conformances.
1178
1230
if (!nominal || isa<ProtocolDecl>(nominal))
1179
- return ProtocolConformanceRef::forInvalid ( );
1231
+ return getInvalidOrMissingConformance (type, protocol );
1180
1232
1181
1233
// Find the (unspecialized) conformance.
1182
1234
SmallVector<ProtocolConformance *, 2 > conformances;
1183
1235
if (!nominal->lookupConformance (mod, protocol, conformances)) {
1184
1236
if (!protocol->isSpecificProtocol (KnownProtocolKind::Sendable))
1185
- return ProtocolConformanceRef::forInvalid ( );
1237
+ return getInvalidOrMissingConformance (type, protocol );
1186
1238
1187
1239
// Try to infer Sendable conformance.
1188
1240
GetImplicitSendableRequest cvRequest{nominal};
@@ -1191,7 +1243,7 @@ LookupConformanceInModuleRequest::evaluate(
1191
1243
conformances.clear ();
1192
1244
conformances.push_back (conformance);
1193
1245
} else {
1194
- return ProtocolConformanceRef::forInvalid ( );
1246
+ return getInvalidOrMissingConformance (type, protocol );
1195
1247
}
1196
1248
}
1197
1249
0 commit comments