Skip to content

Sema: Don't diagnose declarations more available than unavailable container #64515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5990,10 +5990,6 @@ ERROR(availability_decl_more_than_enclosing, none,
"%0 cannot be more available than enclosing scope",
(DescriptiveDeclKind))

WARNING(availability_decl_more_than_unavailable_enclosing, none,
"%0 cannot be more available than unavailable enclosing scope",
(DescriptiveDeclKind))

NOTE(availability_implicit_decl_here, none,
"%0 implicitly declared here with availability of %1 %2 or newer",
(DescriptiveDeclKind, StringRef, llvm::VersionTuple))
Expand Down
30 changes: 0 additions & 30 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,6 @@ static AvailableAttr *createAvailableAttr(PlatformKind Platform,
llvm::VersionTuple Obsoleted =
Inferred.Obsoleted.value_or(llvm::VersionTuple());

// If a decl is unavailable then it cannot have any introduced, deprecated, or
// obsoleted version.
if (Inferred.PlatformAgnostic ==
PlatformAgnosticAvailabilityKind::Unavailable) {
Introduced = llvm::VersionTuple();
Deprecated = llvm::VersionTuple();
Obsoleted = llvm::VersionTuple();
}

return new (Context)
AvailableAttr(SourceLoc(), SourceRange(), Platform,
Message, Rename, RenameDecl,
Expand Down Expand Up @@ -168,27 +159,6 @@ void AvailabilityInference::applyInferredAvailableAttrs(

DeclAttributes &Attrs = ToDecl->getAttrs();

// Some kinds of platform agnostic availability supersede any platform
// specific availability.
auto InferredAgnostic = Inferred.find(PlatformKind::none);
if (InferredAgnostic != Inferred.end()) {
switch (InferredAgnostic->second.PlatformAgnostic) {
case PlatformAgnosticAvailabilityKind::Deprecated:
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
case PlatformAgnosticAvailabilityKind::Unavailable:
Attrs.add(createAvailableAttr(PlatformKind::none,
InferredAgnostic->second, Message, Rename,
RenameDecl, Context));
return;

case PlatformAgnosticAvailabilityKind::None:
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
case PlatformAgnosticAvailabilityKind::NoAsync:
break;
}
}

// Create an availability attribute for each observed platform and add
// to ToDecl.
for (auto &Pair : Inferred) {
Expand Down
12 changes: 1 addition & 11 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1945,17 +1945,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
AvailabilityInference::availableRange(attr, Ctx);

if (auto *parent = getEnclosingDeclForDecl(D)) {
if (auto enclosingUnavailable = parent->getSemanticUnavailableAttr()) {
if (!AttrRange.isKnownUnreachable()) {
const Decl *enclosingDecl = enclosingUnavailable.value().second;
diagnose(D->isImplicit() ? enclosingDecl->getLoc()
: attr->getLocation(),
diag::availability_decl_more_than_unavailable_enclosing,
D->getDescriptiveKind());
diagnose(parent->getLoc(),
diag::availability_decl_more_than_unavailable_enclosing_here);
}
} else if (auto enclosingAvailable =
if (auto enclosingAvailable =
parent->getSemanticAvailableRangeAttr()) {
const AvailableAttr *enclosingAttr = enclosingAvailable.value().first;
const Decl *enclosingDecl = enclosingAvailable.value().second;
Expand Down
40 changes: 36 additions & 4 deletions test/ModuleInterface/actor_availability.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -module-name Library -target %target-swift-abi-5.3-triple
// RUN: %target-swift-emit-module-interfaces(%t/Library.swiftinterface, %t/Library.private.swiftinterface) %s -module-name Library -target %target-swift-abi-5.3-triple
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -module-name Library
// RUN: %FileCheck %s < %t/Library.swiftinterface
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.private.swiftinterface) -module-name Library
// RUN: %FileCheck %s --check-prefixes=CHECK,CHECK-PUBLIC < %t/Library.swiftinterface
// RUN: %FileCheck %s --check-prefixes=CHECK,CHECK-PRIVATE < %t/Library.private.swiftinterface

// REQUIRES: VENDOR=apple

Expand Down Expand Up @@ -33,7 +35,7 @@ public actor ActorWithExplicitAvailability {
@available(macOS, unavailable)
public actor UnavailableActor {
// CHECK: @available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
// CHECK-NEXT: @available(macOS, unavailable)
// CHECK-NEXT: @available(macOS, unavailable, introduced: 10.15)
// CHECK-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor {
// CHECK-NEXT: get
// CHECK-NEXT: }
Expand Down Expand Up @@ -72,9 +74,39 @@ extension Enum {
@available(macOS, unavailable)
public actor UnavailableExtensionNestedActor {
// CHECK: @available(iOS 13.4, tvOS 13.4, watchOS 6.2, *)
// CHECK-NEXT: @available(macOS, unavailable)
// CHECK-NEXT: @available(macOS, unavailable, introduced: 10.15.4)
// CHECK-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor {
// CHECK-NEXT: get
// CHECK-NEXT: }
}
}

// CHECK-PUBLIC: @available(macOS, unavailable)
// CHECK-PUBLIC-NEXT: @available(iOS, unavailable)
// CHECK-PUBLIC-NEXT: @available(watchOS, unavailable)
// CHECK-PUBLIC-NEXT: @available(tvOS, unavailable)
// CHECK-PUBLIC-NEXT: public struct SPIAvailableStruct
// CHECK-PRIVATE: @_spi_available(macOS, introduced: 10.15.4)
// CHECK-PRIVATE-NEXT: @_spi_available(iOS, introduced: 13.4)
// CHECK-PRIVATE-NEXT: @_spi_available(watchOS, introduced: 6.2)
// CHECK-PRIVATE-NEXT: @_spi_available(tvOS, introduced: 13.4)
// CHECK-PRIVATE-NEXT: public struct SPIAvailableStruct
@_spi_available(SwiftStdlib 5.2, *)
public struct SPIAvailableStruct {
// CHECK: #if compiler(>=5.3) && $Actors
// CHECK-NEXT: @_hasMissingDesignatedInitializers @available(macOS, unavailable)
// CHECK-NEXT: public actor UnavailableNestedActor
@available(macOS, unavailable)
public actor UnavailableNestedActor {
// CHECK-PUBLIC: @available(iOS, unavailable)
// CHECK-PUBLIC-NEXT: @available(tvOS, unavailable)
// CHECK-PUBLIC-NEXT: @available(watchOS, unavailable)
// CHECK-PUBLIC-NEXT: @available(macOS, unavailable)
// CHECK-PUBLIC-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor
// CHECK-PRIVATE: @_spi_available(iOS, introduced: 13.4)
// CHECK-PRIVATE-NEXT: @_spi_available(tvOS, introduced: 13.4)
// CHECK-PRIVATE-NEXT: @_spi_available(watchOS, introduced: 6.2)
// CHECK-PRIVATE-NEXT: @_spi_available(macOS, unavailable, introduced: 10.15.4)
// CHECK-PRIVATE-NEXT: @_semantics("defaultActor") nonisolated final public var unownedExecutor: _Concurrency.UnownedSerialExecutor
}
}
3 changes: 1 addition & 2 deletions test/Sema/availability_versions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1731,12 +1731,11 @@ struct HasUnavailableExtension {

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

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

@available(OSX 10.9, *) // expected-warning {{instance method cannot be more available than unavailable enclosing scope}}
@available(OSX 10.9, *)
public func moreAvailableButStillUnavailable() { }
// expected-note@-1 {{'moreAvailableButStillUnavailable()' has been explicitly marked unavailable here}}
}
Expand Down
14 changes: 14 additions & 0 deletions test/Sema/generalized_accessors_availability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ func testButtNested(x: inout Butt.Nested) { // expected-error {{'Nested' is unav
x.$wrapped_modify_more_available = 0 // expected-error {{is unavailable in macOS}}
}

@available(iOS, unavailable)
@_spi_available(macOS, introduced: 10.51)
extension Butt {
struct NestedInSPIAvailableExtension {
@available(macOS, unavailable)
public var unavailable: Int // expected-note {{'unavailable' has been explicitly marked unavailable here}}
}
}

@available(macOS, introduced: 10.51)
func testButtNested(x: inout Butt.NestedInSPIAvailableExtension) {
x.unavailable = 0 // expected-error {{is unavailable in macOS}}
}

@available(macOS 11.0, *)
struct LessAvailable {
@SetterConditionallyAvailable
Expand Down
3 changes: 1 addition & 2 deletions test/attr/attr_availability_transitive_osx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ extension Outer {
}

@available(OSX, unavailable)
// expected-note@+1 {{enclosing scope has been explicitly marked unavailable here}}
extension Outer {
// expected-note@+1 {{'outer_osx_init_osx' has been explicitly marked unavailable here}}
static var outer_osx_init_osx = osx() // OK
Expand All @@ -124,7 +123,7 @@ extension Outer {
}

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