Skip to content

Commit 0671848

Browse files
authored
Merge pull request #15213 from jrose-apple/avail-yourself-of-this-patch
Allow @available(swift, ...) nested within @available(macOS, ...) rdar://problem/32632327
2 parents b0cccdb + 74a4adc commit 0671848

File tree

9 files changed

+81
-15
lines changed

9 files changed

+81
-15
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,6 +3647,10 @@ WARNING(availability_query_useless_enclosing_scope, none,
36473647
NOTE(availability_query_useless_enclosing_scope_here, none,
36483648
"enclosing scope here", ())
36493649

3650+
WARNING(availability_extension_platform_agnostic, none,
3651+
"'@available' without an OS is ignored on extensions; "
3652+
"apply the attribute to each member instead", ())
3653+
36503654
ERROR(availability_global_script_no_potential,
36513655
none, "global variable cannot be marked potentially "
36523656
"unavailable with '@available' in script mode", ())

lib/Sema/TypeCheckAttr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
7070
bool visitDeclAttribute(DeclAttribute *A) = delete;
7171

7272
#define IGNORED_ATTR(X) void visit##X##Attr(X##Attr *) {}
73-
IGNORED_ATTR(Available)
7473
IGNORED_ATTR(CDecl)
7574
IGNORED_ATTR(ClangImporterSynthesizedType)
7675
IGNORED_ATTR(Convenience)
@@ -115,6 +114,14 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
115114
IGNORED_ATTR(WeakLinked)
116115
#undef IGNORED_ATTR
117116

117+
void visitAvailableAttr(AvailableAttr *attr) {
118+
if (!isa<ExtensionDecl>(D))
119+
return;
120+
if (attr->hasPlatform())
121+
return;
122+
diagnoseAndRemoveAttr(attr, diag::availability_extension_platform_agnostic);
123+
}
124+
118125
// @noreturn has been replaced with a 'Never' return type.
119126
void visitNoReturnAttr(NoReturnAttr *attr) {
120127
if (auto FD = dyn_cast<FuncDecl>(D)) {
@@ -1073,8 +1080,10 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
10731080
if (TC.getLangOpts().DisableAvailabilityChecking)
10741081
return;
10751082

1076-
if (!attr->isActivePlatform(TC.Context) || !attr->Introduced.hasValue())
1083+
if (!attr->hasPlatform() || !attr->isActivePlatform(TC.Context) ||
1084+
!attr->Introduced.hasValue()) {
10771085
return;
1086+
}
10781087

10791088
SourceLoc attrLoc = attr->getLocation();
10801089

stdlib/public/SDK/Metal/Metal.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
@_exported import Metal // Clang module
1414

15-
@available(swift 4)
1615
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
1716
extension MTLBlitCommandEncoder {
1817

@@ -21,7 +20,6 @@ extension MTLBlitCommandEncoder {
2120
}
2221
}
2322

24-
@available(swift 4)
2523
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
2624
extension MTLBuffer {
2725

@@ -38,7 +36,6 @@ extension MTLBuffer {
3836
}
3937
}
4038

41-
@available(swift 4)
4239
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
4340
extension MTLComputeCommandEncoder {
4441

@@ -69,7 +66,6 @@ extension MTLComputeCommandEncoder {
6966
}
7067
}
7168

72-
@available(swift 4)
7369
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
7470
extension MTLDevice {
7571

@@ -92,7 +88,6 @@ public func MTLCopyAllDevicesWithObserver(handler: @escaping MTLDeviceNotificati
9288
}
9389
#endif
9490

95-
@available(swift 4)
9691
@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)
9792
extension MTLFunctionConstantValues {
9893

@@ -102,7 +97,6 @@ extension MTLFunctionConstantValues {
10297

10398
}
10499

105-
@available(swift 4)
106100
@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
107101
extension MTLArgumentEncoder {
108102

@@ -119,7 +113,6 @@ extension MTLArgumentEncoder {
119113
}
120114
}
121115

122-
@available(swift 4)
123116
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
124117
extension MTLRenderCommandEncoder {
125118

@@ -201,7 +194,6 @@ extension MTLRenderCommandEncoder {
201194
#endif
202195
}
203196

204-
@available(swift 4)
205197
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
206198
extension MTLRenderPassDescriptor {
207199

@@ -220,7 +212,6 @@ extension MTLRenderPassDescriptor {
220212

221213
}
222214

223-
@available(swift 4)
224215
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
225216
extension MTLTexture {
226217

stdlib/public/SDK/MetalKit/MetalKit.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
@_exported import MetalKit // Clang module
1414

15-
@available(swift 4)
1615
@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)
1716
extension MTKMesh {
1817
public class func newMeshes(asset: MDLAsset, device: MTLDevice) throws -> (modelIOMeshes: [MDLMesh], metalKitMeshes: [MTKMesh]) {

stdlib/public/SDK/UIKit/UIKit.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,9 @@ extension _UIKitNumericRawRepresentable {
9595
}
9696
}
9797

98-
@available(swift 4)
9998
extension UIFont.Weight : _UIKitNumericRawRepresentable {}
10099

101100
#if !os(watchOS)
102-
@available(swift 4)
103101
extension UILayoutPriority : _UIKitNumericRawRepresentable {}
104102
#endif
105103

stdlib/public/core/Integers.swift.gyb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3841,7 +3841,6 @@ extension SignedNumeric where Self : Comparable {
38413841
}
38423842
}
38433843

3844-
@available(swift, obsoleted: 4)
38453844
extension BinaryInteger {
38463845
@_inlineable // FIXME(sil-serialize-all)
38473846
@available(swift, obsoleted: 4)

test/attr/attr_availability.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,3 +807,9 @@ rdar32526620_2(a: 42, b: .bar)
807807
func rdar32526620_3(a: Int, b: E_32526620, c: String) {} // expected-note {{here}}
808808
rdar32526620_3(a: 42, b: .bar, c: "question")
809809
// expected-error@-1 {{'rdar32526620_3(a:b:c:)' has been replaced by instance method 'E_32526620.set(a:c:)'}} {{1-15=E_32526620.bar.set}} {{23-32=}}
810+
811+
@available(*, unavailable) // expected-warning {{'@available' without an OS is ignored on extensions; apply the attribute to each member instead}} {{1-28=}}
812+
extension DummyType {}
813+
814+
@available(*, deprecated) // expected-warning {{'@available' without an OS is ignored on extensions; apply the attribute to each member instead}} {{1-27=}}
815+
extension DummyType {}

test/attr/attr_availability_osx.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,36 @@ doSomethingDeprecatedOnOSX() // expected-warning{{'doSomethingDeprecatedOnOSX()'
7171
func doSomethingDeprecatedOniOS() { }
7272

7373
doSomethingDeprecatedOniOS() // okay
74+
75+
76+
struct TestStruct {}
77+
78+
@available(macOS 10.10, *)
79+
extension TestStruct { // expected-note {{enclosing scope here}}
80+
@available(swift 400)
81+
func doTheThing() {} // expected-note {{'doTheThing()' was introduced in Swift 400}}
82+
83+
@available(macOS 10.9, *) // expected-error {{declaration cannot be more available than enclosing scope}}
84+
@available(swift 400)
85+
func doAnotherThing() {} // expected-note {{'doAnotherThing()' was introduced in Swift 400}}
86+
87+
@available(macOS 10.12, *)
88+
@available(swift 400)
89+
func doThirdThing() {} // expected-note {{'doThirdThing()' was introduced in Swift 400}}
90+
91+
@available(macOS 10.12, *)
92+
@available(swift 1)
93+
func doFourthThing() {}
94+
95+
@available(*, deprecated)
96+
func doDeprecatedThing() {}
97+
}
98+
99+
@available(macOS 10.11, *)
100+
func testMemberAvailability() {
101+
TestStruct().doTheThing() // expected-error {{'doTheThing()' is unavailable}}
102+
TestStruct().doAnotherThing() // expected-error {{'doAnotherThing()' is unavailable}}
103+
TestStruct().doThirdThing() // expected-error {{'doThirdThing()' is unavailable}}
104+
TestStruct().doFourthThing() // expected-error {{'doFourthThing()' is only available on OS X 10.12 or newer}} expected-note {{'if #available'}}
105+
TestStruct().doDeprecatedThing() // expected-warning {{'doDeprecatedThing()' is deprecated}}
106+
}

test/attr/attr_availability_swift.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,30 @@ func baz() {
2020
@available(swift, introduced: 3.0.1, obsoleted: 3.0.2, message: "tiny bug")
2121
func bug() {
2222
}
23+
24+
struct TestStruct {}
25+
26+
@available(macOS 10.11, *)
27+
extension TestStruct {
28+
@available(swift 400)
29+
func doTheThing() {} // expected-note {{'doTheThing()' was introduced in Swift 400}}
30+
}
31+
32+
@available(swift 400) // expected-warning {{'@available' without an OS is ignored on extensions; apply the attribute to each member instead}} {{1-23=}}
33+
extension TestStruct {
34+
func doAnotherThing() {}
35+
}
36+
37+
@available(macOS 10.11, *)
38+
func testMemberAvailability() {
39+
TestStruct().doTheThing() // expected-error {{'doTheThing()' is unavailable}}
40+
TestStruct().doAnotherThing() // okay (for now)
41+
}
42+
43+
@available(swift 400) // expected-warning {{'@available' without an OS is ignored on extensions; apply the attribute to each member instead}} {{1-23=}}
44+
@available(macOS 10.11, *)
45+
extension TestStruct {}
46+
47+
@available(macOS 10.11, *)
48+
@available(swift 400) // expected-warning {{'@available' without an OS is ignored on extensions; apply the attribute to each member instead}} {{1-23=}}
49+
extension TestStruct {}

0 commit comments

Comments
 (0)