mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
22
test/attr/require_explicit_availability_non_darwin.swift
Normal file
22
test/attr/require_explicit_availability_non_darwin.swift
Normal 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() { }
|
||||
Reference in New Issue
Block a user