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.
|
/// Swift compiler for future versions of the target platform.
|
||||||
AvailabilityContext getSwiftFutureAvailability();
|
AvailabilityContext getSwiftFutureAvailability();
|
||||||
|
|
||||||
|
/// Returns `true` if versioned availability annotations are supported for the
|
||||||
|
/// target triple.
|
||||||
|
bool supportsVersionedAvailability() const;
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Diagnostics Helper functions
|
// Diagnostics Helper functions
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "swift/AST/TypeCheckRequests.h"
|
#include "swift/AST/TypeCheckRequests.h"
|
||||||
#include "swift/AST/TypeWalker.h"
|
#include "swift/AST/TypeWalker.h"
|
||||||
#include "swift/AST/Types.h"
|
#include "swift/AST/Types.h"
|
||||||
|
#include "swift/Basic/Platform.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
@@ -706,3 +707,7 @@ ASTContext::getSwift5PlusAvailability(llvm::VersionTuple swiftVersion) {
|
|||||||
Twine("Missing call to getSwiftXYAvailability for Swift ") +
|
Twine("Missing call to getSwiftXYAvailability for Swift ") +
|
||||||
swiftVersion.getAsString());
|
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
|
/// Should we warn that \p decl needs an explicit availability annotation
|
||||||
/// in -require-explicit-availability mode?
|
/// in -require-explicit-availability mode?
|
||||||
static bool declNeedsExplicitAvailability(const Decl *decl) {
|
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.
|
// Skip non-public decls.
|
||||||
if (auto valueDecl = dyn_cast<const ValueDecl>(decl)) {
|
if (auto valueDecl = dyn_cast<const ValueDecl>(decl)) {
|
||||||
AccessScope scope =
|
AccessScope scope =
|
||||||
@@ -4280,7 +4287,6 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Warn on decls without an introduction version.
|
// Warn on decls without an introduction version.
|
||||||
auto &ctx = decl->getASTContext();
|
|
||||||
auto safeRangeUnderApprox = AvailabilityInference::availableRange(decl, ctx);
|
auto safeRangeUnderApprox = AvailabilityInference::availableRange(decl, ctx);
|
||||||
return !safeRangeUnderApprox.getOSVersion().hasLowerEndpoint();
|
return !safeRangeUnderApprox.getOSVersion().hasLowerEndpoint();
|
||||||
}
|
}
|
||||||
@@ -4288,9 +4294,9 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
|
|||||||
void swift::checkExplicitAvailability(Decl *decl) {
|
void swift::checkExplicitAvailability(Decl *decl) {
|
||||||
// Skip if the command line option was not set and
|
// Skip if the command line option was not set and
|
||||||
// accessors as we check the pattern binding decl instead.
|
// accessors as we check the pattern binding decl instead.
|
||||||
auto DiagLevel = decl->getASTContext().LangOpts.RequireExplicitAvailability;
|
auto &ctx = decl->getASTContext();
|
||||||
if (!DiagLevel ||
|
auto DiagLevel = ctx.LangOpts.RequireExplicitAvailability;
|
||||||
isa<AccessorDecl>(decl))
|
if (!DiagLevel || isa<AccessorDecl>(decl))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Only look at decls at module level or in extensions.
|
// 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);
|
auto diag = decl->diagnose(diag::public_decl_needs_availability);
|
||||||
diag.limitBehavior(*DiagLevel);
|
diag.limitBehavior(*DiagLevel);
|
||||||
|
|
||||||
auto suggestPlatform =
|
auto suggestPlatform = ctx.LangOpts.RequireExplicitAvailabilityTarget;
|
||||||
decl->getASTContext().LangOpts.RequireExplicitAvailabilityTarget;
|
|
||||||
if (!suggestPlatform.empty()) {
|
if (!suggestPlatform.empty()) {
|
||||||
auto InsertLoc = decl->getAttrs().getStartLoc(/*forModifiers=*/false);
|
auto InsertLoc = decl->getAttrs().getStartLoc(/*forModifiers=*/false);
|
||||||
if (InsertLoc.isInvalid())
|
if (InsertLoc.isInvalid())
|
||||||
@@ -4349,7 +4354,6 @@ void swift::checkExplicitAvailability(Decl *decl) {
|
|||||||
{
|
{
|
||||||
llvm::raw_string_ostream Out(AttrText);
|
llvm::raw_string_ostream Out(AttrText);
|
||||||
|
|
||||||
auto &ctx = decl->getASTContext();
|
|
||||||
StringRef OriginalIndent = Lexer::getIndentationForLine(
|
StringRef OriginalIndent = Lexer::getIndentationForLine(
|
||||||
ctx.SourceMgr, InsertLoc);
|
ctx.SourceMgr, InsertLoc);
|
||||||
Out << "@available(" << suggestPlatform << ", *)\n"
|
Out << "@available(" << suggestPlatform << ", *)\n"
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
// RUN: %target-swift-frontend -emit-module %t/APILib.swift -I %t \
|
// RUN: %target-swift-frontend -emit-module %t/APILib.swift -I %t \
|
||||||
// RUN: -swift-version 5 -verify \
|
// RUN: -swift-version 5 -verify \
|
||||||
// RUN: -experimental-spi-only-imports \
|
// 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: %target-swift-frontend -emit-module %t/SPILib.swift -I %t \
|
||||||
// RUN: -swift-version 5 -verify \
|
// RUN: -swift-version 5 -verify \
|
||||||
// RUN: -experimental-spi-only-imports \
|
// RUN: -experimental-spi-only-imports \
|
||||||
@@ -25,7 +26,6 @@ public struct LibStruct {}
|
|||||||
@_spiOnly import Lib
|
@_spiOnly import Lib
|
||||||
|
|
||||||
public func publicClient() -> LibStruct { fatalError() } // expected-error {{cannot use struct 'LibStruct' here; 'Lib' was imported for SPI only}}
|
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() }
|
@_spi(X) public func spiClient() -> LibStruct { fatalError() }
|
||||||
|
|
||||||
//--- SPILib.swift
|
//--- 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