Skip to content

Commit 560328f

Browse files
committed
AST: Get SPI status of PatternBindingDecl from anchoring VarDecl.
For property declarations, the `@_spi` attribute is attached to the VarDecl AST node, rather than the PatternBindingDecl AST node, so the `isSPI()` query should take this into account. Failing to do so caused the availability checker to erroneously require that `@_spi` properties of types in `-library-level api` libraries have availability annotations. Resolves rdar://113587321.
1 parent bf2e5ac commit 560328f

File tree

3 files changed

+81
-4
lines changed

3 files changed

+81
-4
lines changed

lib/AST/Availability.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,8 @@ ASTContext::getSwift5PlusAvailability(llvm::VersionTuple swiftVersion) {
747747
swiftVersion.getAsString());
748748
}
749749

750+
// FIXME: Rename abstractSyntaxDeclForAvailableAttribute since it's useful
751+
// for more attributes than `@available`.
750752
const Decl *
751753
swift::abstractSyntaxDeclForAvailableAttribute(const Decl *ConcreteSyntaxDecl) {
752754
// This function needs to be kept in sync with its counterpart,

lib/AST/Module.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3480,12 +3480,14 @@ bool Decl::isSPI() const {
34803480
}
34813481

34823482
ArrayRef<Identifier> Decl::getSPIGroups() const {
3483-
if (!isa<ValueDecl>(this) &&
3484-
!isa<ExtensionDecl>(this))
3483+
const Decl *D = abstractSyntaxDeclForAvailableAttribute(this);
3484+
3485+
if (!isa<ValueDecl>(D) &&
3486+
!isa<ExtensionDecl>(D))
34853487
return ArrayRef<Identifier>();
34863488

34873489
return evaluateOrDefault(getASTContext().evaluator,
3488-
SPIGroupsRequest{ this },
3490+
SPIGroupsRequest{ D },
34893491
ArrayRef<Identifier>());
34903492
}
34913493

test/attr/attr_inlinable_available.swift

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ public struct PropertyWrapper<T> {
743743
public init(_ value: T) { self.wrappedValue = value }
744744
}
745745

746-
public struct PublicStruct { // expected-note 13 {{add @available attribute}}
746+
public struct PublicStruct { // expected-note 15 {{add @available attribute}}
747747
// Public property declarations are exposed.
748748
public var aPublic: NoAvailable,
749749
bPublic: BeforeInliningTarget,
@@ -760,6 +760,44 @@ public struct PublicStruct { // expected-note 13 {{add @available attribute}}
760760
ePublicAvailBetween: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
761761
fPublicAvailBetween: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
762762

763+
@_spi(Private)
764+
public var aSPI: NoAvailable,
765+
bSPI: BeforeInliningTarget,
766+
cSPI: AtInliningTarget,
767+
dSPI: BetweenTargets,
768+
eSPI: AtDeploymentTarget,
769+
fSPI: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
770+
771+
@available(macOS, unavailable)
772+
public var aUnavailable: NoAvailable {
773+
NoAvailable()
774+
}
775+
776+
@available(macOS, unavailable)
777+
public var bUnavailable: BeforeInliningTarget {
778+
BeforeInliningTarget()
779+
}
780+
781+
@available(macOS, unavailable)
782+
public var cUnavailable: AtInliningTarget {
783+
AtInliningTarget()
784+
}
785+
786+
@available(macOS, unavailable)
787+
public var dUnavailable: BetweenTargets {
788+
BetweenTargets()
789+
}
790+
791+
@available(macOS, unavailable)
792+
public var eUnavailable: AtDeploymentTarget {
793+
AtDeploymentTarget()
794+
}
795+
796+
@available(macOS, unavailable)
797+
public var fUnavailable: AfterDeploymentTarget {
798+
AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available' version check}}
799+
}
800+
763801
// The inferred types of public properties are exposed.
764802
public var aPublicInferred = NoAvailable(),
765803
bPublicInferred = BeforeInliningTarget(),
@@ -1357,6 +1395,41 @@ enum InternalNoAvailableEnumWithTypeAliases { // expected-note {{add @available
13571395
public typealias F = AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add @available attribute to enclosing type alias}}
13581396
}
13591397

1398+
// MARK: - Enums with payloads
1399+
1400+
public enum PublicNoAvailableEnumWithPayloads { // expected-note 5 {{add @available attribute to enclosing enum}}
1401+
case aNoAvailable(NoAvailable),
1402+
bNoAvailable(BeforeInliningTarget),
1403+
cNoAvailable(AtInliningTarget),
1404+
dNoAvailable(BetweenTargets), // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
1405+
eNoAvailable(AtDeploymentTarget), // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
1406+
fNoAvailable(AfterDeploymentTarget) // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
1407+
1408+
@available(macOS, introduced: 10.15)
1409+
case aAtDeploymentTarget(NoAvailable),
1410+
bAtDeploymentTarget(BeforeInliningTarget),
1411+
cAtDeploymentTarget(AtInliningTarget),
1412+
dAtDeploymentTarget(BetweenTargets),
1413+
eAtDeploymentTarget(AtDeploymentTarget),
1414+
fAtDeploymentTarget(AfterDeploymentTarget) // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
1415+
1416+
@_spi(Private)
1417+
case aSPI(NoAvailable),
1418+
bSPI(BeforeInliningTarget),
1419+
cSPI(AtInliningTarget),
1420+
dSPI(BetweenTargets),
1421+
eSPI(AtDeploymentTarget),
1422+
fSPI(AfterDeploymentTarget) // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
1423+
1424+
@available(macOS, unavailable)
1425+
case aUnavailable(NoAvailable),
1426+
bUnavailable(BeforeInliningTarget),
1427+
cUnavailable(AtInliningTarget),
1428+
dUnavailable(BetweenTargets),
1429+
eUnavailable(AtDeploymentTarget),
1430+
fUnavailable(AfterDeploymentTarget)
1431+
}
1432+
13601433
// MARK: - Class inheritance
13611434

13621435
// FIXME: Duplicate 'add @available' emitted when classes are nested in a decl

0 commit comments

Comments
 (0)