Skip to content

Commit 765b2ec

Browse files
committed
Modify diagnostics to suggest updating existing available attribute
1 parent 54c1e46 commit 765b2ec

12 files changed

+122
-13
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6649,6 +6649,9 @@ ERROR(availability_variadic_type_only_version_newer, none,
66496649
NOTE(availability_guard_with_version_check, none,
66506650
"add 'if #available' version check", ())
66516651

6652+
NOTE(update_availability_attribute, none,
6653+
"change the @available attribute of the %0 on %1 from %2 to %3", (DescriptiveDeclKind, StringRef, StringRef, StringRef))
6654+
66526655
NOTE(availability_add_attribute, none,
66536656
"add @available attribute to enclosing %0", (DescriptiveDeclKind))
66546657
FIXIT(insert_available_attr,

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,18 +1821,30 @@ static void fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
18211821
if (TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(D).has_value())
18221822
return;
18231823

1824-
if (getActiveAvailableAttribute(D, Context)) {
1825-
// For QoI, in future should emit a fixit to update the existing attribute.
1826-
return;
1827-
}
1828-
18291824
// For some declarations (variables, enum elements), the location in concrete
18301825
// syntax to suggest the Fix-It may differ from the declaration to which
18311826
// we attach availability attributes in the abstract syntax tree during
18321827
// parsing.
18331828
const Decl *ConcDecl = concreteSyntaxDeclForAvailableAttribute(D);
18341829

18351830
DescriptiveDeclKind KindForDiagnostic = ConcDecl->getDescriptiveKind();
1831+
1832+
if (auto Attr = getActiveAvailableAttribute(D, Context)) {
1833+
if (Attr->isUnconditionallyUnavailable()) {
1834+
return;
1835+
}
1836+
SourceManager &SM = Context.SourceMgr;
1837+
auto Version = SM.extractText(Lexer::getCharSourceRangeFromSourceRange(
1838+
SM, Attr->IntroducedRange))
1839+
.str();
1840+
auto Required = RequiredRange.getLowerEndpoint().getAsString();
1841+
Context.Diags
1842+
.diagnose(ReferenceRange.Start, diag::update_availability_attribute,
1843+
KindForDiagnostic, Attr->platformString(), Version, Required)
1844+
.fixItReplace(Attr->IntroducedRange, Required);
1845+
return;
1846+
}
1847+
18361848
SourceLoc InsertLoc;
18371849

18381850
// To avoid exposing the pattern binding declaration to the user, get the

test/Concurrency/sendable_checking.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func testCV(
5151

5252
acceptCV(ns3) // expected-warning {{conformance of 'NS3' to 'Sendable' is only available in macOS 11.0 or newer}}
5353
// expected-note @-1 {{add 'if #available' version check}}
54+
// expected-note @-2 {{change the @available attribute of the global function on macOS from 10.15 to 11.0}}
5455

5556
acceptCV(ns4) // expected-complete-and-tns-warning {{type 'NS4' does not conform to the 'Sendable' protocol}}
5657

@@ -71,6 +72,7 @@ func testCV(
7172
acceptCV(ns2) // expected-warning{{type 'NS2' does not conform to the 'Sendable' protocol}}
7273
acceptCV(ns3) // expected-warning{{conformance of 'NS3' to 'Sendable' is only available in macOS 11.0 or newer}}
7374
// expected-note@-1{{add 'if #available' version check}}
75+
// expected-note @-2 {{change the @available attribute of the global function on macOS from 10.15 to 11.0}}
7476
acceptCV(ns4) // expected-warning{{type 'NS4' does not conform to the 'Sendable' protocol}}
7577
acceptCV(fn) // expected-warning{{type '() -> Void' does not conform to the 'Sendable' protocol}}
7678
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}

test/Sema/api-availability-only.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ public struct S {}
1010
public func newFunc() {
1111
_ = S() // expected-error {{'S' is only available in}}
1212
// expected-note @-1 {{add 'if #available' version check}}
13+
// expected-note @-2 {{change the @available attribute of the global function on macOS from 10.51 to 10.52}} {{9:18-23=10.52}}
1314
}

test/Sema/availability_define.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func client() {
5959
onMacOS10_15()
6060
onMacOS11_0() // expected-error {{is only available in macOS 11.0 or newer}}
6161
// expected-note @-1 {{add 'if #available' version check}}
62+
// expected-note @-2 {{change the @available attribute of the global function on macOS from 10.15 to 11.0}}
6263
onMacOSDeprecated()
6364

6465
if #available(_iOS14Aligned, *) {
@@ -68,6 +69,7 @@ func client() {
6869
if #unavailable(_iOS14Aligned) {
6970
onMacOS11_0() // expected-error {{is only available in macOS 11.0 or newer}}
7071
// expected-note @-1 {{add 'if #available' version check}}
72+
// expected-note @-2 {{change the @available attribute of the global function on macOS from 10.15 to 11.0}}
7173
} else {
7274
onMacOS11_0()
7375
}

test/Sema/availability_swiftui.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ class AnyColorBox: LessAvailable {} // Ok, exception specifically for AnyColorBo
1313
@available(macOS 10.15, *)
1414
@usableFromInline
1515
class OtherClass: LessAvailable {} // expected-error {{'LessAvailable' is only available in macOS 11 or newer; clients of 'SwiftUI' may have a lower deployment target}}
16+
// expected-note @-1 {{change the @available attribute of the class on macOS from 10.15 to 11}} {{13:18-23=11}}

test/Sema/availability_versions.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func functionAvailableOn10_51() {
5555

5656
let _: Int = globalFuncAvailableOn10_52() // expected-error {{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
5757
// expected-note@-1 {{add 'if #available' version check}}
58+
// expected-note@-2 {{change the @available attribute of the global function on macOS from 10.51 to 10.52}} {{43:29-34=10.52}}
5859
}
5960

6061
// Still allow other availability annotations on script-mode globals
@@ -327,7 +328,8 @@ class ClassWithPotentiallyUnavailableProperties {
327328
get {
328329
let _: Int = availableOn10_51Stored // expected-error {{'availableOn10_51Stored' is only available in macOS 10.51 or newer}}
329330
// expected-note@-1 {{add 'if #available' version check}}
330-
331+
// expected-note@-2 {{change the @available attribute of the pattern binding on macOS from 10.9 to 10.51}} {{326:31-35=10.51}}
332+
331333
if #available(OSX 10.51, *) {
332334
let _: Int = availableOn10_51Stored
333335
}
@@ -409,10 +411,12 @@ class ClassWithReferencesInInitializers {
409411
var propWithInitializer10_51: Int = globalFuncAvailableOn10_51()
410412

411413
var propWithInitializer10_52: Int = globalFuncAvailableOn10_52() // expected-error {{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
414+
// expected-note@-1 {{change the @available attribute of the class on macOS from 10.51 to 10.52}} {{409:29-34=10.52}}
412415

413416
lazy var lazyPropWithInitializer10_51: Int = globalFuncAvailableOn10_51()
414417

415418
lazy var lazyPropWithInitializer10_52: Int = globalFuncAvailableOn10_52() // expected-error {{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
419+
// expected-note@-1 {{change the @available attribute of the class on macOS from 10.51 to 10.52}} {{409:29-34=10.52}}
416420
}
417421

418422
func accessPotentiallyUnavailableProperties(_ o: ClassWithPotentiallyUnavailableProperties) {
@@ -522,6 +526,7 @@ enum EnumIntroducedOn10_52 {
522526

523527
@available(OSX, introduced: 10.51)
524528
enum CompassPoint {
529+
525530
case North
526531
case South
527532
case East
@@ -540,9 +545,11 @@ enum CompassPoint {
540545
case WithAvailableByEnumElementPayload1(p : EnumIntroducedOn10_52), WithAvailableByEnumElementPayload2(p : EnumIntroducedOn10_52)
541546

542547
case WithPotentiallyUnavailablePayload(p : EnumIntroducedOn10_52) // expected-error {{'EnumIntroducedOn10_52' is only available in macOS 10.52 or newer}}
548+
// expected-note@-1 {{change the @available attribute of the enum on macOS from 10.51 to 10.52}} {{527:29-34=10.52}}
543549

544550
case WithPotentiallyUnavailablePayload1(p : EnumIntroducedOn10_52), WithPotentiallyUnavailablePayload2(p : EnumIntroducedOn10_52) // expected-error 2{{'EnumIntroducedOn10_52' is only available in macOS 10.52 or newer}}
545-
551+
// expected-note@-1 2{{change the @available attribute of the enum on macOS from 10.51 to 10.52}} {{527:29-34=10.52}}
552+
546553
@available(OSX, unavailable)
547554
case WithPotentiallyUnavailablePayload3(p : EnumIntroducedOn10_52)
548555
}
@@ -878,18 +885,20 @@ class SubWithLargerMemberAvailability : SuperWithLimitedMemberAvailability {
878885
override func someMethod() {
879886
super.someMethod() // expected-error {{'someMethod()' is only available in macOS 10.51 or newer}}
880887
// expected-note@-1 {{add 'if #available' version check}}
881-
888+
// expected-note@-2 {{change the @available attribute of the instance method on macOS from 10.9 to 10.51}} {{884:31-35=10.51}}
889+
882890
if #available(OSX 10.51, *) {
883891
super.someMethod()
884892
}
885893
}
886894

887895
@available(OSX, introduced: 10.9)
888896
override var someProperty: Int {
889-
get {
897+
get {
890898
let _ = super.someProperty // expected-error {{'someProperty' is only available in macOS 10.51 or newer}}
891-
// expected-note@-1 {{add 'if #available' version check}}
892-
899+
// expected-note@-1 {{add 'if #available' version check}}
900+
// expected-note@-2 {{change the @available attribute of the pattern binding on macOS from 10.9 to 10.51}} {{895:31-35=10.51}}
901+
893902
if #available(OSX 10.51, *) {
894903
let _ = super.someProperty
895904
}
@@ -961,6 +970,7 @@ protocol ProtocolAvailableOn10_51 {
961970

962971
@available(OSX, introduced: 10.9)
963972
protocol ProtocolAvailableOn10_9InheritingFromProtocolAvailableOn10_51 : ProtocolAvailableOn10_51 { // expected-error {{'ProtocolAvailableOn10_51' is only available in macOS 10.51 or newer}}
973+
// expected-note@-1 {{change the @available attribute of the protocol on macOS from 10.9 to 10.51}} {{971:29-33=10.51}}
964974
}
965975

966976
@available(OSX, introduced: 10.51)
@@ -973,6 +983,7 @@ protocol UnavailableProtocolInheritingFromProtocolAvailableOn10_51 : ProtocolAva
973983

974984
@available(OSX, introduced: 10.9)
975985
class SubclassAvailableOn10_9OfClassAvailableOn10_51 : ClassAvailableOn10_51 { // expected-error {{'ClassAvailableOn10_51' is only available in macOS 10.51 or newer}}
986+
// expected-note@-1 {{change the @available attribute of the class on macOS from 10.9 to 10.51}} {{984:29-33=10.51}}
976987
}
977988

978989
@available(OSX, unavailable)
@@ -997,12 +1008,14 @@ func castToPotentiallyUnavailableProtocol() {
9971008

9981009
@available(OSX, introduced: 10.9)
9991010
class SubclassAvailableOn10_9OfClassAvailableOn10_51AlsoAdoptingProtocolAvailableOn10_51 : ClassAvailableOn10_51, ProtocolAvailableOn10_51 { // expected-error {{'ClassAvailableOn10_51' is only available in macOS 10.51 or newer}}
1011+
// expected-note@-1 {{change the @available attribute of the class on macOS from 10.9 to 10.51}} {{1009:29-33=10.51}}
10001012
}
10011013

10021014
class SomeGenericClass<T> { }
10031015

10041016
@available(OSX, introduced: 10.9)
10051017
class SubclassAvailableOn10_9OfSomeGenericClassOfProtocolAvailableOn10_51 : SomeGenericClass<ProtocolAvailableOn10_51> { // expected-error {{'ProtocolAvailableOn10_51' is only available in macOS 10.51 or newer}}
1018+
// expected-note@-1 {{change the @available attribute of the class on macOS from 10.9 to 10.51}} {{1016:29-33=10.51}}
10061019
}
10071020

10081021
@available(OSX, unavailable)
@@ -1054,6 +1067,7 @@ extension ClassAvailableOn10_51 {
10541067
let _ = globalFuncAvailableOn10_51()
10551068
let _ = globalFuncAvailableOn10_52() // expected-error {{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
10561069
// expected-note@-1 {{add 'if #available' version check}}
1070+
// expected-note@-2 {{change the @available attribute of the extension on macOS from 10.51 to 10.52}} {{1063:29-34=10.52}}
10571071
}
10581072
}
10591073

@@ -1655,6 +1669,7 @@ class ClassWithShortFormAvailableOn10_54 {
16551669
func funcWithShortFormAvailableOn10_9() {
16561670
let _ = ClassWithShortFormAvailableOn10_51() // expected-error {{'ClassWithShortFormAvailableOn10_51' is only available in macOS 10.51 or newer}}
16571671
// expected-note@-1 {{add 'if #available' version check}}
1672+
// expected-note@-2 {{change the @available attribute of the global function on macOS from 10.9 to 10.51}} {{1668:16-20=10.51}}
16581673
}
16591674

16601675
@available(OSX 10.51, *)
@@ -1689,6 +1704,7 @@ func funcWithMultipleShortFormAnnotationsForTheSamePlatform() {
16891704

16901705
let _ = ClassWithShortFormAvailableOn10_54() // expected-error {{'ClassWithShortFormAvailableOn10_54' is only available in macOS 10.54 or newer}}
16911706
// expected-note@-1 {{add 'if #available' version check}}
1707+
// expected-note@-2 {{change the @available attribute of the global function on macOS from 10.52 to 10.54}} {{1701:16-21=10.54}}
16921708
}
16931709

16941710
func useShortFormAvailable() {

test/Sema/availability_versions_multi.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,21 @@ func useFromOtherOn99_51() {
3434
o10_9.extensionMethodOnOtherIntroduced10_9AvailableOn99_51(o99_51)
3535
_ = o99_51.returns99_52Introduced99_52() // expected-error {{'returns99_52Introduced99_52()' is only available in macOS 99.52 or newer}}
3636
// expected-note@-1 {{add 'if #available' version check}}
37+
// expected-note@-2 {{change the @available attribute of the global function on macOS from 99.51 to 99.52}} {{26:29-34=99.52}}
3738

3839
_ = OtherIntroduced99_52()
3940
// expected-error@-1 {{'OtherIntroduced99_52' is only available in macOS 99.52 or newer}}
4041
// expected-note@-2 {{add 'if #available' version check}}
42+
// expected-note@-3 {{change the @available attribute of the global function on macOS from 99.51 to 99.52}} {{26:29-34=99.52}}
4143

4244
o99_51.extensionMethodOnOtherIntroduced99_51AvailableOn99_52() // expected-error {{'extensionMethodOnOtherIntroduced99_51AvailableOn99_52()' is only available in macOS 99.52 or newer}}
4345
// expected-note@-1 {{add 'if #available' version check}}
46+
// expected-note@-2 {{change the @available attribute of the global function on macOS from 99.51 to 99.52}} {{26:29-34=99.52}}
4447

4548
_ = OtherIntroduced99_51.NestedIntroduced99_52()
4649
// expected-error@-1 {{'NestedIntroduced99_52' is only available in macOS 99.52 or newer}}
4750
// expected-note@-2 {{add 'if #available' version check}}
51+
// expected-note@-3 {{change the @available attribute of the global function on macOS from 99.51 to 99.52}} {{26:29-34=99.52}}
4852
}
4953

5054
@available(OSX, introduced: 99.52)
@@ -55,7 +59,7 @@ func useFromOtherOn99_52() {
5559
_ = n99_52.returns99_52()
5660
_ = n99_52.returns99_53() // expected-error {{'returns99_53()' is only available in macOS 99.53 or newer}}
5761
// expected-note@-1 {{add 'if #available' version check}}
58-
62+
// expected-note@-2 {{change the @available attribute of the global function on macOS from 99.52 to 99.53}} {{54:29-34=99.53}}
5963
// This will trigger validation of the global in availability_in_multi_other.swift
6064
_ = globalFromOtherOn99_52
6165
}

test/attr/ApplicationMain/attr_main_struct_available_future.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// REQUIRES: OS=macosx
44

55
@main // expected-error {{'main()' is only available in macOS 10.99 or newer}}
6+
// expected-note @-1 {{change the @available attribute of the struct on macOS from 10.0 to 10.99}}
67
@available(OSX 10.0, *)
78
struct EntryPoint {
89
@available(OSX 10.99, *)

test/attr/attr_availability_osx.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func testMemberAvailability() {
120120
TestStruct().doAnotherThing() // expected-error {{'doAnotherThing()' is unavailable}}
121121
TestStruct().doThirdThing() // expected-error {{'doThirdThing()' is unavailable}}
122122
TestStruct().doFourthThing() // expected-error {{'doFourthThing()' is only available in macOS 10.12 or newer}} expected-note {{'if #available'}}
123+
// expected-note @-1 {{change the @available attribute of the global function on macOS from 10.11 to 10.12}}
123124
TestStruct().doDeprecatedThing() // expected-warning {{'doDeprecatedThing()' is deprecated}}
124125
}
125126

0 commit comments

Comments
 (0)