mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
AST: Diagnose unrecognized platforms as errors with CustomAvailability enabled.
When the CustomAvailability experimental feature is enabled, make it an error to specify an unrecognized availability domain name. Also, add these diagnostics to a diagnostic group so that developers can control their behavior when they are warnings. Resolves rdar://152741624.
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
GROUP(no_group, "")
|
||||
|
||||
GROUP(ActorIsolatedCall, "actor-isolated-call")
|
||||
GROUP(AvailabilityUnrecognizedName, "availability-unrecognized-name")
|
||||
GROUP(ClangDeclarationImport, "clang-declaration-import")
|
||||
GROUP(ConformanceIsolation, "conformance-isolation")
|
||||
GROUP(DeprecatedDeclaration, "deprecated-declaration")
|
||||
|
||||
@@ -6836,11 +6836,12 @@ ERROR(availability_must_occur_alone, none,
|
||||
(AvailabilityDomain, bool))
|
||||
ERROR(availability_unexpected_version, none,
|
||||
"unexpected version number for %0", (AvailabilityDomain))
|
||||
WARNING(availability_unrecognized_platform_name,
|
||||
PointsToFirstBadToken, "unrecognized platform name %0", (Identifier))
|
||||
WARNING(availability_suggest_platform_name,
|
||||
PointsToFirstBadToken, "unrecognized platform name %0;"
|
||||
" did you mean '%1'?",
|
||||
GROUPED_ERROR(availability_unrecognized_platform_name,
|
||||
AvailabilityUnrecognizedName, PointsToFirstBadToken,
|
||||
"unrecognized platform name %0", (Identifier))
|
||||
GROUPED_ERROR(availability_suggest_platform_name,
|
||||
AvailabilityUnrecognizedName, PointsToFirstBadToken,
|
||||
"unrecognized platform name %0; did you mean '%1'?",
|
||||
(Identifier, StringRef))
|
||||
WARNING(availability_unsupported_version_number, none,
|
||||
"'%0' is not a supported version number", (llvm::VersionTuple))
|
||||
|
||||
@@ -368,22 +368,29 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
|
||||
domain = results.front();
|
||||
}
|
||||
|
||||
bool hasCustomAvailability =
|
||||
ctx.LangOpts.hasFeature(Feature::CustomAvailability);
|
||||
|
||||
if (!domain) {
|
||||
auto domainString = identifier.str();
|
||||
bool downgradeErrors =
|
||||
!hasCustomAvailability || declContext->isInSwiftinterface();
|
||||
if (auto suggestion = closestCorrectedPlatformString(domainString)) {
|
||||
diags
|
||||
.diagnose(loc, diag::availability_suggest_platform_name, identifier,
|
||||
*suggestion)
|
||||
.limitBehaviorIf(downgradeErrors, DiagnosticBehavior::Warning)
|
||||
.fixItReplace(SourceRange(loc), *suggestion);
|
||||
} else {
|
||||
diags.diagnose(loc, diag::availability_unrecognized_platform_name,
|
||||
identifier);
|
||||
diags
|
||||
.diagnose(loc, diag::availability_unrecognized_platform_name,
|
||||
identifier)
|
||||
.limitBehaviorIf(downgradeErrors, DiagnosticBehavior::Warning);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (domain->isCustom() &&
|
||||
!ctx.LangOpts.hasFeature(Feature::CustomAvailability) &&
|
||||
if (domain->isCustom() && !hasCustomAvailability &&
|
||||
!declContext->isInSwiftinterface()) {
|
||||
diags.diagnose(loc, diag::attr_availability_requires_custom_availability,
|
||||
*domain);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Seas
|
||||
|
||||
@available(Arctic) // expected-warning {{unrecognized platform name 'Arctic'}}
|
||||
@available(Arctic) // expected-error {{unrecognized platform name 'Arctic'}}
|
||||
func availableInArctic() { }
|
||||
|
||||
@available(Mediterranean)
|
||||
|
||||
@@ -44,7 +44,7 @@ func availableInPacific() { }
|
||||
func unavailableInColorado() { } // expected-note {{'unavailableInColorado()' has been explicitly marked unavailable here}}
|
||||
|
||||
// The Seas module is only imported directly by the other source file.
|
||||
@available(Baltic) // expected-warning {{unrecognized platform name 'Baltic'}}
|
||||
@available(Baltic) // expected-error {{unrecognized platform name 'Baltic'}}
|
||||
func availableInBaltic() { } // expected-note {{did you mean 'availableInBaltic'}}
|
||||
|
||||
func testSwiftDecls() {
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
if #available(EnabledDomain) { }
|
||||
if #available(DisabledDomain) { }
|
||||
if #available(DynamicDomain) { }
|
||||
if #available(UnknownDomain) { } // expected-warning {{unrecognized platform name 'UnknownDomain'}}
|
||||
if #available(UnknownDomain) { } // expected-error {{unrecognized platform name 'UnknownDomain'}}
|
||||
// expected-error@-1 {{condition required for target platform}}
|
||||
|
||||
if #unavailable(EnabledDomain) { }
|
||||
if #unavailable(DisabledDomain) { }
|
||||
if #unavailable(DynamicDomain) { }
|
||||
if #unavailable(UnknownDomain) { } // expected-warning {{unrecognized platform name 'UnknownDomain'}}
|
||||
if #unavailable(UnknownDomain) { } // expected-error {{unrecognized platform name 'UnknownDomain'}}
|
||||
|
||||
if #available(EnabledDomain 1.0) { } // expected-error {{unexpected version number for EnabledDomain}}
|
||||
if #available(EnabledDomain, DisabledDomain) { } // expected-error {{EnabledDomain availability must be specified alone}}
|
||||
|
||||
@@ -26,7 +26,7 @@ func deprecatedInDynamicDomain() { }
|
||||
@available(DynamicDomain, unavailable)
|
||||
func unavailableInDynamicDomain() { } // expected-note * {{'unavailableInDynamicDomain()' has been explicitly marked unavailable here}}
|
||||
|
||||
@available(UnknownDomain) // expected-warning {{unrecognized platform name 'UnknownDomain'}}
|
||||
@available(UnknownDomain) // expected-error {{unrecognized platform name 'UnknownDomain'}}
|
||||
func availableInUnknownDomain() { }
|
||||
|
||||
func testDeployment() {
|
||||
|
||||
@@ -57,5 +57,5 @@ func deprecatedInRedefinedDomain() { }
|
||||
@available(DynamicDomain)
|
||||
func availableInDynamicDomain() { }
|
||||
|
||||
@available(UnknownDomain) // expected-warning {{unrecognized platform name 'UnknownDomain'}}
|
||||
@available(UnknownDomain) // expected-error {{unrecognized platform name 'UnknownDomain'}}
|
||||
func availableInUnknownDomain() { }
|
||||
|
||||
18
userdocs/diagnostics/availability-unrecognized-name.md
Normal file
18
userdocs/diagnostics/availability-unrecognized-name.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Unrecognized availability platforms (AvailabilityUnrecognizedName)
|
||||
|
||||
Warnings that identify unrecognized platform names in `@available` attributes and `if #available` statements.
|
||||
|
||||
## Overview
|
||||
|
||||
The `AvailabilityUnrecognizedName` group covers warnings emitted when the platform name specified in an availability related construct is unrecognized by the compiler:
|
||||
|
||||
```
|
||||
@available(NotAValidPlatform, introduced: 1.0) // warning: unrecognized platform name 'NotAValidPlatform'
|
||||
public func function() {
|
||||
if #available(NotAValidPlatform 2.0, *) { // warning: unrecognized platform name 'NotAValidPlatform'
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Availability specifications with unrecognized platform names in `@available` attributes and `#available` queries are ignored by the compiler.
|
||||
Reference in New Issue
Block a user