mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Generalize more-available-than-enclosing-decl diagnostics.
NFC.
This commit is contained in:
@@ -2200,13 +2200,19 @@ static Decl *getEnclosingDeclForDecl(Decl *D) {
|
||||
}
|
||||
|
||||
static std::optional<std::pair<SemanticAvailableAttr, const Decl *>>
|
||||
getSemanticAvailableRangeDeclAndAttr(const Decl *decl) {
|
||||
if (auto attr = decl->getAvailableAttrForPlatformIntroduction(
|
||||
/*checkExtension=*/false))
|
||||
return std::make_pair(*attr, decl);
|
||||
getSemanticAvailableRangeDeclAndAttr(const Decl *decl,
|
||||
AvailabilityDomain domain) {
|
||||
auto &ctx = decl->getASTContext();
|
||||
AvailabilityConstraintFlags flags =
|
||||
AvailabilityConstraintFlag::SkipEnclosingExtension;
|
||||
if (auto constraint = swift::getAvailabilityConstraintForDeclInDomain(
|
||||
decl, AvailabilityContext::forAlwaysAvailable(ctx), domain, flags)) {
|
||||
if (constraint->isPotentiallyAvailable())
|
||||
return std::make_pair(constraint->getAttr(), decl);
|
||||
}
|
||||
|
||||
if (auto *parent = decl->parentDeclForAvailability())
|
||||
return getSemanticAvailableRangeDeclAndAttr(parent);
|
||||
return getSemanticAvailableRangeDeclAndAttr(parent, domain);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -2300,7 +2306,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *parsedAttr) {
|
||||
|
||||
if (auto *parent = getEnclosingDeclForDecl(D)) {
|
||||
if (auto enclosingAvailable =
|
||||
getSemanticAvailableRangeDeclAndAttr(parent)) {
|
||||
getSemanticAvailableRangeDeclAndAttr(parent, attr->getDomain())) {
|
||||
SemanticAvailableAttr enclosingAttr = enclosingAvailable->first;
|
||||
const Decl *enclosingDecl = enclosingAvailable->second;
|
||||
enclosingIntroducedRange = enclosingAttr.getIntroducedRange(Ctx);
|
||||
@@ -5245,8 +5251,8 @@ void AttributeChecker::checkBackDeployedAttrs(
|
||||
// If it's not, the attribute doesn't make sense since the back deployment
|
||||
// fallback could never be executed at runtime.
|
||||
if (auto availableRangeAttrPair =
|
||||
getSemanticAvailableRangeDeclAndAttr(VD)) {
|
||||
auto beforeDomain = Attr->getAvailabilityDomain();
|
||||
getSemanticAvailableRangeDeclAndAttr(VD, Domain)) {
|
||||
auto beforeDomain = Domain;
|
||||
auto beforeVersion = Attr->getVersion();
|
||||
auto availableAttr = availableRangeAttrPair.value().first;
|
||||
auto introVersion = availableAttr.getIntroduced().value();
|
||||
|
||||
@@ -231,18 +231,29 @@ func testFixIts() {
|
||||
// expected-note@-1 {{add 'if #available' version check}}{{3-29=if #available(EnabledDomain) {\n availableInEnabledDomain()\n \} else {\n // Fallback\n \}}}
|
||||
}
|
||||
|
||||
struct Container { }
|
||||
|
||||
@available(EnabledDomain)
|
||||
extension Container {
|
||||
@available(EnabledDomain)
|
||||
func redundantlyAvailableInEnabledDomain() { }
|
||||
|
||||
@available(EnabledDomain, unavailable)
|
||||
func unavailableInEnabledDomain() { }
|
||||
}
|
||||
|
||||
protocol P { }
|
||||
|
||||
@available(EnabledDomain)
|
||||
struct AvailableInEnabledDomain: P { }
|
||||
struct AvailableConformsToP: P { }
|
||||
|
||||
@available(EnabledDomain, unavailable)
|
||||
struct UnavailableInEnabledDomain: P { }
|
||||
struct UnavailableConformsToP: P { }
|
||||
|
||||
func testOpaqueReturnType() -> some P {
|
||||
if #available(EnabledDomain) { // expected-error {{opaque return type cannot depend on EnabledDomain availability}}
|
||||
return AvailableInEnabledDomain()
|
||||
return AvailableConformsToP()
|
||||
} else {
|
||||
return UnavailableInEnabledDomain()
|
||||
return UnavailableConformsToP()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user