1818
1919#include " swift/AST/ASTContext.h"
2020#include " swift/AST/ASTWalker.h"
21+ #include " swift/AST/AvailabilityConstraint.h"
2122#include " swift/AST/AvailabilityInference.h"
2223#include " swift/AST/AvailabilitySpec.h"
2324#include " swift/AST/Decl.h"
@@ -461,10 +462,17 @@ class AvailabilityScopeBuilder : private ASTWalker {
461462 // As a convenience, explicitly unavailable decls are constrained to the
462463 // deployment target. There's not much benefit to checking these decls at a
463464 // lower availability version floor since they can't be invoked by clients.
464- if ( getCurrentScope ()->getAvailabilityContext (). isUnavailable () ||
465- decl-> isUnavailable ())
465+ auto context = getCurrentScope ()->getAvailabilityContext ();
466+ if (context. isUnavailable ())
466467 return true ;
467468
469+ // Check whether the decl is unavailable relative to the current context.
470+ if (auto constraint = getAvailabilityConstraintsForDecl (decl, context)
471+ .getPrimaryConstraint ()) {
472+ if (constraint->isUnavailable ())
473+ return true ;
474+ }
475+
468476 // To remain compatible with a lot of existing SPIs that are declared
469477 // without availability attributes, constrain them to the deployment target
470478 // too.
@@ -584,8 +592,7 @@ class AvailabilityScopeBuilder : private ASTWalker {
584592 }
585593
586594 void buildContextsForBodyOfDecl (Decl *decl) {
587- // Are we already constrained by the deployment target and the declaration
588- // doesn't explicitly allow unsafe constructs in its definition, adding
595+ // If we are already constrained by the deployment target then adding
589596 // new contexts won't change availability.
590597 if (isCurrentScopeContainedByDeploymentTarget ())
591598 return ;
@@ -599,8 +606,10 @@ class AvailabilityScopeBuilder : private ASTWalker {
599606 // Apply deployment-target availability if appropriate for this body.
600607 if (!isCurrentScopeContainedByDeploymentTarget () &&
601608 bodyIsDeploymentTarget (decl)) {
602- availability.constrainWithPlatformRange (
603- AvailabilityRange::forDeploymentTarget (Context), Context);
609+ // Also constrain availability with the decl itself to handle the case
610+ // where the decl becomes obsolete at the deployment target.
611+ availability.constrainWithDeclAndPlatformRange (
612+ decl, AvailabilityRange::forDeploymentTarget (Context));
604613 }
605614
606615 nodesAndScopes.push_back (
0 commit comments