@@ -608,6 +608,41 @@ void RewriteSystem::verifyRewriteRules(ValidityPolicy policy) const {
608608#undef ASSERT_RULE
609609}
610610
611+ // / Determine whether this is a redundantly inheritable Objective-C protocol.
612+ // /
613+ // / A redundantly-inheritable Objective-C protocol is one where we will
614+ // / silently accept a directly-stated redundant conformance to this protocol,
615+ // / and emit this protocol in the list of "inherited" protocols. There are
616+ // / two cases where we allow this:
617+ // /
618+ // 1) For a protocol defined in Objective-C, so that we will match Clang's
619+ // / behavior, and
620+ // / 2) For an @objc protocol defined in Swift that directly inherits from
621+ // / JavaScriptCore's JSExport, which depends on this behavior.
622+ static bool isRedundantlyInheritableObjCProtocol (const ProtocolDecl *inheritingProto,
623+ const ProtocolDecl *proto) {
624+ if (!proto->isObjC ()) return false ;
625+
626+ // Check the two conditions in which we will suppress the diagnostic and
627+ // emit the redundant inheritance.
628+ if (!inheritingProto->hasClangNode () && !proto->getName ().is (" JSExport" ))
629+ return false ;
630+
631+ // If the inheriting protocol already has @_restatedObjCConformance with
632+ // this protocol, we're done.
633+ for (auto *attr : inheritingProto->getAttrs ()
634+ .getAttributes <RestatedObjCConformanceAttr>()) {
635+ if (attr->Proto == proto) return true ;
636+ }
637+
638+ // Otherwise, add @_restatedObjCConformance.
639+ auto &ctx = proto->getASTContext ();
640+ const_cast <ProtocolDecl *>(inheritingProto)
641+ ->getAttrs ().add (new (ctx) RestatedObjCConformanceAttr (
642+ const_cast <ProtocolDecl *>(proto)));
643+ return true ;
644+ }
645+
611646// / Computes the set of explicit redundant requirements to
612647// / emit warnings for in the source code.
613648void RewriteSystem::computeRedundantRequirementDiagnostics (
@@ -689,8 +724,18 @@ void RewriteSystem::computeRedundantRequirementDiagnostics(
689724 auto isRedundantRule = [&](unsigned ruleID) {
690725 const auto &rule = getRules ()[ruleID];
691726
692- return (rule.isRedundant () &&
693- nonExplicitNonRedundantRules.count (ruleID) == 0 );
727+ if (!rule.isRedundant ())
728+ return false ;
729+
730+ if (nonExplicitNonRedundantRules.count (ruleID) > 0 )
731+ return false ;
732+
733+ if (rule.isProtocolRefinementRule (Context) &&
734+ isRedundantlyInheritableObjCProtocol (rule.getLHS ()[0 ].getProtocol (),
735+ rule.getLHS ()[1 ].getProtocol ()))
736+ return false ;
737+
738+ return true ;
694739 };
695740
696741 // Finally walk through the written requirements, diagnosing any that are
0 commit comments