Skip to content

Commit 7311886

Browse files
authored
Merge pull request #24334 from brentdax/wherefore-art-thou-api
[TypeChecker] Rephrase platforms in availability diagnostics
2 parents cb94753 + 3494c0b commit 7311886

19 files changed

+325
-316
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3986,8 +3986,9 @@ ERROR(dynamic_replacement_replaced_constructor_is_not_convenience, none,
39863986
//------------------------------------------------------------------------------
39873987

39883988
ERROR(availability_decl_unavailable, none,
3989-
"%select{getter for |setter for |}0%1 is unavailable",
3990-
(unsigned, DeclName))
3989+
"%select{getter for |setter for |}0%1 is unavailable"
3990+
"%select{ in %3|}2",
3991+
(unsigned, DeclName, bool, StringRef))
39913992

39923993
#define REPLACEMENT_DECL_KIND_SELECT "select{| instance method| property}"
39933994
ERROR(availability_decl_unavailable_rename, none,
@@ -4003,16 +4004,9 @@ ERROR(availability_decl_unavailable_rename_msg, none,
40034004
(unsigned, DeclName, bool, unsigned, StringRef, StringRef))
40044005

40054006
ERROR(availability_decl_unavailable_msg, none,
4006-
"%select{getter for |setter for |}0%1 is unavailable: %2",
4007-
(unsigned, DeclName, StringRef))
4008-
4009-
ERROR(availability_decl_unavailable_in_swift, none,
4010-
"%select{getter for |setter for |}0%1 is unavailable in Swift",
4011-
(unsigned, DeclName))
4012-
4013-
ERROR(availability_decl_unavailable_in_swift_msg, none,
4014-
"%select{getter for |setter for |}0%1 is unavailable in Swift: %2",
4015-
(unsigned, DeclName, StringRef))
4007+
"%select{getter for |setter for |}0%1 is unavailable"
4008+
"%select{ in %3|}2: %4",
4009+
(unsigned, DeclName, bool, StringRef, StringRef))
40164010

40174011
NOTE(availability_marked_unavailable, none,
40184012
"%select{getter for |setter for |}0%1 has been explicitly marked "
@@ -4028,18 +4022,18 @@ NOTE(availability_obsoleted, none,
40284022

40294023
WARNING(availability_deprecated, none,
40304024
"%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 "
4031-
"deprecated%select{| %select{on|in}4 %3%select{| %5}4}2",
4025+
"deprecated%select{| in %3%select{| %5}4}2",
40324026
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple))
40334027

40344028
WARNING(availability_deprecated_msg, none,
40354029
"%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 "
4036-
"deprecated%select{| %select{on|in}4 %3%select{| %5}4}2: %6",
4030+
"deprecated%select{| in %3%select{| %5}4}2: %6",
40374031
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple,
40384032
StringRef))
40394033

40404034
WARNING(availability_deprecated_rename, none,
40414035
"%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 "
4042-
"deprecated%select{| %select{on|in}4 %3%select{| %5}4}2: "
4036+
"deprecated%select{| in %3%select{| %5}4}2: "
40434037
"%select{renamed to|replaced by}6%" REPLACEMENT_DECL_KIND_SELECT "7 "
40444038
"'%8'",
40454039
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple, bool,
@@ -4056,7 +4050,7 @@ NOTE(availability_decl_more_than_enclosing_enclosing_here, none,
40564050
"enclosing scope here", ())
40574051

40584052
ERROR(availability_decl_only_version_newer, none,
4059-
"%0 is only available on %1 %2 or newer",
4053+
"%0 is only available in %1 %2 or newer",
40604054
(DeclName, StringRef, llvm::VersionTuple))
40614055

40624056
NOTE(availability_guard_with_version_check, none,
@@ -4066,13 +4060,13 @@ NOTE(availability_add_attribute, none,
40664060
"add @available attribute to enclosing %0", (DescriptiveDeclKind))
40674061

40684062
ERROR(availability_accessor_only_version_newer, none,
4069-
"%select{getter|setter}0 for %1 is only available on %2 %3"
4063+
"%select{getter|setter}0 for %1 is only available in %2 %3"
40704064
" or newer",
40714065
(/*AccessorKind*/unsigned, DeclName, StringRef, llvm::VersionTuple))
40724066

40734067
ERROR(availability_inout_accessor_only_version_newer, none,
40744068
"cannot pass as inout because %select{getter|setter}0 for %1 is only "
4075-
"available on %2 %3 or newer",
4069+
"available in %2 %3 or newer",
40764070
(/*AccessorKind*/unsigned, DeclName, StringRef, llvm::VersionTuple))
40774071

40784072
ERROR(availability_query_required_for_platform, none,
@@ -4094,7 +4088,7 @@ ERROR(availability_stored_property_no_potential,
40944088
"'@available'", ())
40954089

40964090
ERROR(availability_protocol_requires_version,
4097-
none, "protocol %0 requires %1 to be available on %2 %3 and newer",
4091+
none, "protocol %0 requires %1 to be available in %2 %3 and newer",
40984092
(DeclName, DeclName, StringRef, llvm::VersionTuple))
40994093

41004094
NOTE(availability_protocol_requirement_here, none,

include/swift/AST/PlatformKind.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ StringRef platformString(PlatformKind platform);
4141
Optional<PlatformKind> platformFromString(StringRef Name);
4242

4343
/// Returns a human-readable version of the platform name as a string, suitable
44-
/// for emission in diagnostics (e.g., "OS X").
44+
/// for emission in diagnostics (e.g., "macOS").
4545
StringRef prettyPlatformString(PlatformKind platform);
4646

4747
/// Returns whether the passed-in platform is active, given the language

include/swift/AST/PlatformKinds.def

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
AVAILABILITY_PLATFORM(iOS, "iOS")
2626
AVAILABILITY_PLATFORM(tvOS, "tvOS")
2727
AVAILABILITY_PLATFORM(watchOS, "watchOS")
28-
AVAILABILITY_PLATFORM(OSX, "OS X")
29-
AVAILABILITY_PLATFORM(iOSApplicationExtension, "iOS application extension")
30-
AVAILABILITY_PLATFORM(tvOSApplicationExtension, "tvOS application extension")
31-
AVAILABILITY_PLATFORM(watchOSApplicationExtension, "watchOS application extension")
32-
AVAILABILITY_PLATFORM(OSXApplicationExtension, "OS X application extension")
28+
AVAILABILITY_PLATFORM(OSX, "macOS")
29+
AVAILABILITY_PLATFORM(iOSApplicationExtension, "application extensions for iOS")
30+
AVAILABILITY_PLATFORM(tvOSApplicationExtension, "application extensions for tvOS")
31+
AVAILABILITY_PLATFORM(watchOSApplicationExtension, "application extensions for watchOS")
32+
AVAILABILITY_PLATFORM(OSXApplicationExtension, "application extensions for macOS")
3333

3434
#undef AVAILABILITY_PLATFORM

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,64 +2114,74 @@ bool swift::diagnoseExplicitUnavailability(
21142114

21152115
ASTContext &ctx = D->getASTContext();
21162116
auto &diags = ctx.Diags;
2117+
2118+
StringRef platform;
21172119
switch (Attr->getPlatformAgnosticAvailability()) {
21182120
case PlatformAgnosticAvailabilityKind::Deprecated:
2119-
break;
2121+
llvm_unreachable("shouldn't see deprecations in explicit unavailability");
21202122

21212123
case PlatformAgnosticAvailabilityKind::None:
21222124
case PlatformAgnosticAvailabilityKind::Unavailable:
2125+
if (Attr->Platform != PlatformKind::none) {
2126+
// This was platform-specific; indicate the platform.
2127+
platform = Attr->prettyPlatformString();
2128+
break;
2129+
}
2130+
LLVM_FALLTHROUGH;
2131+
21232132
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
21242133
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
2125-
case PlatformAgnosticAvailabilityKind::UnavailableInSwift: {
2126-
bool inSwift = (Attr->getPlatformAgnosticAvailability() ==
2127-
PlatformAgnosticAvailabilityKind::UnavailableInSwift);
2128-
2129-
if (!Attr->Rename.empty()) {
2130-
SmallString<32> newNameBuf;
2131-
Optional<ReplacementDeclKind> replaceKind =
2132-
describeRename(ctx, Attr, D, newNameBuf);
2133-
unsigned rawReplaceKind = static_cast<unsigned>(
2134-
replaceKind.getValueOr(ReplacementDeclKind::None));
2135-
StringRef newName = replaceKind ? newNameBuf.str() : Attr->Rename;
2136-
2137-
if (Attr->Message.empty()) {
2138-
auto diag = diags.diagnose(Loc,
2139-
diag::availability_decl_unavailable_rename,
2140-
RawAccessorKind, Name,
2141-
replaceKind.hasValue(),
2142-
rawReplaceKind, newName);
2143-
attachRenameFixIts(diag);
2144-
} else {
2145-
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
2146-
auto diag =
2147-
diags.diagnose(Loc, diag::availability_decl_unavailable_rename_msg,
2148-
RawAccessorKind, Name, replaceKind.hasValue(),
2149-
rawReplaceKind, newName, EncodedMessage.Message);
2150-
attachRenameFixIts(diag);
2151-
}
2152-
} else if (isSubscriptReturningString(D, ctx)) {
2153-
diags.diagnose(Loc, diag::availabilty_string_subscript_migration)
2154-
.highlight(R)
2155-
.fixItInsert(R.Start, "String(")
2156-
.fixItInsertAfter(R.End, ")");
2134+
// We don't want to give further detail about these.
2135+
platform = "";
2136+
break;
21572137

2158-
// Skip the note emitted below.
2159-
return true;
2160-
} else if (Attr->Message.empty()) {
2161-
diags.diagnose(Loc, inSwift ? diag::availability_decl_unavailable_in_swift
2162-
: diag::availability_decl_unavailable,
2163-
RawAccessorKind, Name)
2164-
.highlight(R);
2165-
} else {
2166-
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
2167-
diags.diagnose(Loc,
2168-
inSwift ? diag::availability_decl_unavailable_in_swift_msg
2169-
: diag::availability_decl_unavailable_msg,
2170-
RawAccessorKind, Name, EncodedMessage.Message)
2171-
.highlight(R);
2172-
}
2138+
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
2139+
// This API is explicitly unavailable in Swift.
2140+
platform = "Swift";
21732141
break;
21742142
}
2143+
2144+
if (!Attr->Rename.empty()) {
2145+
SmallString<32> newNameBuf;
2146+
Optional<ReplacementDeclKind> replaceKind =
2147+
describeRename(ctx, Attr, D, newNameBuf);
2148+
unsigned rawReplaceKind = static_cast<unsigned>(
2149+
replaceKind.getValueOr(ReplacementDeclKind::None));
2150+
StringRef newName = replaceKind ? newNameBuf.str() : Attr->Rename;
2151+
2152+
if (Attr->Message.empty()) {
2153+
auto diag = diags.diagnose(Loc,
2154+
diag::availability_decl_unavailable_rename,
2155+
RawAccessorKind, Name,
2156+
replaceKind.hasValue(),
2157+
rawReplaceKind, newName);
2158+
attachRenameFixIts(diag);
2159+
} else {
2160+
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
2161+
auto diag =
2162+
diags.diagnose(Loc, diag::availability_decl_unavailable_rename_msg,
2163+
RawAccessorKind, Name, replaceKind.hasValue(),
2164+
rawReplaceKind, newName, EncodedMessage.Message);
2165+
attachRenameFixIts(diag);
2166+
}
2167+
} else if (isSubscriptReturningString(D, ctx)) {
2168+
diags.diagnose(Loc, diag::availabilty_string_subscript_migration)
2169+
.highlight(R)
2170+
.fixItInsert(R.Start, "String(")
2171+
.fixItInsertAfter(R.End, ")");
2172+
2173+
// Skip the note emitted below.
2174+
return true;
2175+
} else if (Attr->Message.empty()) {
2176+
diags.diagnose(Loc, diag::availability_decl_unavailable,
2177+
RawAccessorKind, Name, platform.empty(), platform)
2178+
.highlight(R);
2179+
} else {
2180+
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
2181+
diags.diagnose(Loc, diag::availability_decl_unavailable_msg,
2182+
RawAccessorKind, Name, platform.empty(), platform,
2183+
EncodedMessage.Message)
2184+
.highlight(R);
21752185
}
21762186

21772187
switch (Attr->getVersionAvailability(ctx)) {
@@ -2205,7 +2215,7 @@ bool swift::diagnoseExplicitUnavailability(
22052215
} else if (Attr->isPackageDescriptionVersionSpecific()) {
22062216
platformDisplayString = "PackageDescription";
22072217
} else {
2208-
platformDisplayString = Attr->prettyPlatformString();
2218+
platformDisplayString = platform;
22092219
}
22102220

22112221
diags.diagnose(D, diag::availability_obsoleted,
@@ -2642,7 +2652,7 @@ AvailabilityWalker::diagnoseIncDecRemoval(const ValueDecl *D, SourceRange R,
26422652

26432653
// If we emit a deprecation diagnostic, produce a fixit hint as well.
26442654
auto diag = TC.diagnose(R.Start, diag::availability_decl_unavailable_msg,
2645-
RawAccessorKind, Name,
2655+
RawAccessorKind, Name, true, "",
26462656
"it has been removed in Swift 3");
26472657
if (isa<PrefixUnaryExpr>(call)) {
26482658
// Prefix: remove the ++ or --.
@@ -2693,7 +2703,8 @@ AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,
26932703

26942704
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
26952705
auto diag = TC.diagnose(R.Start, diag::availability_decl_unavailable_msg,
2696-
RawAccessorKind, Name, EncodedMessage.Message);
2706+
RawAccessorKind, Name, true, "",
2707+
EncodedMessage.Message);
26972708
diag.highlight(R);
26982709

26992710
auto subject = args->getSubExpr();
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -application-extension %s
22

3+
// Check the exact error message, which requires a regex match
4+
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -application-extension %s 2>&1 | %FileCheck %s
5+
36
// REQUIRES: objc_interop
47

58
import Foundation
69

710
func test_unavailable_app_extension() {
8-
_ = SomeCrazyAppExtensionForbiddenAPI() // expected-error {{'SomeCrazyAppExtensionForbiddenAPI()' is unavailable: Not available in App Extensions}}
11+
_ = SomeCrazyAppExtensionForbiddenAPI() // expected-error {{unavailable}}
12+
// CHECK: error: 'SomeCrazyAppExtensionForbiddenAPI()' is unavailable in application extensions for {{[a-z]+}}OS: Not available in App Extensions
913
}

test/ClangImporter/availability_implicit_macosx.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ func useClassThatTriggersImportOfPotentiallyUnavailableOptions() {
2929
}
3030

3131
func directUseShouldStillTriggerDeprecationWarning() {
32-
_ = NSDeprecatedOptions.first // expected-warning {{'NSDeprecatedOptions' was deprecated in OS X 10.51: Use a different API}}
33-
_ = NSDeprecatedEnum.first // expected-warning {{'NSDeprecatedEnum' was deprecated in OS X 10.51: Use a different API}}
32+
_ = NSDeprecatedOptions.first // expected-warning {{'NSDeprecatedOptions' was deprecated in macOS 10.51: Use a different API}}
33+
_ = NSDeprecatedEnum.first // expected-warning {{'NSDeprecatedEnum' was deprecated in macOS 10.51: Use a different API}}
3434
}
3535

36-
func useInSignature(_ options: NSDeprecatedOptions) { // expected-warning {{'NSDeprecatedOptions' was deprecated in OS X 10.51: Use a different API}}
36+
func useInSignature(_ options: NSDeprecatedOptions) { // expected-warning {{'NSDeprecatedOptions' was deprecated in macOS 10.51: Use a different API}}
3737
}
3838

3939
class SuperClassWithDeprecatedInitializer {
@@ -49,15 +49,15 @@ class SubClassWithSynthesizedDesignedInitializerOverride : SuperClassWithDepreca
4949
}
5050

5151
func callImplicitInitializerOnSubClassWithSynthesizedDesignedInitializerOverride() {
52-
_ = SubClassWithSynthesizedDesignedInitializerOverride() // expected-warning {{'init()' was deprecated in OS X 10.51}}
52+
_ = SubClassWithSynthesizedDesignedInitializerOverride() // expected-warning {{'init()' was deprecated in macOS 10.51}}
5353
}
5454

5555
@available(OSX, introduced: 10.9, deprecated: 10.51)
5656
class NSDeprecatedSuperClass {
5757
var i : Int = 7 // Causes initializer to be synthesized
5858
}
5959

60-
class NotDeprecatedSubClassOfDeprecatedSuperClass : NSDeprecatedSuperClass { // expected-warning {{'NSDeprecatedSuperClass' was deprecated in OS X 10.51}}
60+
class NotDeprecatedSubClassOfDeprecatedSuperClass : NSDeprecatedSuperClass { // expected-warning {{'NSDeprecatedSuperClass' was deprecated in macOS 10.51}}
6161
}
6262

6363
func callImplicitInitializerOnNotDeprecatedSubClassOfDeprecatedSuperClass() {

test/ClangImporter/objc_factory_method.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,27 @@ func testFactoryWithLaterIntroducedInit() {
4242

4343
// Don't prefer more available convenience factory initializer over less
4444
// available designated initializer
45-
_ = NSHavingConvenienceFactoryAndLaterDesignatedInit(flim:5) // expected-error {{'init(flim:)' is only available on OS X 10.52 or newer}}
45+
_ = NSHavingConvenienceFactoryAndLaterDesignatedInit(flim:5) // expected-error {{'init(flim:)' is only available in macOS 10.52 or newer}}
4646
// expected-note @-1 {{add 'if #available' version check}}
4747

48-
_ = NSHavingConvenienceFactoryAndLaterDesignatedInit(flam:5) // expected-error {{'init(flam:)' is only available on OS X 10.52 or newer}}
48+
_ = NSHavingConvenienceFactoryAndLaterDesignatedInit(flam:5) // expected-error {{'init(flam:)' is only available in macOS 10.52 or newer}}
4949
// expected-note @-1 {{add 'if #available' version check}} {{3-63=if #available(OSX 10.52, *) {\n _ = NSHavingConvenienceFactoryAndLaterDesignatedInit(flam:5)\n \} else {\n // Fallback on earlier versions\n \}}}
5050

5151

5252
// Don't prefer more available factory initializer over less
5353
// available designated initializer
54-
_ = NSHavingFactoryAndLaterConvenienceInit(flim:5) // expected-error {{'init(flim:)' is only available on OS X 10.52 or newer}}
54+
_ = NSHavingFactoryAndLaterConvenienceInit(flim:5) // expected-error {{'init(flim:)' is only available in macOS 10.52 or newer}}
5555
// expected-note @-1 {{add 'if #available' version check}}
5656

5757

58-
_ = NSHavingFactoryAndLaterConvenienceInit(flam:5) // expected-error {{'init(flam:)' is only available on OS X 10.52 or newer}}
58+
_ = NSHavingFactoryAndLaterConvenienceInit(flam:5) // expected-error {{'init(flam:)' is only available in macOS 10.52 or newer}}
5959
// expected-note @-1 {{add 'if #available' version check}}
6060

6161

6262
// When both a convenience factory and a convenience initializer have the
6363
// same availability, choose the convenience initializer.
64-
_ = NSHavingConvenienceFactoryAndSameConvenienceInit(flim:5) // expected-warning {{'init(flim:)' was deprecated in OS X 10.51: ConvenienceInit}}
65-
_ = NSHavingConvenienceFactoryAndSameConvenienceInit(flam:5) // expected-warning {{'init(flam:)' was deprecated in OS X 10.51: ConvenienceInit}}
64+
_ = NSHavingConvenienceFactoryAndSameConvenienceInit(flim:5) // expected-warning {{'init(flim:)' was deprecated in macOS 10.51: ConvenienceInit}}
65+
_ = NSHavingConvenienceFactoryAndSameConvenienceInit(flam:5) // expected-warning {{'init(flam:)' was deprecated in macOS 10.51: ConvenienceInit}}
6666

6767
_ = NSHavingConvenienceFactoryAndSameConvenienceInit(flotsam:5) // expected-warning {{'init(flotsam:)' is deprecated: ConvenienceInit}}
6868
_ = NSHavingConvenienceFactoryAndSameConvenienceInit(jetsam:5) // expected-warning {{'init(jetsam:)' is deprecated: ConvenienceInit}}

test/Interpreter/availability_host_os.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ print(mavericks()) // CHECK: {{^9$}}
1313
print(yosemite()) // CHECK-NEXT: {{^10$}}
1414

1515
#if FAIL
16-
print(todosSantos()) // expected-error {{'todosSantos()' is only available on OS X 10.99 or newer}}
16+
print(todosSantos()) // expected-error {{'todosSantos()' is only available in macOS 10.99 or newer}}
1717
// expected-note@-1 {{add 'if #available' version check}}
1818
#endif

test/Sema/Inputs/availability_multi_other.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class OtherIntroduced10_51 {
2020

2121
// This method uses a 10_52 only type in its signature, so validating
2222
// the declaration should produce an availability error
23-
func returns10_52() -> OtherIntroduced10_52 { // expected-error {{'OtherIntroduced10_52' is only available on OS X 10.52 or newer}}
23+
func returns10_52() -> OtherIntroduced10_52 { // expected-error {{'OtherIntroduced10_52' is only available in macOS 10.52 or newer}}
2424
// expected-note@-1 {{add @available attribute to enclosing instance method}}
2525

2626
// Body is not type checked (by design) so no error is expected for unavailable type used in return.
@@ -86,5 +86,5 @@ extension OtherIntroduced10_51 {
8686
class OtherIntroduced10_53 {
8787
}
8888

89-
var globalFromOtherOn10_52 : OtherIntroduced10_52? = nil // expected-error {{'OtherIntroduced10_52' is only available on OS X 10.52 or newer}}
89+
var globalFromOtherOn10_52 : OtherIntroduced10_52? = nil // expected-error {{'OtherIntroduced10_52' is only available in macOS 10.52 or newer}}
9090
// expected-note@-1 {{add @available attribute to enclosing var}}

0 commit comments

Comments
 (0)