Skip to content

Sema: Suppress explicit availability diagnostics on non-Darwin targets #65772

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
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
3 changes: 3 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,9 @@ class ASTContext final {
/// 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
Expand Down
5 changes: 5 additions & 0 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
18 changes: 11 additions & 7 deletions lib/Sema/TypeCheckAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -4280,17 +4287,16 @@ 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();
}

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.
Expand Down Expand Up @@ -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())
Expand All @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions test/SPI/spi-only-and-library-level.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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
Expand Down
22 changes: 22 additions & 0 deletions test/attr/require_explicit_availability_non_darwin.swift
Original file line number Diff line number Diff line change
@@ -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() { }