@@ -6256,20 +6256,56 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
62566256 // protocol, just warn; we'll pick up the original conformance.
62576257 auto existingModule = diag.ExistingDC ->getParentModule ();
62586258 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 ||
62626262 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+ if ((existingModule != dc->getParentModule () && conformanceInOrigModule) ||
6279+ isSendable) {
62646280 // 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 ());
6281+ if (isSendable && SendableConformance &&
6282+ isa<InheritedProtocolConformance>(SendableConformance)) {
6283+ // Allow re-stated unchecked conformances to Sendable in subclasses
6284+ // as long as the inherited conformance isn't unavailable.
6285+ auto *conformance = SendableConformance->getRootConformance ();
6286+ auto *decl = conformance->getDeclContext ()->getAsDecl ();
6287+ if (!AvailableAttr::isUnavailable (decl)) {
6288+ continue ;
6289+ }
6290+
6291+ Context.Diags .diagnose (diag.Loc , diag::unavailable_conformance,
6292+ nominal->getDeclaredInterfaceType (),
6293+ diag.Protocol ->getName ());
6294+ } else if (existingModule == dc->getParentModule ()) {
6295+ Context.Diags .diagnose (diag.Loc , diag::redundant_conformance,
6296+ nominal->getDeclaredInterfaceType (),
6297+ diag.Protocol ->getName ())
6298+ .limitBehavior (DiagnosticBehavior::Warning);
6299+ } else {
6300+ auto diagID = differentlyConditional
6301+ ? diag::redundant_conformance_adhoc_conditional
6302+ : diag::redundant_conformance_adhoc;
6303+ Context.Diags .diagnose (diag.Loc , diagID, dc->getDeclaredInterfaceType (),
6304+ diag.Protocol ->getName (),
6305+ existingModule->getName () ==
6306+ extendedNominal->getParentModule ()->getName (),
6307+ existingModule->getName ());
6308+ }
62736309
62746310 // Complain about any declarations in this extension whose names match
62756311 // a requirement in that protocol.
0 commit comments