@@ -6256,20 +6256,57 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
6256
6256
// protocol, just warn; we'll pick up the original conformance.
6257
6257
auto existingModule = diag.ExistingDC ->getParentModule ();
6258
6258
auto extendedNominal = diag.ExistingDC ->getSelfNominalTypeDecl ();
6259
- if (existingModule != dc ->getParentModule () &&
6260
- (existingModule-> getName () = =
6261
- extendedNominal-> getParentModule () ->getName () ||
6259
+ auto definingModule = extendedNominal ->getParentModule ()-> getName ();
6260
+ bool conformanceInOrigModule =
6261
+ (existingModule ->getName () == definingModule ||
6262
6262
existingModule == diag.Protocol ->getParentModule () ||
6263
- existingModule->getName ().is (" CoreGraphics" ))) {
6263
+ existingModule->getName ().is (" CoreGraphics" ));
6264
+
6265
+ // Redundant Sendable conformances are always warnings.
6266
+ auto knownProtocol = diag.Protocol ->getKnownProtocolKind ();
6267
+ bool isSendable = knownProtocol == KnownProtocolKind::Sendable;
6268
+ // Try to find an inherited Sendable conformance if there is one.
6269
+ if (isSendable && !SendableConformance) {
6270
+ SmallVector<ProtocolConformance *, 2 > conformances;
6271
+ nominal->lookupConformance (diag.Protocol , conformances);
6272
+ for (auto conformance : conformances) {
6273
+ if (isa<InheritedProtocolConformance>(conformance))
6274
+ SendableConformance = conformance;
6275
+ }
6276
+ }
6277
+
6278
+
6279
+ if ((existingModule != dc->getParentModule () && conformanceInOrigModule) ||
6280
+ isSendable) {
6264
6281
// Warn about the conformance.
6265
- auto diagID = differentlyConditional
6266
- ? diag::redundant_conformance_adhoc_conditional
6267
- : diag::redundant_conformance_adhoc;
6268
- Context.Diags .diagnose (diag.Loc , diagID, dc->getDeclaredInterfaceType (),
6269
- diag.Protocol ->getName (),
6270
- existingModule->getName () ==
6271
- extendedNominal->getParentModule ()->getName (),
6272
- existingModule->getName ());
6282
+ if (isSendable && SendableConformance &&
6283
+ isa<InheritedProtocolConformance>(SendableConformance)) {
6284
+ // Allow re-stated unchecked conformances to Sendable in subclasses
6285
+ // as long as the inherited conformance isn't unavailable.
6286
+ auto *conformance = SendableConformance->getRootConformance ();
6287
+ auto *decl = conformance->getDeclContext ()->getAsDecl ();
6288
+ if (!AvailableAttr::isUnavailable (decl)) {
6289
+ continue ;
6290
+ }
6291
+
6292
+ Context.Diags .diagnose (diag.Loc , diag::unavailable_conformance,
6293
+ nominal->getDeclaredInterfaceType (),
6294
+ diag.Protocol ->getName ());
6295
+ } else if (existingModule == dc->getParentModule ()) {
6296
+ Context.Diags .diagnose (diag.Loc , diag::redundant_conformance,
6297
+ nominal->getDeclaredInterfaceType (),
6298
+ diag.Protocol ->getName ())
6299
+ .limitBehavior (DiagnosticBehavior::Warning);
6300
+ } else {
6301
+ auto diagID = differentlyConditional
6302
+ ? diag::redundant_conformance_adhoc_conditional
6303
+ : diag::redundant_conformance_adhoc;
6304
+ Context.Diags .diagnose (diag.Loc , diagID, dc->getDeclaredInterfaceType (),
6305
+ diag.Protocol ->getName (),
6306
+ existingModule->getName () ==
6307
+ extendedNominal->getParentModule ()->getName (),
6308
+ existingModule->getName ());
6309
+ }
6273
6310
6274
6311
// Complain about any declarations in this extension whose names match
6275
6312
// a requirement in that protocol.
0 commit comments