Skip to content

Commit b207c89

Browse files
authored
Merge pull request #37843 from slavapestov/unavailable-enum-case-warning
Sema: Downgrade potentially unavailable enum cases to a warning in module interfaces
2 parents 666f62e + 765ce78 commit b207c89

File tree

8 files changed

+54
-3
lines changed

8 files changed

+54
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5344,6 +5344,10 @@ ERROR(availability_enum_element_no_potential,
53445344
none, "enum cases with associated values cannot be marked potentially unavailable with "
53455345
"'@available'", ())
53465346

5347+
WARNING(availability_enum_element_no_potential_warn,
5348+
none, "enum cases with associated values cannot be marked potentially unavailable with "
5349+
"'@available'", ())
5350+
53475351
ERROR(availability_protocol_requires_version,
53485352
none, "protocol %0 requires %1 to be available in %2 %3 and newer",
53495353
(Identifier, DeclName, StringRef, llvm::VersionTuple))

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ namespace swift {
134134
/// Should conformance availability violations be diagnosed as errors?
135135
bool EnableConformanceAvailabilityErrors = false;
136136

137+
/// Should potential unavailability on enum cases be downgraded to a warning?
138+
bool WarnOnPotentiallyUnavailableEnumCase = false;
139+
137140
/// Maximum number of typo corrections we are allowed to perform.
138141
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
139142
unsigned TypoCorrectionLimit = 0;

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ def disable_conformance_availability_errors : Flag<["-"],
453453
"disable-conformance-availability-errors">,
454454
HelpText<"Diagnose conformance availability violations as warnings">;
455455

456+
def warn_on_potentially_unavailable_enum_case : Flag<["-"],
457+
"warn-on-potentially-unavailable-enum-case">,
458+
HelpText<"Downgrade potential unavailability of enum case to a warning">;
459+
456460
def report_errors_to_debugger : Flag<["-"], "report-errors-to-debugger">,
457461
HelpText<"Deprecated, will be removed in future versions.">;
458462

lib/Driver/ToolChains.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
175175
arguments.push_back("-aarch64-use-tbi");
176176
}
177177

178+
if (output.getPrimaryOutputType() == file_types::TY_SwiftModuleFile) {
179+
arguments.push_back("-warn-on-potentially-unavailable-enum-case");
180+
}
181+
178182
// Enable or disable ObjC interop appropriately for the platform
179183
if (Triple.isOSDarwin()) {
180184
arguments.push_back("-enable-objc-interop");

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
457457
= A->getOption().matches(OPT_enable_conformance_availability_errors);
458458
}
459459

460+
Opts.WarnOnPotentiallyUnavailableEnumCase |=
461+
Args.hasArg(OPT_warn_on_potentially_unavailable_enum_case);
460462
if (auto A = Args.getLastArg(OPT_enable_access_control,
461463
OPT_disable_access_control)) {
462464
Opts.EnableAccessControl

lib/Sema/TypeCheckAttr.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3367,6 +3367,8 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
33673367

33683368
Optional<Diag<>>
33693369
TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
3370+
auto *DC = D->getDeclContext();
3371+
33703372
if (auto *VD = dyn_cast<VarDecl>(D)) {
33713373
if (!VD->hasStorage())
33723374
return None;
@@ -3379,14 +3381,23 @@ TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
33793381

33803382
// Globals and statics are lazily initialized, so they are safe
33813383
// for potential unavailability.
3382-
if (!VD->isStatic() && !VD->getDeclContext()->isModuleScopeContext())
3384+
if (!VD->isStatic() && !DC->isModuleScopeContext())
33833385
return diag::availability_stored_property_no_potential;
33843386

33853387
} else if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
33863388
// An enum element with an associated value cannot be potentially
33873389
// unavailable.
3388-
if (EED->hasAssociatedValues())
3389-
return diag::availability_enum_element_no_potential;
3390+
if (EED->hasAssociatedValues()) {
3391+
auto &ctx = DC->getASTContext();
3392+
auto *SF = DC->getParentSourceFile();
3393+
3394+
if (SF->Kind == SourceFileKind::Interface ||
3395+
ctx.LangOpts.WarnOnPotentiallyUnavailableEnumCase) {
3396+
return diag::availability_enum_element_no_potential_warn;
3397+
} else {
3398+
return diag::availability_enum_element_no_potential;
3399+
}
3400+
}
33903401
}
33913402

33923403
return None;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public enum Horse {
2+
@available(macOS 100, *)
3+
case kevin(Int)
4+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-build-swift -emit-module %S/Inputs/availability_enum_case_other.swift -emit-module-interface-path %t/availability_enum_case_other.swiftinterface -swift-version 5 -enable-library-evolution
4+
// RUN: %target-typecheck-verify-swift -I %t
5+
6+
// RUN: %target-build-swift -emit-module %S/Inputs/availability_enum_case_other.swift -emit-module-interface-path %t/availability_enum_case_other.swiftinterface -swift-version 5 -enable-library-evolution -whole-module-optimization
7+
// RUN: %target-typecheck-verify-swift -I %t
8+
9+
// REQUIRES: OS=macosx
10+
11+
import availability_enum_case_other
12+
13+
func ride(horse: Horse) {
14+
// expected-note@-1 {{add @available attribute to enclosing global function}}
15+
16+
_ = Horse.kevin
17+
// expected-error@-1 {{'kevin' is only available in macOS 100 or newer}}
18+
// expected-note@-2 {{add 'if #available' version check}}
19+
}

0 commit comments

Comments
 (0)