18
18
19
19
#include " swift/AST/ASTContext.h"
20
20
#include " swift/AST/ASTWalker.h"
21
+ #include " swift/AST/AvailabilityConstraint.h"
21
22
#include " swift/AST/AvailabilityInference.h"
22
23
#include " swift/AST/AvailabilitySpec.h"
23
24
#include " swift/AST/Decl.h"
@@ -461,10 +462,17 @@ class AvailabilityScopeBuilder : private ASTWalker {
461
462
// As a convenience, explicitly unavailable decls are constrained to the
462
463
// deployment target. There's not much benefit to checking these decls at a
463
464
// 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 ())
466
467
return true ;
467
468
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
+
468
476
// To remain compatible with a lot of existing SPIs that are declared
469
477
// without availability attributes, constrain them to the deployment target
470
478
// too.
@@ -584,8 +592,7 @@ class AvailabilityScopeBuilder : private ASTWalker {
584
592
}
585
593
586
594
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
589
596
// new contexts won't change availability.
590
597
if (isCurrentScopeContainedByDeploymentTarget ())
591
598
return ;
@@ -599,8 +606,10 @@ class AvailabilityScopeBuilder : private ASTWalker {
599
606
// Apply deployment-target availability if appropriate for this body.
600
607
if (!isCurrentScopeContainedByDeploymentTarget () &&
601
608
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));
604
613
}
605
614
606
615
nodesAndScopes.push_back (
0 commit comments