Skip to content

Commit 620462d

Browse files
committed
Sema: Don't diagnose declarations more available than unavailable container.
It turns out that we must allow declarations with `introduced:` availability nested inside of other declarations that are `unavailable` in order to influence weak linking. Stop diagnosing declarations as being more available than their unavailable containers and revert some changes to availability inference that were designed to avoid creating these nestings but caused regressions for declarations marked `@_spi_available.` Reverts parts of #64310, #64015, and #62900.
1 parent 1482108 commit 620462d

File tree

7 files changed

+53
-53
lines changed

7 files changed

+53
-53
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5990,10 +5990,6 @@ ERROR(availability_decl_more_than_enclosing, none,
59905990
"%0 cannot be more available than enclosing scope",
59915991
(DescriptiveDeclKind))
59925992

5993-
WARNING(availability_decl_more_than_unavailable_enclosing, none,
5994-
"%0 cannot be more available than unavailable enclosing scope",
5995-
(DescriptiveDeclKind))
5996-
59975993
NOTE(availability_implicit_decl_here, none,
59985994
"%0 implicitly declared here with availability of %1 %2 or newer",
59995995
(DescriptiveDeclKind, StringRef, llvm::VersionTuple))

lib/AST/Availability.cpp

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,6 @@ static AvailableAttr *createAvailableAttr(PlatformKind Platform,
109109
llvm::VersionTuple Obsoleted =
110110
Inferred.Obsoleted.value_or(llvm::VersionTuple());
111111

112-
// If a decl is unavailable then it cannot have any introduced, deprecated, or
113-
// obsoleted version.
114-
if (Inferred.PlatformAgnostic ==
115-
PlatformAgnosticAvailabilityKind::Unavailable) {
116-
Introduced = llvm::VersionTuple();
117-
Deprecated = llvm::VersionTuple();
118-
Obsoleted = llvm::VersionTuple();
119-
}
120-
121112
return new (Context)
122113
AvailableAttr(SourceLoc(), SourceRange(), Platform,
123114
Message, Rename, RenameDecl,
@@ -168,27 +159,6 @@ void AvailabilityInference::applyInferredAvailableAttrs(
168159

169160
DeclAttributes &Attrs = ToDecl->getAttrs();
170161

171-
// Some kinds of platform agnostic availability supersede any platform
172-
// specific availability.
173-
auto InferredAgnostic = Inferred.find(PlatformKind::none);
174-
if (InferredAgnostic != Inferred.end()) {
175-
switch (InferredAgnostic->second.PlatformAgnostic) {
176-
case PlatformAgnosticAvailabilityKind::Deprecated:
177-
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
178-
case PlatformAgnosticAvailabilityKind::Unavailable:
179-
Attrs.add(createAvailableAttr(PlatformKind::none,
180-
InferredAgnostic->second, Message, Rename,
181-
RenameDecl, Context));
182-
return;
183-
184-
case PlatformAgnosticAvailabilityKind::None:
185-
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
186-
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
187-
case PlatformAgnosticAvailabilityKind::NoAsync:
188-
break;
189-
}
190-
}
191-
192162
// Create an availability attribute for each observed platform and add
193163
// to ToDecl.
194164
for (auto &Pair : Inferred) {

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,17 +1945,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
19451945
AvailabilityInference::availableRange(attr, Ctx);
19461946

19471947
if (auto *parent = getEnclosingDeclForDecl(D)) {
1948-
if (auto enclosingUnavailable = parent->getSemanticUnavailableAttr()) {
1949-
if (!AttrRange.isKnownUnreachable()) {
1950-
const Decl *enclosingDecl = enclosingUnavailable.value().second;
1951-
diagnose(D->isImplicit() ? enclosingDecl->getLoc()
1952-
: attr->getLocation(),
1953-
diag::availability_decl_more_than_unavailable_enclosing,
1954-
D->getDescriptiveKind());
1955-
diagnose(parent->getLoc(),
1956-
diag::availability_decl_more_than_unavailable_enclosing_here);
1957-
}
1958-
} else if (auto enclosingAvailable =
1948+
if (auto enclosingAvailable =
19591949
parent->getSemanticAvailableRangeAttr()) {
19601950
const AvailableAttr *enclosingAttr = enclosingAvailable.value().first;
19611951
const Decl *enclosingDecl = enclosingAvailable.value().second;

test/ModuleInterface/actor_availability.swift

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -module-name Library -target %target-swift-abi-5.3-triple
2+
// RUN: %target-swift-emit-module-interfaces(%t/Library.swiftinterface, %t/Library.private.swiftinterface) %s -module-name Library -target %target-swift-abi-5.3-triple
33
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -module-name Library
4-
// RUN: %FileCheck %s < %t/Library.swiftinterface
4+
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.private.swiftinterface) -module-name Library
5+
// RUN: %FileCheck %s --check-prefixes=CHECK,CHECK-PUBLIC < %t/Library.swiftinterface
6+
// RUN: %FileCheck %s --check-prefixes=CHECK,CHECK-PRIVATE < %t/Library.private.swiftinterface
57

68
// REQUIRES: VENDOR=apple
79

@@ -33,7 +35,7 @@ public actor ActorWithExplicitAvailability {
3335
@available(macOS, unavailable)
3436
public actor UnavailableActor {
3537
// CHECK: @available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
36-
// CHECK-NEXT: @available(macOS, unavailable)
38+
// CHECK-NEXT: @available(macOS, unavailable, introduced: 10.15)
3739
// CHECK-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor {
3840
// CHECK-NEXT: get
3941
// CHECK-NEXT: }
@@ -72,9 +74,39 @@ extension Enum {
7274
@available(macOS, unavailable)
7375
public actor UnavailableExtensionNestedActor {
7476
// CHECK: @available(iOS 13.4, tvOS 13.4, watchOS 6.2, *)
75-
// CHECK-NEXT: @available(macOS, unavailable)
77+
// CHECK-NEXT: @available(macOS, unavailable, introduced: 10.15.4)
7678
// CHECK-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor {
7779
// CHECK-NEXT: get
7880
// CHECK-NEXT: }
7981
}
8082
}
83+
84+
// CHECK-PUBLIC: @available(macOS, unavailable)
85+
// CHECK-PUBLIC-NEXT: @available(iOS, unavailable)
86+
// CHECK-PUBLIC-NEXT: @available(watchOS, unavailable)
87+
// CHECK-PUBLIC-NEXT: @available(tvOS, unavailable)
88+
// CHECK-PUBLIC-NEXT: public struct SPIAvailableStruct
89+
// CHECK-PRIVATE: @_spi_available(macOS, introduced: 10.15.4)
90+
// CHECK-PRIVATE-NEXT: @_spi_available(iOS, introduced: 13.4)
91+
// CHECK-PRIVATE-NEXT: @_spi_available(watchOS, introduced: 6.2)
92+
// CHECK-PRIVATE-NEXT: @_spi_available(tvOS, introduced: 13.4)
93+
// CHECK-PRIVATE-NEXT: public struct SPIAvailableStruct
94+
@_spi_available(SwiftStdlib 5.2, *)
95+
public struct SPIAvailableStruct {
96+
// CHECK: #if compiler(>=5.3) && $Actors
97+
// CHECK-NEXT: @_hasMissingDesignatedInitializers @available(macOS, unavailable)
98+
// CHECK-NEXT: public actor UnavailableNestedActor
99+
@available(macOS, unavailable)
100+
public actor UnavailableNestedActor {
101+
// CHECK-PUBLIC: @available(iOS, unavailable)
102+
// CHECK-PUBLIC-NEXT: @available(tvOS, unavailable)
103+
// CHECK-PUBLIC-NEXT: @available(watchOS, unavailable)
104+
// CHECK-PUBLIC-NEXT: @available(macOS, unavailable)
105+
// CHECK-PUBLIC-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor
106+
// CHECK-PRIVATE: @_spi_available(iOS, introduced: 13.4)
107+
// CHECK-PRIVATE-NEXT: @_spi_available(tvOS, introduced: 13.4)
108+
// CHECK-PRIVATE-NEXT: @_spi_available(watchOS, introduced: 6.2)
109+
// CHECK-PRIVATE-NEXT: @_spi_available(macOS, unavailable, introduced: 10.15.4)
110+
// CHECK-PRIVATE-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor
111+
}
112+
}

test/Sema/availability_versions.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,12 +1731,11 @@ struct HasUnavailableExtension {
17311731

17321732
@available(OSX, unavailable)
17331733
extension HasUnavailableExtension {
1734-
// expected-note@-1 {{enclosing scope has been explicitly marked unavailable here}}
17351734

17361735
public func inheritsUnavailable() { }
17371736
// expected-note@-1 {{'inheritsUnavailable()' has been explicitly marked unavailable here}}
17381737

1739-
@available(OSX 10.9, *) // expected-warning {{instance method cannot be more available than unavailable enclosing scope}}
1738+
@available(OSX 10.9, *)
17401739
public func moreAvailableButStillUnavailable() { }
17411740
// expected-note@-1 {{'moreAvailableButStillUnavailable()' has been explicitly marked unavailable here}}
17421741
}

test/Sema/generalized_accessors_availability.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,20 @@ func testButtNested(x: inout Butt.Nested) { // expected-error {{'Nested' is unav
131131
x.$wrapped_modify_more_available = 0 // expected-error {{is unavailable in macOS}}
132132
}
133133

134+
@available(iOS, unavailable)
135+
@_spi_available(macOS, introduced: 10.51)
136+
extension Butt {
137+
struct NestedInSPIAvailableExtension {
138+
@available(macOS, unavailable)
139+
public var unavailable: Int // expected-note {{'unavailable' has been explicitly marked unavailable here}}
140+
}
141+
}
142+
143+
@available(macOS, introduced: 10.51)
144+
func testButtNested(x: inout Butt.NestedInSPIAvailableExtension) {
145+
x.unavailable = 0 // expected-error {{is unavailable in macOS}}
146+
}
147+
134148
@available(macOS 11.0, *)
135149
struct LessAvailable {
136150
@SetterConditionallyAvailable

test/attr/attr_availability_transitive_osx.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ extension Outer {
105105
}
106106

107107
@available(OSX, unavailable)
108-
// expected-note@+1 {{enclosing scope has been explicitly marked unavailable here}}
109108
extension Outer {
110109
// expected-note@+1 {{'outer_osx_init_osx' has been explicitly marked unavailable here}}
111110
static var outer_osx_init_osx = osx() // OK
@@ -124,7 +123,7 @@ extension Outer {
124123
}
125124

126125
// This @available should be ignored; inherited unavailability takes precedence
127-
@available(OSX 999, *) // expected-warning {{instance method cannot be more available than unavailable enclosing scope}}
126+
@available(OSX 999, *)
128127
// expected-note@+1 {{'osx_more_available_but_still_unavailable_call_osx()' has been explicitly marked unavailable here}}
129128
func osx_more_available_but_still_unavailable_call_osx() {
130129
osx() // OK

0 commit comments

Comments
 (0)