Skip to content

Commit d2f77f4

Browse files
authored
Merge pull request #77341 from tshortli/unavailable-types-in-unavailable-signatures
Sema: Fixes for availability checking in unavailable contexts
2 parents 9106543 + 7c75b26 commit d2f77f4

11 files changed

+826
-283
lines changed

include/swift/AST/AvailabilityContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class AvailabilityContext {
6666
/// returns `nullopt`.
6767
std::optional<PlatformKind> getUnavailablePlatformKind() const;
6868

69+
/// Returns true if this context is unavailable.
70+
bool isUnavailable() const {
71+
return getUnavailablePlatformKind().has_value();
72+
}
73+
6974
/// Returns true if this context is deprecated on the current platform.
7075
bool isDeprecated() const;
7176

lib/AST/AvailabilityContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ bool AvailabilityContext::PlatformInfo::isContainedIn(
9191
if (IsUnavailable && other.IsUnavailable) {
9292
if (UnavailablePlatform != other.UnavailablePlatform &&
9393
UnavailablePlatform != PlatformKind::none &&
94-
!inheritsAvailabilityFromPlatform(UnavailablePlatform,
95-
other.UnavailablePlatform))
94+
inheritsAvailabilityFromPlatform(UnavailablePlatform,
95+
other.UnavailablePlatform))
9696
return false;
9797
}
9898

lib/Sema/TypeCheckAccess.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2033,7 +2033,7 @@ class DeclAvailabilityChecker : public DeclVisitor<DeclAvailabilityChecker> {
20332033

20342034
// If the decl which references this type is unavailable on the current
20352035
// platform, don't diagnose the availability of the type.
2036-
if (AvailableAttr::isUnavailable(context))
2036+
if (Where.getAvailability().isUnavailable())
20372037
return;
20382038

20392039
diagnoseTypeAvailability(typeRepr, type, context->getLoc(),

test/Sema/availability.swift

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// RUN: %target-typecheck-verify-swift -parse-as-library -module-name MyModule
22

3-
// REQUIRES: OS=macosx
4-
53
@available(*, unavailable)
64
func unavailable_foo() {} // expected-note {{'unavailable_foo()' has been explicitly marked unavailable here}}
75

@@ -31,90 +29,6 @@ func foo(x : NSUInteger) { // expected-error {{'NSUInteger' is unavailable: use
3129
// expected-error@-1 {{cannot convert value of type 'Int' to specified type 'Outer.NSUInteger'}}
3230
}
3331

34-
/* FIXME 'nil == a' fails to type-check with a bogus error message
35-
* <rdar://problem/17540796>
36-
func markUsed<T>(t: T) {}
37-
func testString() {
38-
let a : String = "Hey"
39-
if a == nil {
40-
markUsed("nil")
41-
} else if nil == a {
42-
markUsed("nil")
43-
}
44-
else {
45-
markUsed("not nil")
46-
}
47-
}
48-
*/
49-
50-
// Test preventing protocol witnesses for unavailable requirements
51-
@objc
52-
protocol ProtocolWithRenamedRequirement {
53-
@available(*, unavailable, renamed: "new(bar:)")
54-
@objc optional func old(foo: Int) // expected-note{{'old(foo:)' has been explicitly marked unavailable here}}
55-
func new(bar: Int)
56-
}
57-
58-
class ClassWithGoodWitness : ProtocolWithRenamedRequirement {
59-
@objc func new(bar: Int) {}
60-
}
61-
62-
class ClassWithBadWitness : ProtocolWithRenamedRequirement {
63-
@objc func old(foo: Int) {} // expected-error{{'old(foo:)' has been renamed to 'new(bar:)'}}
64-
@objc func new(bar: Int) {}
65-
}
66-
67-
@available(OSX, unavailable)
68-
let unavailableOnOSX: Int = 0 // expected-note{{explicitly marked unavailable here}}
69-
@available(iOS, unavailable)
70-
let unavailableOniOS: Int = 0
71-
@available(iOS, unavailable) @available(OSX, unavailable)
72-
let unavailableOnBothA: Int = 0 // expected-note{{explicitly marked unavailable here}}
73-
@available(OSX, unavailable) @available(iOS, unavailable)
74-
let unavailableOnBothB: Int = 0 // expected-note{{explicitly marked unavailable here}}
75-
76-
@available(OSX, unavailable)
77-
typealias UnavailableOnOSX = Int // expected-note{{explicitly marked unavailable here}}
78-
@available(iOS, unavailable)
79-
typealias UnavailableOniOS = Int
80-
@available(iOS, unavailable) @available(OSX, unavailable)
81-
typealias UnavailableOnBothA = Int // expected-note{{explicitly marked unavailable here}}
82-
@available(OSX, unavailable) @available(iOS, unavailable)
83-
typealias UnavailableOnBothB = Int // expected-note{{explicitly marked unavailable here}}
84-
85-
@available(macOS, unavailable)
86-
let unavailableOnMacOS: Int = 0 // expected-note{{explicitly marked unavailable here}}
87-
@available(macOS, unavailable)
88-
typealias UnavailableOnMacOS = Int // expected-note{{explicitly marked unavailable here}}
89-
90-
@available(OSXApplicationExtension, unavailable)
91-
let unavailableOnOSXAppExt: Int = 0
92-
@available(macOSApplicationExtension, unavailable)
93-
let unavailableOnMacOSAppExt: Int = 0
94-
95-
@available(OSXApplicationExtension, unavailable)
96-
typealias UnavailableOnOSXAppExt = Int
97-
@available(macOSApplicationExtension, unavailable)
98-
typealias UnavailableOnMacOSAppExt = Int
99-
100-
func testPlatforms() {
101-
_ = unavailableOnOSX // expected-error{{unavailable}}
102-
_ = unavailableOniOS
103-
_ = unavailableOnBothA // expected-error{{unavailable}}
104-
_ = unavailableOnBothB // expected-error{{unavailable}}
105-
_ = unavailableOnMacOS // expected-error{{unavailable}}
106-
_ = unavailableOnOSXAppExt
107-
_ = unavailableOnMacOSAppExt
108-
109-
let _: UnavailableOnOSX = 0 // expected-error{{unavailable}}
110-
let _: UnavailableOniOS = 0
111-
let _: UnavailableOnBothA = 0 // expected-error{{unavailable}}
112-
let _: UnavailableOnBothB = 0 // expected-error{{unavailable}}
113-
let _: UnavailableOnMacOS = 0 // expected-error{{unavailable}}
114-
let _: UnavailableOnOSXAppExt = 0
115-
let _: UnavailableOnMacOSAppExt = 0
116-
}
117-
11832
struct VarToFunc {
11933
@available(*, unavailable, renamed: "function()")
12034
var variable: Int { // expected-note 2 {{explicitly marked unavailable here}}

test/Sema/availability_versions.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ func classViaTypeParameter() {
769769
// Potentially unavailable class used in declarations
770770

771771
class ClassWithDeclarationsOfPotentiallyUnavailableClasses {
772-
// expected-note@-1 6{{add @available attribute to enclosing class}}
772+
// expected-note@-1 5{{add @available attribute to enclosing class}}
773773

774774
@available(OSX, introduced: 51)
775775
init() {}
@@ -823,8 +823,7 @@ class ClassWithDeclarationsOfPotentiallyUnavailableClasses {
823823

824824
@available(OSX, unavailable)
825825
func unavailableMethodWithPotentiallyUnavailableLocalDeclaration() {
826-
let _ : ClassAvailableOn51 = methodWithPotentiallyUnavailableReturnType() // expected-error {{'ClassAvailableOn51' is only available in macOS 51 or newer}}
827-
// expected-note@-1 {{add 'if #available' version check}}
826+
let _ : ClassAvailableOn51 = methodWithPotentiallyUnavailableReturnType()
828827
}
829828
}
830829

test/Sema/property_wrapper_availability.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct Available51Wrapper<T> {
1717

1818
@available(*, unavailable)
1919
@propertyWrapper
20-
struct UnavailableWrapper<T> { // expected-note 8 {{'UnavailableWrapper' has been explicitly marked unavailable here}}
20+
struct UnavailableWrapper<T> { // expected-note 6 {{'UnavailableWrapper' has been explicitly marked unavailable here}}
2121
var wrappedValue: T
2222
}
2323

@@ -77,8 +77,8 @@ struct UnavailableStruct {
7777
@AlwaysAvailableWrapper var alwaysAvailableExplicit: S
7878
@AlwaysAvailableWrapper var alwaysAvailableInferred = S()
7979

80-
@Available51Wrapper var available51Explicit: S // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
81-
@Available51Wrapper var available51Inferred = S() // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
80+
@Available51Wrapper var available51Explicit: S
81+
@Available51Wrapper var available51Inferred = S()
8282

8383
@UnavailableWrapper var unavailableExplicit: S
8484
@UnavailableWrapper var unavailableInferred = S()
@@ -92,11 +92,11 @@ struct UnavailableOnMacOSStruct {
9292
@AlwaysAvailableWrapper var alwaysAvailableExplicit: S
9393
@AlwaysAvailableWrapper var alwaysAvailableInferred = S()
9494

95-
@Available51Wrapper var available51Explicit: S // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
96-
@Available51Wrapper var available51Inferred = S() // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
95+
@Available51Wrapper var available51Explicit: S
96+
@Available51Wrapper var available51Inferred = S()
9797

98-
@UnavailableWrapper var unavailableExplicit: S // expected-error {{'UnavailableWrapper' is unavailable}}
99-
@UnavailableWrapper var unavailableInferred = S() // expected-error {{'UnavailableWrapper' is unavailable}}
98+
@UnavailableWrapper var unavailableExplicit: S
99+
@UnavailableWrapper var unavailableInferred = S()
100100

101101
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S
102102
@WrappedValueAvailable51 var wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}

test/attr/attr_availability_objc.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,20 @@ class Kitten : Snout {}
142142
extension Kitten {
143143
@nonobjc func sniff() {}
144144
}
145+
146+
// Test preventing protocol witnesses for unavailable requirements
147+
@objc
148+
protocol ProtocolWithRenamedRequirement {
149+
@available(*, unavailable, renamed: "new(bar:)")
150+
@objc optional func old(foo: Int) // expected-note{{'old(foo:)' has been explicitly marked unavailable here}}
151+
func new(bar: Int)
152+
}
153+
154+
class ClassWithGoodWitness : ProtocolWithRenamedRequirement {
155+
@objc func new(bar: Int) {}
156+
}
157+
158+
class ClassWithBadWitness : ProtocolWithRenamedRequirement {
159+
@objc func old(foo: Int) {} // expected-error{{'old(foo:)' has been renamed to 'new(bar:)'}}
160+
@objc func new(bar: Int) {}
161+
}

test/attr/attr_availability_transitive_multiple.swift

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)