Skip to content

Commit dcbef35

Browse files
committed
[Sema] Intro flag to promote to an error missing explicit availability
1 parent 8f256ad commit dcbef35

File tree

8 files changed

+64
-16
lines changed

8 files changed

+64
-16
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ ERROR(error_unknown_library_level, none,
4848
"unknown library level '%0', "
4949
"expected one of 'api', 'spi' or 'other'", (StringRef))
5050

51+
ERROR(error_unknown_require_explicit_availability, none,
52+
"unknown argument '%0', passed to -require-explicit-availability, "
53+
"expected 'error', 'warn' or 'ignore'",
54+
(StringRef))
55+
5156
ERROR(error_unsupported_opt_for_target, none,
5257
"unsupported option '%0' for target '%1'", (StringRef, StringRef))
5358

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5749,9 +5749,9 @@ ERROR(availability_protocol_requires_version,
57495749
NOTE(availability_protocol_requirement_here, none,
57505750
"protocol requirement here", ())
57515751

5752-
WARNING(public_decl_needs_availability, none,
5753-
"public declarations should have an availability attribute "
5754-
"with an introduction version", ())
5752+
ERROR(public_decl_needs_availability, none,
5753+
"public declarations should have an availability attribute "
5754+
"with an introduction version", ())
57555755

57565756
ERROR(attr_requires_decl_availability_for_platform,none,
57575757
"'%0' requires that %1 have explicit availability for %2",

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,9 @@ namespace swift {
193193
/// Enable 'availability' restrictions for App Extensions.
194194
bool EnableAppExtensionRestrictions = false;
195195

196-
/// Require public declarations to declare an introduction OS version.
197-
bool RequireExplicitAvailability = false;
196+
/// Diagnostic level to report when a public declarations doesn't declare
197+
/// an introduction OS version.
198+
Optional<DiagnosticBehavior> RequireExplicitAvailability = None;
198199

199200
/// Introduction platform and version to suggest as fix-it
200201
/// when using RequireExplicitAvailability.

include/swift/Option/Options.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,13 @@ def enable_library_evolution : Flag<["-"], "enable-library-evolution">,
411411

412412
def require_explicit_availability : Flag<["-"], "require-explicit-availability">,
413413
Flags<[FrontendOption, NoInteractiveOption]>,
414-
HelpText<"Require explicit availability on public declarations">;
414+
HelpText<"Warn on public declarations without an availability attribute">;
415+
416+
def require_explicit_availability_EQ : Joined<["-"], "require-explicit-availability=">,
417+
MetaVarName<"<error,warn,ignore>">,
418+
Flags<[FrontendOption, NoInteractiveOption]>,
419+
HelpText<"Set diagnostic level to report public declarations without an availability attribute">;
420+
415421
def require_explicit_availability_target : Separate<["-"], "require-explicit-availability-target">,
416422
Flags<[FrontendOption, NoInteractiveOption]>,
417423
HelpText<"Suggest fix-its adding @available(<target>, *) to public declarations without availability">,

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
241241
inputArgs.AddLastArg(arguments, options::OPT_enable_library_evolution);
242242
inputArgs.AddLastArg(arguments, options::OPT_require_explicit_availability);
243243
inputArgs.AddLastArg(arguments, options::OPT_require_explicit_availability_target);
244+
inputArgs.AddLastArg(arguments, options::OPT_require_explicit_availability_EQ);
244245
inputArgs.AddLastArg(arguments, options::OPT_require_explicit_sendable);
245246
inputArgs.AddLastArg(arguments, options::OPT_check_api_availability_only);
246247
inputArgs.AddLastArg(arguments, options::OPT_enable_testing);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -587,13 +587,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
587587
if (Args.getLastArg(OPT_debug_cycles))
588588
Opts.DebugDumpCycles = true;
589589

590-
if (Args.getLastArg(OPT_require_explicit_availability, OPT_require_explicit_availability_target)) {
591-
Opts.RequireExplicitAvailability = true;
592-
if (const Arg *A = Args.getLastArg(OPT_require_explicit_availability_target)) {
593-
Opts.RequireExplicitAvailabilityTarget = A->getValue();
594-
}
595-
}
596-
597590
Opts.RequireExplicitSendable |= Args.hasArg(OPT_require_explicit_sendable);
598591
for (const Arg *A : Args.filtered(OPT_define_availability)) {
599592
Opts.AvailabilityMacros.push_back(A->getValue());
@@ -721,6 +714,28 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
721714
}
722715
}
723716

717+
if (const Arg *A = Args.getLastArg(OPT_require_explicit_availability_EQ)) {
718+
StringRef diagLevel = A->getValue();
719+
if (diagLevel == "warn") {
720+
Opts.RequireExplicitAvailability = DiagnosticBehavior::Warning;
721+
} else if (diagLevel == "error") {
722+
Opts.RequireExplicitAvailability = DiagnosticBehavior::Error;
723+
} else if (diagLevel == "ignore") {
724+
Opts.RequireExplicitAvailability = None;
725+
} else {
726+
Diags.diagnose(SourceLoc(),
727+
diag::error_unknown_require_explicit_availability,
728+
diagLevel);
729+
}
730+
} else if (Args.getLastArg(OPT_require_explicit_availability,
731+
OPT_require_explicit_availability_target)) {
732+
Opts.RequireExplicitAvailability = DiagnosticBehavior::Warning;
733+
}
734+
735+
if (const Arg *A = Args.getLastArg(OPT_require_explicit_availability_target)) {
736+
Opts.RequireExplicitAvailabilityTarget = A->getValue();
737+
}
738+
724739
Opts.EnableSPIOnlyImports = Args.hasArg(OPT_experimental_spi_only_imports);
725740

726741
if (Opts.EnableSwift3ObjCInference) {

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4279,7 +4279,8 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
42794279
void swift::checkExplicitAvailability(Decl *decl) {
42804280
// Skip if the command line option was not set and
42814281
// accessors as we check the pattern binding decl instead.
4282-
if (!decl->getASTContext().LangOpts.RequireExplicitAvailability ||
4282+
auto DiagLevel = decl->getASTContext().LangOpts.RequireExplicitAvailability;
4283+
if (!DiagLevel ||
42834284
isa<AccessorDecl>(decl))
42844285
return;
42854286

@@ -4323,6 +4324,7 @@ void swift::checkExplicitAvailability(Decl *decl) {
43234324

43244325
if (declNeedsExplicitAvailability(decl)) {
43254326
auto diag = decl->diagnose(diag::public_decl_needs_availability);
4327+
diag.limitBehavior(*DiagLevel);
43264328

43274329
auto suggestPlatform =
43284330
decl->getASTContext().LangOpts.RequireExplicitAvailabilityTarget;

test/attr/require_explicit_availability.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
// Test the -require-explicit-availability flag
22
// REQUIRES: OS=macosx
3-
4-
// RUN: %swiftc_driver -typecheck -parse-as-library -target %target-cpu-apple-macosx10.10 -Xfrontend -verify -require-explicit-availability -require-explicit-availability-target "macOS 10.10" %s
3+
// RUN: %empty-directory(%t)
4+
5+
/// Using the flag directly raises warnings and fixits.
6+
// RUN: %swiftc_driver -typecheck -parse-as-library -Xfrontend -verify %s \
7+
// RUN: -target %target-cpu-apple-macosx10.10 -require-explicit-availability \
8+
// RUN: -require-explicit-availability-target "macOS 10.10"
9+
// RUN: %swiftc_driver -typecheck -parse-as-library -Xfrontend -verify %s \
10+
// RUN: -target %target-cpu-apple-macosx10.10 -require-explicit-availability=warn \
11+
// RUN: -require-explicit-availability-target "macOS 10.10"
12+
13+
/// Upgrade the diagnostic to an error.
14+
// RUN: sed -e "s/xpected-warning/xpected-error/" < %s > %t/Errors.swift
15+
// RUN: %target-swift-frontend -typecheck -parse-as-library -verify %t/Errors.swift \
16+
// RUN: -target %target-cpu-apple-macosx10.10 -require-explicit-availability=error \
17+
// RUN: -require-explicit-availability-target "macOS 10.10"
18+
19+
/// Error on an invalid argument.
20+
// RUN: not %target-swift-frontend -typecheck %s -require-explicit-availability=NotIt 2>&1 \
21+
// RUN: | %FileCheck %s --check-prefix CHECK-ARG
22+
// CHECK-ARG: error: unknown argument 'NotIt', passed to -require-explicit-availability, expected 'error', 'warn' or 'ignore'
523

624
public struct S { // expected-warning {{public declarations should have an availability attribute with an introduction version}}
725
public func method() { }

0 commit comments

Comments
 (0)