mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Custom availability] Fix conformance availability diagnostic
Emit a proper diagnostic for a conformance that is not available due to custom availability that doesn't have version information, eliminating an assertion.
This commit is contained in:
@@ -7282,6 +7282,10 @@ ERROR(conformance_availability_only_version_newer, none,
|
||||
"conformance of %0 to %1 is only available in %2 %3 or newer",
|
||||
(Type, Type, AvailabilityDomain, AvailabilityRange))
|
||||
|
||||
ERROR(conformance_availability_not_available, none,
|
||||
"conformance of %0 to %1 is only available in %2",
|
||||
(Type, Type, AvailabilityDomain))
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// MARK: if #available(...)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -1465,6 +1465,21 @@ static void configureAvailabilityDomains(const ASTContext &ctx,
|
||||
for (auto dynamic : opts.AvailabilityDomains.DynamicDomains)
|
||||
createAndInsertDomain(dynamic, CustomAvailabilityDomain::Kind::Dynamic);
|
||||
|
||||
// If we didn't see the UnicodeNormalization availability domain, set it
|
||||
// appropriately.
|
||||
if (domainMap.count(ctx.getIdentifier("UnicodeNormalization")) == 0) {
|
||||
if (ctx.LangOpts.hasFeature(Feature::Embedded)) {
|
||||
// Embedded Swift disables this domain by default.
|
||||
createAndInsertDomain("UnicodeNormalization",
|
||||
CustomAvailabilityDomain::Kind::Enabled);
|
||||
} else {
|
||||
// Non-Embedded Swift always enables the Unicode tables.
|
||||
createAndInsertDomain("UnicodeNormalization",
|
||||
CustomAvailabilityDomain::Kind::AlwaysEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mainModule->setAvailabilityDomains(std::move(domainMap));
|
||||
}
|
||||
|
||||
|
||||
@@ -1041,15 +1041,22 @@ static bool diagnosePotentialUnavailability(
|
||||
{
|
||||
auto type = rootConf->getType();
|
||||
auto proto = rootConf->getProtocol()->getDeclaredInterfaceType();
|
||||
auto err = ctx.Diags.diagnose(
|
||||
loc, diag::conformance_availability_only_version_newer, type, proto,
|
||||
domain, availability);
|
||||
auto err = availability.hasMinimumVersion()
|
||||
? ctx.Diags.diagnose(
|
||||
loc, diag::conformance_availability_only_version_newer, type, proto,
|
||||
domain, availability)
|
||||
: ctx.Diags.diagnose(
|
||||
loc, diag::conformance_availability_not_available, type, proto,
|
||||
domain);
|
||||
|
||||
auto behaviorLimit = behaviorLimitForExplicitUnavailability(rootConf, dc);
|
||||
if (behaviorLimit >= DiagnosticBehavior::Warning)
|
||||
if (!availability.hasMinimumVersion()) {
|
||||
// Don't downgrade
|
||||
} else if (behaviorLimit >= DiagnosticBehavior::Warning) {
|
||||
err.limitBehavior(behaviorLimit);
|
||||
else
|
||||
} else {
|
||||
err.warnUntilSwiftVersion(6);
|
||||
}
|
||||
|
||||
// Direct a fixit to the error if an existing guard is nearly-correct
|
||||
if (fixAvailabilityByNarrowingNearbyVersionCheck(loc, dc, domain,
|
||||
|
||||
@@ -568,3 +568,31 @@ class DerivedUnavailable2: BaseAvailableInEnabledDomain { } // expected-error {{
|
||||
@available(DisabledDomain, unavailable)
|
||||
class DerivedUnavailable3: BaseAvailableInEnabledDomain { }
|
||||
|
||||
|
||||
// Protocol conformance availability.
|
||||
protocol P { }
|
||||
|
||||
struct MyType1 { }
|
||||
|
||||
@available(EnabledDomain)
|
||||
extension MyType1: P { }
|
||||
|
||||
struct MyType2 { }
|
||||
|
||||
@available(AlwaysEnabledDomain)
|
||||
extension MyType2: P { }
|
||||
|
||||
struct MyType3 { }
|
||||
|
||||
@available(DisabledDomain)
|
||||
extension MyType3: P { }
|
||||
|
||||
func acceptP<T: P>(_: T.Type) { }
|
||||
|
||||
func testP() { // expected-note 2{{add '@available' attribute to enclosing global function}}
|
||||
acceptP(MyType1.self) // expected-error{{conformance of 'MyType1' to 'P' is only available in EnabledDomain}}
|
||||
// expected-note@-1{{add 'if #available' version check}}
|
||||
acceptP(MyType2.self) // okay
|
||||
acceptP(MyType3.self) // expected-error{{conformance of 'MyType3' to 'P' is only available in DisabledDomain}}
|
||||
// expected-note@-1{{add 'if #available' version check}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user