Skip to content

Commit d79b69b

Browse files
authored
Merge pull request #37870 from slavapestov/unavailable-enum-case-warning-5.5
Sema: Downgrade potentially unavailable enum cases to a warning in module interfaces [5.5]
2 parents 51e2fdf + 2fb3f6d commit d79b69b

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
@@ -5303,6 +5303,10 @@ ERROR(availability_enum_element_no_potential,
53035303
none, "enum cases with associated values cannot be marked potentially unavailable with "
53045304
"'@available'", ())
53055305

5306+
WARNING(availability_enum_element_no_potential_warn,
5307+
none, "enum cases with associated values cannot be marked potentially unavailable with "
5308+
"'@available'", ())
5309+
53065310
ERROR(availability_protocol_requires_version,
53075311
none, "protocol %0 requires %1 to be available in %2 %3 and newer",
53085312
(Identifier, DeclName, StringRef, llvm::VersionTuple))

include/swift/Basic/LangOptions.h

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

118+
/// Should potential unavailability on enum cases be downgraded to a warning?
119+
bool WarnOnPotentiallyUnavailableEnumCase = false;
120+
118121
/// Maximum number of typo corrections we are allowed to perform.
119122
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
120123
unsigned TypoCorrectionLimit = 0;

include/swift/Option/FrontendOptions.td

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

420+
def warn_on_potentially_unavailable_enum_case : Flag<["-"],
421+
"warn-on-potentially-unavailable-enum-case">,
422+
HelpText<"Downgrade potential unavailability of enum case to a warning">;
423+
420424
def report_errors_to_debugger : Flag<["-"], "report-errors-to-debugger">,
421425
HelpText<"Deprecated, will be removed in future versions.">;
422426

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
@@ -423,6 +423,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
423423
= A->getOption().matches(OPT_enable_conformance_availability_errors);
424424
}
425425

426+
Opts.WarnOnPotentiallyUnavailableEnumCase |=
427+
Args.hasArg(OPT_warn_on_potentially_unavailable_enum_case);
426428
if (auto A = Args.getLastArg(OPT_enable_access_control,
427429
OPT_disable_access_control)) {
428430
Opts.EnableAccessControl

lib/Sema/TypeCheckAttr.cpp

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

33843384
Optional<Diag<>>
33853385
TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
3386+
auto *DC = D->getDeclContext();
3387+
33863388
if (auto *VD = dyn_cast<VarDecl>(D)) {
33873389
if (!VD->hasStorage())
33883390
return None;
@@ -3395,14 +3397,23 @@ TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
33953397

33963398
// Globals and statics are lazily initialized, so they are safe
33973399
// for potential unavailability.
3398-
if (!VD->isStatic() && !VD->getDeclContext()->isModuleScopeContext())
3400+
if (!VD->isStatic() && !DC->isModuleScopeContext())
33993401
return diag::availability_stored_property_no_potential;
34003402

34013403
} else if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
34023404
// An enum element with an associated value cannot be potentially
34033405
// unavailable.
3404-
if (EED->hasAssociatedValues())
3405-
return diag::availability_enum_element_no_potential;
3406+
if (EED->hasAssociatedValues()) {
3407+
auto &ctx = DC->getASTContext();
3408+
auto *SF = DC->getParentSourceFile();
3409+
3410+
if (SF->Kind == SourceFileKind::Interface ||
3411+
ctx.LangOpts.WarnOnPotentiallyUnavailableEnumCase) {
3412+
return diag::availability_enum_element_no_potential_warn;
3413+
} else {
3414+
return diag::availability_enum_element_no_potential;
3415+
}
3416+
}
34063417
}
34073418

34083419
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)