@@ -1002,11 +1002,13 @@ void swift::diagnoseUnnecessaryPreconcurrencyImports(SourceFile &sf) {
10021002// / Produce a diagnostic for a single instance of a non-Sendable type where
10031003// / a Sendable type is required.
10041004static bool diagnoseSingleNonSendableType (
1005- Type type, SendableCheckContext fromContext, SourceLoc loc,
1005+ Type type, SendableCheckContext fromContext,
1006+ Type inDerivedConformance, SourceLoc loc,
10061007 llvm::function_ref<bool (Type, DiagnosticBehavior)> diagnose) {
10071008
10081009 auto module = fromContext.fromDC ->getParentModule ();
10091010 auto nominal = type->getAnyNominal ();
1011+ auto &ctx = module ->getASTContext ();
10101012
10111013 return diagnoseSendabilityErrorBasedOn (nominal, fromContext,
10121014 [&](DiagnosticBehavior behavior) {
@@ -1017,9 +1019,13 @@ static bool diagnoseSingleNonSendableType(
10171019 if (wasSuppressed || behavior == DiagnosticBehavior::Ignore)
10181020 return true ;
10191021
1022+ if (inDerivedConformance) {
1023+ ctx.Diags .diagnose (loc, diag::in_derived_conformance,
1024+ inDerivedConformance);
1025+ }
1026+
10201027 if (type->is <FunctionType>()) {
1021- module ->getASTContext ().Diags
1022- .diagnose (loc, diag::nonsendable_function_type);
1028+ ctx.Diags .diagnose (loc, diag::nonsendable_function_type);
10231029 } else if (nominal && nominal->getParentModule () == module ) {
10241030 // If the nominal type is in the current module, suggest adding
10251031 // `Sendable` if it might make sense. Otherwise, just complain.
@@ -1052,7 +1058,8 @@ static bool diagnoseSingleNonSendableType(
10521058}
10531059
10541060bool swift::diagnoseNonSendableTypes (
1055- Type type, SendableCheckContext fromContext, SourceLoc loc,
1061+ Type type, SendableCheckContext fromContext,
1062+ Type inDerivedConformance, SourceLoc loc,
10561063 llvm::function_ref<bool (Type, DiagnosticBehavior)> diagnose) {
10571064 auto module = fromContext.fromDC ->getParentModule ();
10581065
@@ -1064,15 +1071,17 @@ bool swift::diagnoseNonSendableTypes(
10641071 // FIXME: More detail for unavailable conformances.
10651072 auto conformance = TypeChecker::conformsToProtocol (type, proto, module );
10661073 if (conformance.isInvalid () || conformance.hasUnavailableConformance ()) {
1067- return diagnoseSingleNonSendableType (type, fromContext, loc, diagnose);
1074+ return diagnoseSingleNonSendableType (
1075+ type, fromContext, inDerivedConformance, loc, diagnose);
10681076 }
10691077
10701078 // Walk the conformance, diagnosing any missing Sendable conformances.
10711079 bool anyMissing = false ;
10721080 conformance.forEachMissingConformance (module ,
10731081 [&](BuiltinProtocolConformance *missing) {
10741082 if (diagnoseSingleNonSendableType (
1075- missing->getType (), fromContext, loc, diagnose)) {
1083+ missing->getType (), fromContext,
1084+ inDerivedConformance, loc, diagnose)) {
10761085 anyMissing = true ;
10771086 }
10781087
@@ -1095,11 +1104,27 @@ bool swift::diagnoseNonSendableTypesInReference(
10951104 return swift::getActorIsolation (declRef.getDecl ());
10961105 };
10971106
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+
10981122 // Check the 'self' argument.
10991123 if (base) {
11001124 if (diagnoseNonSendableTypes (
11011125 base->getType (),
1102- fromDC, base->getStartLoc (),
1126+ fromDC, derivedConformanceType,
1127+ base->getStartLoc (),
11031128 diag::non_sendable_param_type,
11041129 (unsigned )refKind, declRef.getDecl (),
11051130 getActorIsolation ()))
@@ -1114,7 +1139,8 @@ bool swift::diagnoseNonSendableTypesInReference(
11141139 for (auto param : *function->getParameters ()) {
11151140 Type paramType = param->getInterfaceType ().subst (subs);
11161141 if (diagnoseNonSendableTypes (
1117- paramType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1142+ paramType, fromDC, derivedConformanceType,
1143+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
11181144 diag::non_sendable_param_type,
11191145 (unsigned )refKind, function, getActorIsolation ()))
11201146 return true ;
@@ -1127,7 +1153,8 @@ bool swift::diagnoseNonSendableTypesInReference(
11271153 // only check results if funcCheckKind specifies so
11281154 Type resultType = func->getResultInterfaceType ().subst (subs);
11291155 if (diagnoseNonSendableTypes (
1130- resultType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1156+ resultType, fromDC, derivedConformanceType,
1157+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
11311158 diag::non_sendable_result_type,
11321159 (unsigned )refKind, func, getActorIsolation ()))
11331160 return true ;
@@ -1142,7 +1169,8 @@ bool swift::diagnoseNonSendableTypesInReference(
11421169 ? var->getTypeInContext ()
11431170 : var->getValueInterfaceType ().subst (subs);
11441171 if (diagnoseNonSendableTypes (
1145- propertyType, fromDC, refLoc,
1172+ propertyType, fromDC,
1173+ derivedConformanceType, refLoc,
11461174 diag::non_sendable_property_type,
11471175 var,
11481176 var->isLocalCapture (),
@@ -1157,7 +1185,8 @@ bool swift::diagnoseNonSendableTypesInReference(
11571185 // Check params of this subscript override for sendability
11581186 Type paramType = param->getInterfaceType ().subst (subs);
11591187 if (diagnoseNonSendableTypes (
1160- paramType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1188+ paramType, fromDC, derivedConformanceType,
1189+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
11611190 diag::non_sendable_param_type,
11621191 (unsigned )refKind, subscript, getActorIsolation ()))
11631192 return true ;
@@ -1168,7 +1197,8 @@ bool swift::diagnoseNonSendableTypesInReference(
11681197 // Check the element type of a subscript.
11691198 Type resultType = subscript->getElementInterfaceType ().subst (subs);
11701199 if (diagnoseNonSendableTypes (
1171- resultType, fromDC, refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
1200+ resultType, fromDC, derivedConformanceType,
1201+ refLoc, diagnoseLoc.isInvalid () ? refLoc : diagnoseLoc,
11721202 diag::non_sendable_result_type,
11731203 (unsigned )refKind, subscript, getActorIsolation ()))
11741204 return true ;
@@ -1183,7 +1213,8 @@ bool swift::diagnoseNonSendableTypesInReference(
11831213void swift::diagnoseMissingSendableConformance (
11841214 SourceLoc loc, Type type, const DeclContext *fromDC) {
11851215 diagnoseNonSendableTypes (
1186- type, fromDC, loc, diag::non_sendable_type);
1216+ type, fromDC, /* inDerivedConformance*/ Type (),
1217+ loc, diag::non_sendable_type);
11871218}
11881219
11891220namespace {
@@ -1935,7 +1966,8 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
19351966 auto *base = selfApply->getBase ();
19361967 if (diagnoseNonSendableTypes (
19371968 base->getType (),
1938- declContext, base->getStartLoc (),
1969+ declContext, /* inDerivedConformance*/ Type (),
1970+ base->getStartLoc (),
19391971 diag::non_sendable_call_argument,
19401972 isolationCrossing.value ().exitsIsolation (),
19411973 isolationCrossing.value ().getDiagnoseIsolation ()))
@@ -1976,7 +2008,8 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
19762008
19772009 if (diagnoseNonSendableTypes (
19782010 argType ? argType : param.getParameterType (),
1979- declContext, argLoc, diag::non_sendable_call_argument,
2011+ declContext, /* inDerivedConformance*/ Type (),
2012+ argLoc, diag::non_sendable_call_argument,
19802013 isolationCrossing.value ().exitsIsolation (),
19812014 isolationCrossing.value ().getDiagnoseIsolation ()))
19822015 return true ;
@@ -2418,19 +2451,24 @@ namespace {
24182451 // into async let to SIL level region based isolation.
24192452 if (!ctx.LangOpts .hasFeature (Feature::RegionBasedIsolation)) {
24202453 diagnoseNonSendableTypes (
2421- type, getDeclContext (), capture.getLoc (),
2454+ type, getDeclContext (),
2455+ /* inDerivedConformance*/ Type (), capture.getLoc (),
24222456 diag::implicit_async_let_non_sendable_capture,
24232457 decl->getName ());
24242458 }
24252459 } else {
24262460 // Fallback to a generic implicit capture missing sendable
24272461 // conformance diagnostic.
2428- diagnoseNonSendableTypes (type, getDeclContext (), capture.getLoc (),
2462+ diagnoseNonSendableTypes (type, getDeclContext (),
2463+ /* inDerivedConformance*/ Type (),
2464+ capture.getLoc (),
24292465 diag::implicit_non_sendable_capture,
24302466 decl->getName ());
24312467 }
24322468 } else {
2433- diagnoseNonSendableTypes (type, getDeclContext (), capture.getLoc (),
2469+ diagnoseNonSendableTypes (type, getDeclContext (),
2470+ /* inDerivedConformance*/ Type (),
2471+ capture.getLoc (),
24342472 diag::non_sendable_capture, decl->getName (),
24352473 /* closure=*/ closure != nullptr );
24362474 }
@@ -3341,7 +3379,9 @@ namespace {
33413379
33423380 // Check for sendability of the result type.
33433381 if (diagnoseNonSendableTypes (
3344- fnType->getResult (), getDeclContext (), apply->getLoc (),
3382+ fnType->getResult (), getDeclContext (),
3383+ /* inDerivedConformance*/ Type (),
3384+ apply->getLoc (),
33453385 diag::non_sendable_call_result_type,
33463386 apply->isImplicitlyAsync ().has_value (),
33473387 *unsatisfiedIsolation))
@@ -3483,6 +3523,7 @@ namespace {
34833523 llvm::None)) {
34843524 if (diagnoseNonSendableTypes (
34853525 component.getComponentType (), getDeclContext (),
3526+ /* inDerivedConformance*/ Type (),
34863527 component.getLoc (),
34873528 diag::non_sendable_keypath_access)) {
34883529 diagnosed = true ;
@@ -3516,6 +3557,7 @@ namespace {
35163557 auto type = getType (arg.getExpr ());
35173558 if (type && shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
35183559 diagnoseNonSendableTypes (type, getDeclContext (),
3560+ /* inDerivedConformance*/ Type (),
35193561 component.getLoc (),
35203562 diag::non_sendable_keypath_capture))
35213563 diagnosed = true ;
@@ -5163,7 +5205,8 @@ static bool checkSendableInstanceStorage(
51635205
51645206 // Check that the property type is Sendable.
51655207 diagnoseNonSendableTypes (
5166- propertyType, SendableCheckContext (dc, check), property->getLoc (),
5208+ propertyType, SendableCheckContext (dc, check),
5209+ /* inDerivedConformance*/ Type (), property->getLoc (),
51675210 [&](Type type, DiagnosticBehavior behavior) {
51685211 if (isImplicitSendableCheck (check)) {
51695212 // If this is for an externally-visible conformance, fail.
@@ -5199,7 +5242,8 @@ static bool checkSendableInstanceStorage(
51995242 // / Handle an enum associated value.
52005243 bool operator ()(EnumElementDecl *element, Type elementType) override {
52015244 diagnoseNonSendableTypes (
5202- elementType, SendableCheckContext (dc, check), element->getLoc (),
5245+ elementType, SendableCheckContext (dc, check),
5246+ /* inDerivedConformance*/ Type (), element->getLoc (),
52035247 [&](Type type, DiagnosticBehavior behavior) {
52045248 if (isImplicitSendableCheck (check)) {
52055249 // If this is for an externally-visible conformance, fail.
0 commit comments