@@ -905,7 +905,7 @@ void TypeChecker::diagnoseRequirementFailure(
905
905
const auto &req = reqFailureInfo.Req ;
906
906
const auto &substReq = reqFailureInfo.SubstReq ;
907
907
908
- Diag<Type, Type, Type> diagnostic;
908
+ std::optional< Diag<Type, Type, Type> > diagnostic;
909
909
Diag<Type, Type, StringRef> diagnosticNote;
910
910
911
911
const auto reqKind = req.getKind ();
@@ -923,6 +923,24 @@ void TypeChecker::diagnoseRequirementFailure(
923
923
break ;
924
924
925
925
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
+
926
944
diagnoseConformanceFailure (substReq.getFirstType (),
927
945
substReq.getProtocolDecl (), nullptr , errorLoc);
928
946
@@ -951,9 +969,12 @@ void TypeChecker::diagnoseRequirementFailure(
951
969
}
952
970
953
971
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
+ }
957
978
958
979
const auto genericParamBindingsText = gatherGenericParamBindingsText (
959
980
{req.getFirstType (), secondTy}, genericParams, substitutions);
@@ -966,6 +987,7 @@ void TypeChecker::diagnoseRequirementFailure(
966
987
}
967
988
968
989
CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics (
990
+ GenericSignature signature,
969
991
ArrayRef<Requirement> requirements,
970
992
TypeSubstitutionFn substitutions) {
971
993
using ParentConditionalConformances =
@@ -1004,7 +1026,9 @@ CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics(
1004
1026
auto substReq = item.SubstReq ;
1005
1027
1006
1028
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)) {
1008
1032
case CheckRequirementResult::Success:
1009
1033
break ;
1010
1034
@@ -1036,6 +1060,38 @@ CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics(
1036
1060
hadSubstFailure = true ;
1037
1061
break ;
1038
1062
}
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
+ }
1039
1095
}
1040
1096
1041
1097
if (hadSubstFailure)
0 commit comments