@@ -1002,11 +1002,13 @@ void swift::diagnoseUnnecessaryPreconcurrencyImports(SourceFile &sf) {
1002
1002
// / Produce a diagnostic for a single instance of a non-Sendable type where
1003
1003
// / a Sendable type is required.
1004
1004
static bool diagnoseSingleNonSendableType (
1005
- Type type, SendableCheckContext fromContext, SourceLoc loc,
1005
+ Type type, SendableCheckContext fromContext,
1006
+ Type inDerivedConformance, SourceLoc loc,
1006
1007
llvm::function_ref<bool (Type, DiagnosticBehavior)> diagnose) {
1007
1008
1008
1009
auto module = fromContext.fromDC ->getParentModule ();
1009
1010
auto nominal = type->getAnyNominal ();
1011
+ auto &ctx = module ->getASTContext ();
1010
1012
1011
1013
return diagnoseSendabilityErrorBasedOn (nominal, fromContext,
1012
1014
[&](DiagnosticBehavior behavior) {
@@ -1017,9 +1019,13 @@ static bool diagnoseSingleNonSendableType(
1017
1019
if (wasSuppressed || behavior == DiagnosticBehavior::Ignore)
1018
1020
return true ;
1019
1021
1022
+ if (inDerivedConformance) {
1023
+ ctx.Diags .diagnose (loc, diag::in_derived_conformance,
1024
+ inDerivedConformance);
1025
+ }
1026
+
1020
1027
if (type->is <FunctionType>()) {
1021
- module ->getASTContext ().Diags
1022
- .diagnose (loc, diag::nonsendable_function_type);
1028
+ ctx.Diags .diagnose (loc, diag::nonsendable_function_type);
1023
1029
} else if (nominal && nominal->getParentModule () == module ) {
1024
1030
// If the nominal type is in the current module, suggest adding
1025
1031
// `Sendable` if it might make sense. Otherwise, just complain.
@@ -1052,7 +1058,8 @@ static bool diagnoseSingleNonSendableType(
1052
1058
}
1053
1059
1054
1060
bool swift::diagnoseNonSendableTypes (
1055
- Type type, SendableCheckContext fromContext, SourceLoc loc,
1061
+ Type type, SendableCheckContext fromContext,
1062
+ Type inDerivedConformance, SourceLoc loc,
1056
1063
llvm::function_ref<bool (Type, DiagnosticBehavior)> diagnose) {
1057
1064
auto module = fromContext.fromDC ->getParentModule ();
1058
1065
@@ -1064,15 +1071,17 @@ bool swift::diagnoseNonSendableTypes(
1064
1071
// FIXME: More detail for unavailable conformances.
1065
1072
auto conformance = TypeChecker::conformsToProtocol (type, proto, module );
1066
1073
if (conformance.isInvalid () || conformance.hasUnavailableConformance ()) {
1067
- return diagnoseSingleNonSendableType (type, fromContext, loc, diagnose);
1074
+ return diagnoseSingleNonSendableType (
1075
+ type, fromContext, inDerivedConformance, loc, diagnose);
1068
1076
}
1069
1077
1070
1078
// Walk the conformance, diagnosing any missing Sendable conformances.
1071
1079
bool anyMissing = false ;
1072
1080
conformance.forEachMissingConformance (module ,
1073
1081
[&](BuiltinProtocolConformance *missing) {
1074
1082
if (diagnoseSingleNonSendableType (
1075
- missing->getType (), fromContext, loc, diagnose)) {
1083
+ missing->getType (), fromContext,
1084
+ inDerivedConformance, loc, diagnose)) {
1076
1085
anyMissing = true ;
1077
1086
}
1078
1087
@@ -1095,11 +1104,27 @@ bool swift::diagnoseNonSendableTypesInReference(
1095
1104
return swift::getActorIsolation (declRef.getDecl ());
1096
1105
};
1097
1106
1107
+ // If the violation is in the implementation of a derived conformance,
1108
+ // point to the location of the parent type instead.
1109
+ Type derivedConformanceType;
1110
+ if (refLoc.isInvalid ()) {
1111
+ auto *decl = fromDC->getAsDecl ();
1112
+ if (decl && decl->isImplicit ()) {
1113
+ if (auto *implements = decl->getAttrs ().getAttribute <ImplementsAttr>()) {
1114
+ auto *parentDC = decl->getDeclContext ();
1115
+ refLoc = parentDC->getAsDecl ()->getLoc ();
1116
+ derivedConformanceType =
1117
+ implements->getProtocol (parentDC)->getDeclaredInterfaceType ();
1118
+ }
1119
+ }
1120
+ }
1121
+
1098
1122
// Check the 'self' argument.
1099
1123
if (base) {
1100
1124
if (diagnoseNonSendableTypes (
1101
1125
base->getType (),
1102
- fromDC, base->getStartLoc (),
1126
+ fromDC, derivedConformanceType,
1127
+ base->getStartLoc (),
1103
1128
diag::non_sendable_param_type,
1104
1129
(unsigned )refKind, declRef.getDecl (),
1105
1130
getActorIsolation ()))
@@ -1114,7 +1139,8 @@ bool swift::diagnoseNonSendableTypesInReference(
1114
1139
for (auto param : *function->getParameters ()) {
1115
1140
Type paramType = param->getInterfaceType ().subst (subs);
1116
1141
if (diagnoseNonSendableTypes (
1117
- paramType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1142
+ paramType, fromDC, derivedConformanceType,
1143
+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1118
1144
diag::non_sendable_param_type,
1119
1145
(unsigned )refKind, function, getActorIsolation ()))
1120
1146
return true ;
@@ -1127,7 +1153,8 @@ bool swift::diagnoseNonSendableTypesInReference(
1127
1153
// only check results if funcCheckKind specifies so
1128
1154
Type resultType = func->getResultInterfaceType ().subst (subs);
1129
1155
if (diagnoseNonSendableTypes (
1130
- resultType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1156
+ resultType, fromDC, derivedConformanceType,
1157
+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1131
1158
diag::non_sendable_result_type,
1132
1159
(unsigned )refKind, func, getActorIsolation ()))
1133
1160
return true ;
@@ -1142,7 +1169,8 @@ bool swift::diagnoseNonSendableTypesInReference(
1142
1169
? var->getTypeInContext ()
1143
1170
: var->getValueInterfaceType ().subst (subs);
1144
1171
if (diagnoseNonSendableTypes (
1145
- propertyType, fromDC, refLoc,
1172
+ propertyType, fromDC,
1173
+ derivedConformanceType, refLoc,
1146
1174
diag::non_sendable_property_type,
1147
1175
var,
1148
1176
var->isLocalCapture (),
@@ -1157,7 +1185,8 @@ bool swift::diagnoseNonSendableTypesInReference(
1157
1185
// Check params of this subscript override for sendability
1158
1186
Type paramType = param->getInterfaceType ().subst (subs);
1159
1187
if (diagnoseNonSendableTypes (
1160
- paramType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1188
+ paramType, fromDC, derivedConformanceType,
1189
+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1161
1190
diag::non_sendable_param_type,
1162
1191
(unsigned )refKind, subscript, getActorIsolation ()))
1163
1192
return true ;
@@ -1168,7 +1197,8 @@ bool swift::diagnoseNonSendableTypesInReference(
1168
1197
// Check the element type of a subscript.
1169
1198
Type resultType = subscript->getElementInterfaceType ().subst (subs);
1170
1199
if (diagnoseNonSendableTypes (
1171
- resultType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1200
+ resultType, fromDC, derivedConformanceType,
1201
+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1172
1202
diag::non_sendable_result_type,
1173
1203
(unsigned )refKind, subscript, getActorIsolation ()))
1174
1204
return true ;
@@ -1183,7 +1213,8 @@ bool swift::diagnoseNonSendableTypesInReference(
1183
1213
void swift::diagnoseMissingSendableConformance (
1184
1214
SourceLoc loc, Type type, const DeclContext *fromDC) {
1185
1215
diagnoseNonSendableTypes (
1186
- type, fromDC, loc, diag::non_sendable_type);
1216
+ type, fromDC, /* inDerivedConformance*/ Type (),
1217
+ loc, diag::non_sendable_type);
1187
1218
}
1188
1219
1189
1220
namespace {
@@ -1935,7 +1966,8 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
1935
1966
auto *base = selfApply->getBase ();
1936
1967
if (diagnoseNonSendableTypes (
1937
1968
base->getType (),
1938
- declContext, base->getStartLoc (),
1969
+ declContext, /* inDerivedConformance*/ Type (),
1970
+ base->getStartLoc (),
1939
1971
diag::non_sendable_call_argument,
1940
1972
isolationCrossing.value ().exitsIsolation (),
1941
1973
isolationCrossing.value ().getDiagnoseIsolation ()))
@@ -1976,7 +2008,8 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
1976
2008
1977
2009
if (diagnoseNonSendableTypes (
1978
2010
argType ? argType : param.getParameterType (),
1979
- declContext, argLoc, diag::non_sendable_call_argument,
2011
+ declContext, /* inDerivedConformance*/ Type (),
2012
+ argLoc, diag::non_sendable_call_argument,
1980
2013
isolationCrossing.value ().exitsIsolation (),
1981
2014
isolationCrossing.value ().getDiagnoseIsolation ()))
1982
2015
return true ;
@@ -2418,19 +2451,24 @@ namespace {
2418
2451
// into async let to SIL level region based isolation.
2419
2452
if (!ctx.LangOpts .hasFeature (Feature::RegionBasedIsolation)) {
2420
2453
diagnoseNonSendableTypes (
2421
- type, getDeclContext (), capture.getLoc (),
2454
+ type, getDeclContext (),
2455
+ /* inDerivedConformance*/ Type (), capture.getLoc (),
2422
2456
diag::implicit_async_let_non_sendable_capture,
2423
2457
decl->getName ());
2424
2458
}
2425
2459
} else {
2426
2460
// Fallback to a generic implicit capture missing sendable
2427
2461
// conformance diagnostic.
2428
- diagnoseNonSendableTypes (type, getDeclContext (), capture.getLoc (),
2462
+ diagnoseNonSendableTypes (type, getDeclContext (),
2463
+ /* inDerivedConformance*/ Type (),
2464
+ capture.getLoc (),
2429
2465
diag::implicit_non_sendable_capture,
2430
2466
decl->getName ());
2431
2467
}
2432
2468
} else {
2433
- diagnoseNonSendableTypes (type, getDeclContext (), capture.getLoc (),
2469
+ diagnoseNonSendableTypes (type, getDeclContext (),
2470
+ /* inDerivedConformance*/ Type (),
2471
+ capture.getLoc (),
2434
2472
diag::non_sendable_capture, decl->getName (),
2435
2473
/* closure=*/ closure != nullptr );
2436
2474
}
@@ -3341,7 +3379,9 @@ namespace {
3341
3379
3342
3380
// Check for sendability of the result type.
3343
3381
if (diagnoseNonSendableTypes (
3344
- fnType->getResult (), getDeclContext (), apply->getLoc (),
3382
+ fnType->getResult (), getDeclContext (),
3383
+ /* inDerivedConformance*/ Type (),
3384
+ apply->getLoc (),
3345
3385
diag::non_sendable_call_result_type,
3346
3386
apply->isImplicitlyAsync ().has_value (),
3347
3387
*unsatisfiedIsolation))
@@ -3483,6 +3523,7 @@ namespace {
3483
3523
llvm::None)) {
3484
3524
if (diagnoseNonSendableTypes (
3485
3525
component.getComponentType (), getDeclContext (),
3526
+ /* inDerivedConformance*/ Type (),
3486
3527
component.getLoc (),
3487
3528
diag::non_sendable_keypath_access)) {
3488
3529
diagnosed = true ;
@@ -3516,6 +3557,7 @@ namespace {
3516
3557
auto type = getType (arg.getExpr ());
3517
3558
if (type && shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
3518
3559
diagnoseNonSendableTypes (type, getDeclContext (),
3560
+ /* inDerivedConformance*/ Type (),
3519
3561
component.getLoc (),
3520
3562
diag::non_sendable_keypath_capture))
3521
3563
diagnosed = true ;
@@ -5163,7 +5205,8 @@ static bool checkSendableInstanceStorage(
5163
5205
5164
5206
// Check that the property type is Sendable.
5165
5207
diagnoseNonSendableTypes (
5166
- propertyType, SendableCheckContext (dc, check), property->getLoc (),
5208
+ propertyType, SendableCheckContext (dc, check),
5209
+ /* inDerivedConformance*/ Type (), property->getLoc (),
5167
5210
[&](Type type, DiagnosticBehavior behavior) {
5168
5211
if (isImplicitSendableCheck (check)) {
5169
5212
// If this is for an externally-visible conformance, fail.
@@ -5199,7 +5242,8 @@ static bool checkSendableInstanceStorage(
5199
5242
// / Handle an enum associated value.
5200
5243
bool operator ()(EnumElementDecl *element, Type elementType) override {
5201
5244
diagnoseNonSendableTypes (
5202
- elementType, SendableCheckContext (dc, check), element->getLoc (),
5245
+ elementType, SendableCheckContext (dc, check),
5246
+ /* inDerivedConformance*/ Type (), element->getLoc (),
5203
5247
[&](Type type, DiagnosticBehavior behavior) {
5204
5248
if (isImplicitSendableCheck (check)) {
5205
5249
// If this is for an externally-visible conformance, fail.
0 commit comments