Skip to content

Commit 7aa338e

Browse files
authored
Merge pull request swiftlang#71225 from tshortli/back-deployed-attr-refactor
AST/Sema: Adjust `@backDeployed` attribute diagnostics for unavailable decls
2 parents f5e5789 + 52abd6c commit 7aa338e

File tree

6 files changed

+46
-24
lines changed

6 files changed

+46
-24
lines changed

include/swift/AST/PlatformKind.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ llvm::Optional<StringRef> closestCorrectedPlatformString(StringRef candidate);
5151
/// for emission in diagnostics (e.g., "macOS").
5252
StringRef prettyPlatformString(PlatformKind platform);
5353

54+
/// Returns the base platform for an application-extension platform. For example
55+
/// `iOS` would be returned for `iOSApplicationExtension`. Returns `None` for
56+
/// platforms which are not application extension platforms.
57+
llvm::Optional<PlatformKind>
58+
basePlatformForExtensionPlatform(PlatformKind Platform);
59+
5460
/// Returns whether the passed-in platform is active, given the language
5561
/// options. A platform is active if either it is the target platform or its
5662
/// AppExtension variant is the target platform. For example, OS X is

lib/AST/Decl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,8 +551,10 @@ Decl::getIntroducedOSVersion(PlatformKind Kind) const {
551551

552552
llvm::Optional<llvm::VersionTuple>
553553
Decl::getBackDeployedBeforeOSVersion(ASTContext &Ctx) const {
554-
if (auto *attr = getAttrs().getBackDeployed(Ctx))
555-
return attr->Version;
554+
if (auto *attr = getAttrs().getBackDeployed(Ctx)) {
555+
auto version = attr->Version;
556+
return version;
557+
}
556558

557559
// Accessors may inherit `@backDeployed`.
558560
if (auto *AD = dyn_cast<AccessorDecl>(this))

lib/AST/PlatformKind.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,19 @@ swift::closestCorrectedPlatformString(StringRef candidate) {
8383
return (minDistance < distanceThreshold) ? result : llvm::None;
8484
}
8585

86-
static bool isApplicationExtensionPlatform(PlatformKind Platform) {
86+
llvm::Optional<PlatformKind>
87+
swift::basePlatformForExtensionPlatform(PlatformKind Platform) {
8788
switch (Platform) {
8889
case PlatformKind::macOSApplicationExtension:
90+
return PlatformKind::macOS;
8991
case PlatformKind::iOSApplicationExtension:
92+
return PlatformKind::iOS;
9093
case PlatformKind::macCatalystApplicationExtension:
94+
return PlatformKind::macCatalyst;
9195
case PlatformKind::tvOSApplicationExtension:
96+
return PlatformKind::tvOS;
9297
case PlatformKind::watchOSApplicationExtension:
93-
return true;
98+
return PlatformKind::watchOS;
9499
case PlatformKind::macOS:
95100
case PlatformKind::iOS:
96101
case PlatformKind::macCatalyst:
@@ -99,11 +104,15 @@ static bool isApplicationExtensionPlatform(PlatformKind Platform) {
99104
case PlatformKind::OpenBSD:
100105
case PlatformKind::Windows:
101106
case PlatformKind::none:
102-
return false;
107+
return llvm::None;
103108
}
104109
llvm_unreachable("bad PlatformKind");
105110
}
106111

112+
static bool isApplicationExtensionPlatform(PlatformKind Platform) {
113+
return basePlatformForExtensionPlatform(Platform).has_value();
114+
}
115+
107116
static bool isPlatformActiveForTarget(PlatformKind Platform,
108117
const llvm::Triple &Target,
109118
bool EnableAppExtensionRestrictions) {
@@ -187,20 +196,21 @@ PlatformKind swift::targetPlatform(const LangOptions &LangOpts) {
187196

188197
bool swift::inheritsAvailabilityFromPlatform(PlatformKind Child,
189198
PlatformKind Parent) {
199+
if (auto ChildPlatformBase = basePlatformForExtensionPlatform(Child)) {
200+
if (Parent == ChildPlatformBase)
201+
return true;
202+
}
203+
190204
if (Child == PlatformKind::macCatalyst && Parent == PlatformKind::iOS)
191205
return true;
192206

193207
if (Child == PlatformKind::macCatalystApplicationExtension) {
194208
if (Parent == PlatformKind::iOS ||
195-
Parent == PlatformKind::iOSApplicationExtension ||
196-
Parent == PlatformKind::macCatalyst) {
209+
Parent == PlatformKind::iOSApplicationExtension) {
197210
return true;
198211
}
199212
}
200213

201-
// Ideally we would have all ApplicationExtension platforms
202-
// inherit from their non-extension platform.
203-
204214
return false;
205215
}
206216

lib/Sema/TypeCheckAttr.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4547,11 +4547,12 @@ void AttributeChecker::checkBackDeployedAttrs(
45474547
// Unavailable decls cannot be back deployed.
45484548
if (auto unavailableAttrPair = VD->getSemanticUnavailableAttr()) {
45494549
auto unavailableAttr = unavailableAttrPair.value().first;
4550+
if (!inheritsAvailabilityFromPlatform(unavailableAttr->Platform,
4551+
Attr->Platform)) {
4552+
auto platformString = prettyPlatformString(Attr->Platform);
45504553

4551-
if (unavailableAttr->Platform == PlatformKind::none ||
4552-
unavailableAttr->Platform == Attr->Platform) {
4553-
diagnose(AtLoc, diag::attr_has_no_effect_on_unavailable_decl, Attr,
4554-
VD, prettyPlatformString(Platform));
4554+
diagnose(AtLoc, diag::attr_has_no_effect_on_unavailable_decl, Attr, VD,
4555+
platformString);
45554556
diagnose(unavailableAttr->AtLoc, diag::availability_marked_unavailable,
45564557
VD)
45574558
.highlight(unavailableAttr->getRange());
@@ -4563,14 +4564,17 @@ void AttributeChecker::checkBackDeployedAttrs(
45634564
// If it's not, the attribute doesn't make sense since the back deployment
45644565
// fallback could never be executed at runtime.
45654566
if (auto availableRangeAttrPair = VD->getSemanticAvailableRangeAttr()) {
4567+
auto beforePlatformString = prettyPlatformString(Attr->Platform);
4568+
auto beforeVersion = Attr->Version;
45664569
auto availableAttr = availableRangeAttrPair.value().first;
4567-
if (Attr->Version <= availableAttr->Introduced.value()) {
4570+
auto introVersion = availableAttr->Introduced.value();
4571+
StringRef introPlatformString = availableAttr->prettyPlatformString();
4572+
4573+
if (Attr->Version <= introVersion) {
45684574
diagnose(AtLoc, diag::attr_has_no_effect_decl_not_available_before,
4569-
Attr, VD, prettyPlatformString(Platform),
4570-
Attr->Version);
4575+
Attr, VD, beforePlatformString, beforeVersion);
45714576
diagnose(availableAttr->AtLoc, diag::availability_introduced_in_version,
4572-
VD, prettyPlatformString(availableAttr->Platform),
4573-
*availableAttr->Introduced)
4577+
VD, introPlatformString, introVersion)
45744578
.highlight(availableAttr->getRange());
45754579
continue;
45764580
}

test/attr/attr_availability_transitive_ios_appext.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
func ios() {} // expected-note 2{{'ios()' has been explicitly marked unavailable here}}
99

1010
@available(iOSApplicationExtension, unavailable)
11-
func ios_extension() {} // expected-note 2{{'ios_extension()' has been explicitly marked unavailable here}}
11+
func ios_extension() {} // expected-note {{'ios_extension()' has been explicitly marked unavailable here}}
1212

1313
func call_ios_extension() {
1414
ios_extension() // expected-error {{'ios_extension()' is unavailable}}
@@ -19,7 +19,7 @@ func call_ios() {
1919

2020
@available(iOS, unavailable)
2121
func ios_call_ios_extension() {
22-
ios_extension() // expected-error {{'ios_extension()' is unavailable}}
22+
ios_extension()
2323
}
2424

2525
@available(iOS, unavailable)

test/attr/attr_availability_transitive_osx_appext.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
func osx() {} // expected-note 3{{'osx()' has been explicitly marked unavailable here}}
88

99
@available(OSXApplicationExtension, unavailable)
10-
func osx_extension() {} // expected-note 3{{'osx_extension()' has been explicitly marked unavailable here}}
10+
func osx_extension() {} // expected-note {{'osx_extension()' has been explicitly marked unavailable here}}
1111

1212
func call_osx_extension() {
1313
osx_extension() // expected-error {{'osx_extension()' is unavailable}}
@@ -18,7 +18,7 @@ func call_osx() {
1818

1919
@available(OSX, unavailable)
2020
func osx_call_osx_extension() {
21-
osx_extension() // expected-error {{'osx_extension()' is unavailable}}
21+
osx_extension()
2222
}
2323

2424
@available(OSX, unavailable)
@@ -46,7 +46,7 @@ extension NotOnOSX {
4646
}
4747

4848
func osx_call_osx_extension() {
49-
osx_extension() // expected-error {{'osx_extension()' is unavailable in application extensions for macOS}}
49+
osx_extension()
5050
}
5151
}
5252

0 commit comments

Comments
 (0)