@@ -5097,23 +5097,10 @@ void AttributeChecker::checkAvailableAttrs(ArrayRef<AvailableAttr *> attrs) {
50975097 if (availabilityConstraint->isUnavailable ()) {
50985098 auto attr = availabilityConstraint->getAttr ();
50995099 if (auto diag = TypeChecker::diagnosticIfDeclCannotBeUnavailable (D)) {
5100- diagnose (attr.getParsedAttr ()->getLocation (), diag.value ());
5100+ diagnoseAndRemoveAttr (const_cast <AvailableAttr *>(attr.getParsedAttr ()),
5101+ diag.value ());
51015102 return ;
51025103 }
5103-
5104- if (auto *PD = dyn_cast<ProtocolDecl>(D->getDeclContext ())) {
5105- if (auto *VD = dyn_cast<ValueDecl>(D)) {
5106- if (VD->isProtocolRequirement () && !PD->isObjC ()) {
5107- diagnoseAndRemoveAttr (
5108- const_cast <AvailableAttr *>(attr.getParsedAttr ()),
5109- diag::unavailable_method_non_objc_protocol)
5110- .warnInSwiftInterface (D->getDeclContext ());
5111- // Be lenient in interfaces to accomodate @_spi_available, which has
5112- // been accepted historically.
5113- return ;
5114- }
5115- }
5116- }
51175104 }
51185105
51195106 // If the decl is potentially unavailable relative to its parent and it's
@@ -5484,6 +5471,21 @@ TypeChecker::diagnosticIfDeclCannotBeUnavailable(const Decl *D) {
54845471 return Diagnostic (diag::availability_decl_no_unavailable, D);
54855472 }
54865473
5474+ auto DC = D->getDeclContext ();
5475+ if (auto *PD = dyn_cast<ProtocolDecl>(DC)) {
5476+ if (auto *VD = dyn_cast<ValueDecl>(D)) {
5477+ if (VD->isProtocolRequirement () && !PD->isObjC ()) {
5478+ auto diag = Diagnostic (diag::unavailable_method_non_objc_protocol);
5479+
5480+ // Be lenient in interfaces to accomodate @_spi_available, which has
5481+ // been accepted historically.
5482+ if (DC->isInSwiftinterface ())
5483+ diag.setBehaviorLimit (DiagnosticBehavior::Warning);
5484+ return diag;
5485+ }
5486+ }
5487+ }
5488+
54875489 if (auto *VD = dyn_cast<VarDecl>(D)) {
54885490 if (!VD->hasStorageOrWrapsStorage ())
54895491 return std::nullopt ;
0 commit comments