@@ -6256,20 +6256,56 @@ 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
+ if ((existingModule != dc->getParentModule () && conformanceInOrigModule) ||
6279
+ isSendable) {
6264
6280
// 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
+ }
6273
6309
6274
6310
// Complain about any declarations in this extension whose names match
6275
6311
// a requirement in that protocol.
0 commit comments