@@ -905,7 +905,7 @@ void TypeChecker::diagnoseRequirementFailure(
905905 const auto &req = reqFailureInfo.Req ;
906906 const auto &substReq = reqFailureInfo.SubstReq ;
907907
908- Diag<Type, Type, Type> diagnostic;
908+ std::optional< Diag<Type, Type, Type> > diagnostic;
909909 Diag<Type, Type, StringRef> diagnosticNote;
910910
911911 const auto reqKind = req.getKind ();
@@ -923,6 +923,24 @@ void TypeChecker::diagnoseRequirementFailure(
923923 break ;
924924
925925 case RequirementKind::Conformance: {
926+ // If this was a failure due to isolated conformances conflicting with
927+ // a Sendable or MetatypeSendable requirement, diagnose that.
928+ if (reqFailureInfo.IsolatedConformanceProto ) {
929+ ASTContext &ctx =
930+ reqFailureInfo.IsolatedConformanceProto ->getASTContext ();
931+ auto isolatedConformance = reqFailureInfo.IsolatedConformances .front ();
932+ ctx.Diags .diagnose (
933+ errorLoc, diag::isolated_conformance_with_sendable,
934+ isolatedConformance->getType (),
935+ isolatedConformance->getProtocol ()->getName (),
936+ reqFailureInfo
937+ .IsolatedConformanceProto ->isSpecificProtocol (
938+ KnownProtocolKind::SendableMetatype),
939+ req.getFirstType ());
940+ diagnosticNote = diag::type_does_not_inherit_or_conform_requirement;
941+ break ;
942+ }
943+
926944 diagnoseConformanceFailure (substReq.getFirstType (),
927945 substReq.getProtocolDecl (), nullptr , errorLoc);
928946
@@ -951,9 +969,12 @@ void TypeChecker::diagnoseRequirementFailure(
951969 }
952970
953971 ASTContext &ctx = targetTy->getASTContext ();
954- // FIXME: Poor source-location information.
955- ctx.Diags .diagnose (errorLoc, diagnostic, targetTy, substReq.getFirstType (),
956- substSecondTy);
972+
973+ if (diagnostic) {
974+ // FIXME: Poor source-location information.
975+ ctx.Diags .diagnose (errorLoc, *diagnostic, targetTy, substReq.getFirstType (),
976+ substSecondTy);
977+ }
957978
958979 const auto genericParamBindingsText = gatherGenericParamBindingsText (
959980 {req.getFirstType (), secondTy}, genericParams, substitutions);
@@ -966,6 +987,7 @@ void TypeChecker::diagnoseRequirementFailure(
966987}
967988
968989CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics (
990+ GenericSignature signature,
969991 ArrayRef<Requirement> requirements,
970992 TypeSubstitutionFn substitutions) {
971993 using ParentConditionalConformances =
@@ -1004,7 +1026,9 @@ CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics(
10041026 auto substReq = item.SubstReq ;
10051027
10061028 SmallVector<Requirement, 2 > subReqs;
1007- switch (substReq.checkRequirement (subReqs, /* allowMissing=*/ true )) {
1029+ SmallVector<ProtocolConformance *, 2 > isolatedConformances;
1030+ switch (substReq.checkRequirement (subReqs, /* allowMissing=*/ true ,
1031+ &isolatedConformances)) {
10081032 case CheckRequirementResult::Success:
10091033 break ;
10101034
@@ -1036,6 +1060,38 @@ CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics(
10361060 hadSubstFailure = true ;
10371061 break ;
10381062 }
1063+
1064+ if (!isolatedConformances.empty ()) {
1065+ // Dig out the original type parameter for the requirement.
1066+ // FIXME: req might not be the right pre-substituted requirement,
1067+ // if this came from a conditional requirement.
1068+ auto firstType = req.getFirstType ();
1069+
1070+ // An isolated conformance cannot be used in a context where the type
1071+ // parameter can escape the isolation domain in which the conformance
1072+ // was formed. To establish this, we look for Sendable or SendableMetatype
1073+ // requirements on the type parameter itself.
1074+ ASTContext &ctx = firstType->getASTContext ();
1075+ auto sendableProto = ctx.getProtocol (KnownProtocolKind::Sendable);
1076+ auto sendableMetatypeProto =
1077+ ctx.getProtocol (KnownProtocolKind::SendableMetatype);
1078+ if (firstType->isTypeParameter ()) {
1079+ std::optional<ProtocolDecl *> failedProtocol;
1080+ if (sendableProto &&
1081+ signature->requiresProtocol (firstType, sendableProto))
1082+ failedProtocol = sendableProto;
1083+ else if (sendableMetatypeProto &&
1084+ signature->requiresProtocol (firstType, sendableMetatypeProto))
1085+ failedProtocol = sendableMetatypeProto;
1086+
1087+ if (failedProtocol) {
1088+ return CheckGenericArgumentsResult::createIsolatedConformanceFailure (
1089+ req, substReq,
1090+ TinyPtrVector<ProtocolConformance *>(isolatedConformances),
1091+ *failedProtocol);
1092+ }
1093+ }
1094+ }
10391095 }
10401096
10411097 if (hadSubstFailure)
0 commit comments