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