Sema: Suppress explicit availability diagnostics on non-Darwin targets.

Suggesting the addition of an `@available` attribute on Linux and Windows is
inapprorpriate given that Swift is not ABI stable on those platforms.

Resolves rdar://107387133
This commit is contained in:
Allan Shortlidge
2023-05-08 12:20:40 -07:00
parent 44489c77b2
commit 93a96e81c2
5 changed files with 43 additions and 9 deletions

View File

@@ -970,6 +970,9 @@ public:
/// Swift compiler for future versions of the target platform.
AvailabilityContext getSwiftFutureAvailability();
/// Returns `true` if versioned availability annotations are supported for the
/// target triple.
bool supportsVersionedAvailability() const;
//===--------------------------------------------------------------------===//
// Diagnostics Helper functions

View File

@@ -22,6 +22,7 @@
#include "swift/AST/TypeCheckRequests.h"
#include "swift/AST/TypeWalker.h"
#include "swift/AST/Types.h"
#include "swift/Basic/Platform.h"
#include <map>
using namespace swift;
@@ -706,3 +707,7 @@ ASTContext::getSwift5PlusAvailability(llvm::VersionTuple swiftVersion) {
Twine("Missing call to getSwiftXYAvailability for Swift ") +
swiftVersion.getAsString());
}
bool ASTContext::supportsVersionedAvailability() const {
return minimumAvailableOSVersionForTriple(LangOpts.Target).has_value();
}

View File

@@ -4260,6 +4260,13 @@ swift::diagnoseSubstitutionMapAvailability(SourceLoc loc,
/// Should we warn that \p decl needs an explicit availability annotation
/// in -require-explicit-availability mode?
static bool declNeedsExplicitAvailability(const Decl *decl) {
auto &ctx = decl->getASTContext();
// Don't require an introduced version on platforms that don't support
// versioned availability.
if (!ctx.supportsVersionedAvailability())
return false;
// Skip non-public decls.
if (auto valueDecl = dyn_cast<const ValueDecl>(decl)) {
AccessScope scope =
@@ -4280,7 +4287,6 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
return false;
// Warn on decls without an introduction version.
auto &ctx = decl->getASTContext();
auto safeRangeUnderApprox = AvailabilityInference::availableRange(decl, ctx);
return !safeRangeUnderApprox.getOSVersion().hasLowerEndpoint();
}
@@ -4288,9 +4294,9 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
void swift::checkExplicitAvailability(Decl *decl) {
// Skip if the command line option was not set and
// accessors as we check the pattern binding decl instead.
auto DiagLevel = decl->getASTContext().LangOpts.RequireExplicitAvailability;
if (!DiagLevel ||
isa<AccessorDecl>(decl))
auto &ctx = decl->getASTContext();
auto DiagLevel = ctx.LangOpts.RequireExplicitAvailability;
if (!DiagLevel || isa<AccessorDecl>(decl))
return;
// Only look at decls at module level or in extensions.
@@ -4335,8 +4341,7 @@ void swift::checkExplicitAvailability(Decl *decl) {
auto diag = decl->diagnose(diag::public_decl_needs_availability);
diag.limitBehavior(*DiagLevel);
auto suggestPlatform =
decl->getASTContext().LangOpts.RequireExplicitAvailabilityTarget;
auto suggestPlatform = ctx.LangOpts.RequireExplicitAvailabilityTarget;
if (!suggestPlatform.empty()) {
auto InsertLoc = decl->getAttrs().getStartLoc(/*forModifiers=*/false);
if (InsertLoc.isInvalid())
@@ -4349,7 +4354,6 @@ void swift::checkExplicitAvailability(Decl *decl) {
{
llvm::raw_string_ostream Out(AttrText);
auto &ctx = decl->getASTContext();
StringRef OriginalIndent = Lexer::getIndentationForLine(
ctx.SourceMgr, InsertLoc);
Out << "@available(" << suggestPlatform << ", *)\n"

View File

@@ -7,7 +7,8 @@
// RUN: %target-swift-frontend -emit-module %t/APILib.swift -I %t \
// RUN: -swift-version 5 -verify \
// RUN: -experimental-spi-only-imports \
// RUN: -library-level api
// RUN: -library-level api \
// RUN: -require-explicit-availability=ignore
// RUN: %target-swift-frontend -emit-module %t/SPILib.swift -I %t \
// RUN: -swift-version 5 -verify \
// RUN: -experimental-spi-only-imports \
@@ -25,7 +26,6 @@ public struct LibStruct {}
@_spiOnly import Lib
public func publicClient() -> LibStruct { fatalError() } // expected-error {{cannot use struct 'LibStruct' here; 'Lib' was imported for SPI only}}
// expected-warning @-1 {{public declarations should have an availability attribute with an introduction version}}
@_spi(X) public func spiClient() -> LibStruct { fatalError() }
//--- SPILib.swift

View File

@@ -0,0 +1,22 @@
// Test that the -require-explicit-availability flag does not cause diagnostics
// to be emitted on platforms where versioned availability annotations are not
// meaningful.
// RUN: %target-swift-frontend -typecheck -parse-as-library -verify %s -require-explicit-availability=error
// Currently versioned availability should only be required on Apple platforms.
// UNSUPPORTED: VENDOR=apple
public struct NoAvailabilityStruct {
public func method() { }
}
@available(*, unavailable)
public struct UnavailableStruct {
public func okMethod() { }
}
public func noAvailabilityFunc() { }
@available(SwiftStdlib 5.9, *)
public func stdlib5_9AvailabilityFunc() { }