Skip to content

Commit 93a96e8

Browse files
committed
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
1 parent 44489c7 commit 93a96e8

File tree

5 files changed

+43
-9
lines changed

5 files changed

+43
-9
lines changed

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,9 @@ class ASTContext final {
970970
/// Swift compiler for future versions of the target platform.
971971
AvailabilityContext getSwiftFutureAvailability();
972972

973+
/// Returns `true` if versioned availability annotations are supported for the
974+
/// target triple.
975+
bool supportsVersionedAvailability() const;
973976

974977
//===--------------------------------------------------------------------===//
975978
// Diagnostics Helper functions

lib/AST/Availability.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/TypeCheckRequests.h"
2323
#include "swift/AST/TypeWalker.h"
2424
#include "swift/AST/Types.h"
25+
#include "swift/Basic/Platform.h"
2526
#include <map>
2627

2728
using namespace swift;
@@ -706,3 +707,7 @@ ASTContext::getSwift5PlusAvailability(llvm::VersionTuple swiftVersion) {
706707
Twine("Missing call to getSwiftXYAvailability for Swift ") +
707708
swiftVersion.getAsString());
708709
}
710+
711+
bool ASTContext::supportsVersionedAvailability() const {
712+
return minimumAvailableOSVersionForTriple(LangOpts.Target).has_value();
713+
}

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4260,6 +4260,13 @@ swift::diagnoseSubstitutionMapAvailability(SourceLoc loc,
42604260
/// Should we warn that \p decl needs an explicit availability annotation
42614261
/// in -require-explicit-availability mode?
42624262
static bool declNeedsExplicitAvailability(const Decl *decl) {
4263+
auto &ctx = decl->getASTContext();
4264+
4265+
// Don't require an introduced version on platforms that don't support
4266+
// versioned availability.
4267+
if (!ctx.supportsVersionedAvailability())
4268+
return false;
4269+
42634270
// Skip non-public decls.
42644271
if (auto valueDecl = dyn_cast<const ValueDecl>(decl)) {
42654272
AccessScope scope =
@@ -4280,17 +4287,16 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
42804287
return false;
42814288

42824289
// Warn on decls without an introduction version.
4283-
auto &ctx = decl->getASTContext();
42844290
auto safeRangeUnderApprox = AvailabilityInference::availableRange(decl, ctx);
42854291
return !safeRangeUnderApprox.getOSVersion().hasLowerEndpoint();
42864292
}
42874293

42884294
void swift::checkExplicitAvailability(Decl *decl) {
42894295
// Skip if the command line option was not set and
42904296
// accessors as we check the pattern binding decl instead.
4291-
auto DiagLevel = decl->getASTContext().LangOpts.RequireExplicitAvailability;
4292-
if (!DiagLevel ||
4293-
isa<AccessorDecl>(decl))
4297+
auto &ctx = decl->getASTContext();
4298+
auto DiagLevel = ctx.LangOpts.RequireExplicitAvailability;
4299+
if (!DiagLevel || isa<AccessorDecl>(decl))
42944300
return;
42954301

42964302
// Only look at decls at module level or in extensions.
@@ -4335,8 +4341,7 @@ void swift::checkExplicitAvailability(Decl *decl) {
43354341
auto diag = decl->diagnose(diag::public_decl_needs_availability);
43364342
diag.limitBehavior(*DiagLevel);
43374343

4338-
auto suggestPlatform =
4339-
decl->getASTContext().LangOpts.RequireExplicitAvailabilityTarget;
4344+
auto suggestPlatform = ctx.LangOpts.RequireExplicitAvailabilityTarget;
43404345
if (!suggestPlatform.empty()) {
43414346
auto InsertLoc = decl->getAttrs().getStartLoc(/*forModifiers=*/false);
43424347
if (InsertLoc.isInvalid())
@@ -4349,7 +4354,6 @@ void swift::checkExplicitAvailability(Decl *decl) {
43494354
{
43504355
llvm::raw_string_ostream Out(AttrText);
43514356

4352-
auto &ctx = decl->getASTContext();
43534357
StringRef OriginalIndent = Lexer::getIndentationForLine(
43544358
ctx.SourceMgr, InsertLoc);
43554359
Out << "@available(" << suggestPlatform << ", *)\n"

test/SPI/spi-only-and-library-level.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
// RUN: %target-swift-frontend -emit-module %t/APILib.swift -I %t \
88
// RUN: -swift-version 5 -verify \
99
// RUN: -experimental-spi-only-imports \
10-
// RUN: -library-level api
10+
// RUN: -library-level api \
11+
// RUN: -require-explicit-availability=ignore
1112
// RUN: %target-swift-frontend -emit-module %t/SPILib.swift -I %t \
1213
// RUN: -swift-version 5 -verify \
1314
// RUN: -experimental-spi-only-imports \
@@ -25,7 +26,6 @@ public struct LibStruct {}
2526
@_spiOnly import Lib
2627

2728
public func publicClient() -> LibStruct { fatalError() } // expected-error {{cannot use struct 'LibStruct' here; 'Lib' was imported for SPI only}}
28-
// expected-warning @-1 {{public declarations should have an availability attribute with an introduction version}}
2929
@_spi(X) public func spiClient() -> LibStruct { fatalError() }
3030

3131
//--- SPILib.swift
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Test that the -require-explicit-availability flag does not cause diagnostics
2+
// to be emitted on platforms where versioned availability annotations are not
3+
// meaningful.
4+
5+
// RUN: %target-swift-frontend -typecheck -parse-as-library -verify %s -require-explicit-availability=error
6+
7+
// Currently versioned availability should only be required on Apple platforms.
8+
// UNSUPPORTED: VENDOR=apple
9+
10+
public struct NoAvailabilityStruct {
11+
public func method() { }
12+
}
13+
14+
@available(*, unavailable)
15+
public struct UnavailableStruct {
16+
public func okMethod() { }
17+
}
18+
19+
public func noAvailabilityFunc() { }
20+
21+
@available(SwiftStdlib 5.9, *)
22+
public func stdlib5_9AvailabilityFunc() { }

0 commit comments

Comments
 (0)