diff --git a/include/swift/AST/AvailabilityDomain.h b/include/swift/AST/AvailabilityDomain.h index ff1fe134168f3..eea232ecc4454 100644 --- a/include/swift/AST/AvailabilityDomain.h +++ b/include/swift/AST/AvailabilityDomain.h @@ -33,12 +33,21 @@ namespace swift { class ASTContext; +class AvailabilityDomainAndRange; class CustomAvailabilityDomain; class DeclContext; class FuncDecl; class ModuleDecl; class ValueDecl; +/// Discriminates whether a version tuple represents the `introduced:`, +/// `deprecated:`, or `obsoleted:` version of an `@available` attribute. +enum class AvailabilityVersionKind { + Introduced, + Deprecated, + Obsoleted, +}; + /// Represents a dimension of availability (e.g. macOS platform or Swift /// language mode). class AvailabilityDomain final { @@ -131,6 +140,9 @@ class AvailabilityDomain final { : std::nullopt; } + std::optional + getRemappedDomainOrNull(const ASTContext &ctx) const; + public: AvailabilityDomain() {} @@ -294,19 +306,22 @@ class AvailabilityDomain final { /// descendants of the iOS domain. AvailabilityDomain getRootDomain() const; - /// Returns the canonical domain that versions in this domain must be remapped - /// to before making availability comparisons in the current compilation - /// context. Sets \p didRemap to `true` if a remap was required. - const AvailabilityDomain getRemappedDomain(const ASTContext &ctx, - bool &didRemap) const; - /// Returns the canonical domain that versions in this domain must be remapped /// to before making availability comparisons in the current compilation /// context. const AvailabilityDomain getRemappedDomain(const ASTContext &ctx) const { - bool unused; - return getRemappedDomain(ctx, unused); - } + auto remappedDomain = getRemappedDomainOrNull(ctx); + return remappedDomain ? *remappedDomain : *this; + } + + /// Converts the domain and the given version into a canonical domain and + /// range that can be used for availability comparisons in the current current + /// compilation context. If no conversion is necessary or possible, the domain + /// and range are returned unmodified. + AvailabilityDomainAndRange + getRemappedDomainAndRange(const llvm::VersionTuple &version, + AvailabilityVersionKind versionKind, + const ASTContext &ctx) const; /// Returns true for a domain that is permanently always available, and /// therefore availability constraints in the domain are effectively the same diff --git a/include/swift/AST/AvailabilityInference.h b/include/swift/AST/AvailabilityInference.h index efb9fd7290fa2..b8e1d51a4ac9f 100644 --- a/include/swift/AST/AvailabilityInference.h +++ b/include/swift/AST/AvailabilityInference.h @@ -25,7 +25,6 @@ namespace swift { class ASTContext; class AvailabilityDomain; -class BackDeployedAttr; class Decl; class SemanticAvailableAttr; @@ -49,37 +48,8 @@ class AvailabilityInference { static std::optional annotatedAvailableRange(const Decl *D); - static AvailabilityRange - annotatedAvailableRangeForAttr(const Decl *D, const AbstractSpecializeAttr *attr, - ASTContext &ctx); - - /// For the attribute's introduction version, update the platform and version - /// values to the re-mapped platform's, if using a fallback platform. - /// Returns `true` if a remap occured. - static bool updateIntroducedAvailabilityDomainForFallback( - const SemanticAvailableAttr &attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer); - - /// For the attribute's deprecation version, update the platform and version - /// values to the re-mapped platform's, if using a fallback platform. - /// Returns `true` if a remap occured. - static bool updateDeprecatedAvailabilityDomainForFallback( - const SemanticAvailableAttr &attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer); - - /// For the attribute's obsoletion version, update the platform and version - /// values to the re-mapped platform's, if using a fallback platform. - /// Returns `true` if a remap occured. - static bool updateObsoletedAvailabilityDomainForFallback( - const SemanticAvailableAttr &attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer); - - /// For the attribute's before version, update the platform and version - /// values to the re-mapped platform's, if using a fallback platform. - /// Returns `true` if a remap occured. - static bool updateBeforeAvailabilityDomainForFallback( - const BackDeployedAttr *attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer); + static AvailabilityRange annotatedAvailableRangeForAttr( + const Decl *D, const AbstractSpecializeAttr *attr, ASTContext &ctx); }; } // end namespace swift diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 026dce1948458..7c41541229f61 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -1134,8 +1134,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated, public Swi /// Returns the active `@backDeployed` attribute and the `AvailabilityRange` /// in which the decl is available as ABI. std::optional> - getBackDeployedAttrAndRange(ASTContext &Ctx, - bool forTargetVariant = false) const; + getBackDeployedAttrAndRange(bool forTargetVariant = false) const; /// Returns true if the decl has a valid and active `@backDeployed` attribute. bool isBackDeployed() const; diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index 3d220566ba5ae..e9b7986842c15 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -18,7 +18,6 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/ASTPrinter.h" #include "swift/AST/AvailabilityDomain.h" -#include "swift/AST/AvailabilityInference.h" #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" #include "swift/AST/GenericEnvironment.h" diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 6d9072a84ebf4..e9237a6c5d505 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -256,128 +256,6 @@ static bool isBetterThan(const SemanticAvailableAttr &newAttr, prevAttr->getPlatform()); } -static const clang::DarwinSDKInfo::RelatedTargetVersionMapping * -getFallbackVersionMapping(const ASTContext &Ctx, - clang::DarwinSDKInfo::OSEnvPair Kind) { - auto *SDKInfo = Ctx.getDarwinSDKInfo(); - if (SDKInfo) - return SDKInfo->getVersionMapping(Kind); - - return Ctx.getAuxiliaryDarwinPlatformRemapInfo(Kind); -} - -static std::optional -getRemappedIntroducedVersionForFallbackPlatform( - const ASTContext &Ctx, const llvm::VersionTuple &Version) { - const auto *Mapping = getFallbackVersionMapping( - Ctx, clang::DarwinSDKInfo::OSEnvPair( - llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, - llvm::Triple::XROS, llvm::Triple::UnknownEnvironment)); - if (!Mapping) - return std::nullopt; - return Mapping->mapIntroducedAvailabilityVersion(Version); -} - -static std::optional -getRemappedDeprecatedObsoletedVersionForFallbackPlatform( - const ASTContext &Ctx, const llvm::VersionTuple &Version) { - const auto *Mapping = getFallbackVersionMapping( - Ctx, clang::DarwinSDKInfo::OSEnvPair( - llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, - llvm::Triple::XROS, llvm::Triple::UnknownEnvironment)); - if (!Mapping) - return std::nullopt; - return Mapping->mapDeprecatedObsoletedAvailabilityVersion(Version); -} - -bool AvailabilityInference::updateIntroducedAvailabilityDomainForFallback( - const SemanticAvailableAttr &attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer) { - std::optional introducedVersion = attr.getIntroduced(); - if (!introducedVersion.has_value()) - return false; - - bool hasRemap = false; - auto remappedDomain = attr.getDomain().getRemappedDomain(ctx, hasRemap); - if (!hasRemap) - return false; - - auto potentiallyRemappedIntroducedVersion = - getRemappedIntroducedVersionForFallbackPlatform(ctx, *introducedVersion); - if (potentiallyRemappedIntroducedVersion.has_value()) { - domain = remappedDomain; - platformVer = potentiallyRemappedIntroducedVersion.value(); - return true; - } - return false; -} - -bool AvailabilityInference::updateDeprecatedAvailabilityDomainForFallback( - const SemanticAvailableAttr &attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer) { - std::optional deprecatedVersion = attr.getDeprecated(); - if (!deprecatedVersion.has_value()) - return false; - - bool hasRemap = false; - auto remappedDomain = attr.getDomain().getRemappedDomain(ctx, hasRemap); - if (!hasRemap) - return false; - - auto potentiallyRemappedDeprecatedVersion = - getRemappedDeprecatedObsoletedVersionForFallbackPlatform( - ctx, *deprecatedVersion); - if (potentiallyRemappedDeprecatedVersion.has_value()) { - domain = remappedDomain; - platformVer = potentiallyRemappedDeprecatedVersion.value(); - return true; - } - return false; -} - -bool AvailabilityInference::updateObsoletedAvailabilityDomainForFallback( - const SemanticAvailableAttr &attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer) { - std::optional obsoletedVersion = attr.getObsoleted(); - if (!obsoletedVersion.has_value()) - return false; - - bool hasRemap = false; - auto remappedDomain = attr.getDomain().getRemappedDomain(ctx, hasRemap); - if (!hasRemap) - return false; - - auto potentiallyRemappedObsoletedVersion = - getRemappedDeprecatedObsoletedVersionForFallbackPlatform( - ctx, *obsoletedVersion); - if (potentiallyRemappedObsoletedVersion.has_value()) { - domain = remappedDomain; - platformVer = potentiallyRemappedObsoletedVersion.value(); - return true; - } - return false; -} - -bool AvailabilityInference::updateBeforeAvailabilityDomainForFallback( - const BackDeployedAttr *attr, const ASTContext &ctx, - AvailabilityDomain &domain, llvm::VersionTuple &platformVer) { - bool hasRemap = false; - auto remappedDomain = - attr->getAvailabilityDomain().getRemappedDomain(ctx, hasRemap); - if (!hasRemap) - return false; - - auto beforeVersion = attr->getVersion(); - auto potentiallyRemappedIntroducedVersion = - getRemappedIntroducedVersionForFallbackPlatform(ctx, beforeVersion); - if (potentiallyRemappedIntroducedVersion.has_value()) { - domain = remappedDomain; - platformVer = potentiallyRemappedIntroducedVersion.value(); - return true; - } - return false; -} - static std::optional getDeclAvailableAttrForPlatformIntroduction(const Decl *D) { std::optional bestAvailAttr; @@ -917,40 +795,31 @@ std::optional SemanticAvailableAttr::getIntroduced() const { std::optional SemanticAvailableAttr::getIntroducedDomainAndRange( const ASTContext &Ctx) const { - auto *attr = getParsedAttr(); auto domain = getDomain(); - if (domain.isUniversal()) return std::nullopt; - if (!attr->getRawIntroduced().has_value()) { - // For versioned domains, an "introduced:" version is always required to - // indicate introduction. - if (domain.isVersioned()) - return std::nullopt; + if (auto introduced = getIntroduced()) + return domain.getRemappedDomainAndRange( + *introduced, AvailabilityVersionKind::Introduced, Ctx); - // For version-less domains, an attribute that does not indicate some other - // kind of unconditional availability constraint implicitly specifies that - // the decl is available in all versions of the domain. - switch (attr->getKind()) { - case AvailableAttr::Kind::Default: - return AvailabilityDomainAndRange(domain.getRemappedDomain(Ctx), - AvailabilityRange::alwaysAvailable()); - case AvailableAttr::Kind::Deprecated: - case AvailableAttr::Kind::Unavailable: - case AvailableAttr::Kind::NoAsync: - return std::nullopt; - } - } - - llvm::VersionTuple introducedVersion = getIntroduced().value(); - llvm::VersionTuple remappedVersion; - if (AvailabilityInference::updateIntroducedAvailabilityDomainForFallback( - *this, Ctx, domain, remappedVersion)) - introducedVersion = remappedVersion; + // For versioned domains, an "introduced:" version is always required to + // indicate introduction. + if (domain.isVersioned()) + return std::nullopt; - return AvailabilityDomainAndRange(domain, - AvailabilityRange{introducedVersion}); + // For version-less domains, an attribute that does not indicate some other + // kind of unconditional availability constraint implicitly specifies that + // the decl is available in all versions of the domain. + switch (attr->getKind()) { + case AvailableAttr::Kind::Default: + return AvailabilityDomainAndRange(domain.getRemappedDomain(Ctx), + AvailabilityRange::alwaysAvailable()); + case AvailableAttr::Kind::Deprecated: + case AvailableAttr::Kind::Unavailable: + case AvailableAttr::Kind::NoAsync: + return std::nullopt; + } } std::optional SemanticAvailableAttr::getDeprecated() const { @@ -962,28 +831,18 @@ std::optional SemanticAvailableAttr::getDeprecated() const { std::optional SemanticAvailableAttr::getDeprecatedDomainAndRange( const ASTContext &Ctx) const { - auto *attr = getParsedAttr(); - AvailabilityDomain domain = getDomain(); - - if (!attr->getRawDeprecated().has_value()) { - // Regardless of the whether the domain supports versions or not, an - // unconditional deprecation attribute indicates the decl is always - // deprecated. - if (isUnconditionallyDeprecated()) - return AvailabilityDomainAndRange(domain.getRemappedDomain(Ctx), - AvailabilityRange::alwaysAvailable()); - - return std::nullopt; - } + if (auto deprecated = getDeprecated()) + return getDomain().getRemappedDomainAndRange( + *deprecated, AvailabilityVersionKind::Deprecated, Ctx); - llvm::VersionTuple deprecatedVersion = getDeprecated().value(); - llvm::VersionTuple remappedVersion; - if (AvailabilityInference::updateDeprecatedAvailabilityDomainForFallback( - *this, Ctx, domain, remappedVersion)) - deprecatedVersion = remappedVersion; + // Regardless of the whether the domain supports versions or not, an + // unconditional deprecation attribute indicates the decl is always + // deprecated. + if (isUnconditionallyDeprecated()) + return AvailabilityDomainAndRange(getDomain().getRemappedDomain(Ctx), + AvailabilityRange::alwaysAvailable()); - return AvailabilityDomainAndRange(domain, - AvailabilityRange{deprecatedVersion}); + return std::nullopt; } std::optional SemanticAvailableAttr::getObsoleted() const { @@ -994,26 +853,16 @@ std::optional SemanticAvailableAttr::getObsoleted() const { std::optional SemanticAvailableAttr::getObsoletedDomainAndRange(const ASTContext &Ctx) const { - auto *attr = getParsedAttr(); - AvailabilityDomain domain = getDomain(); - - if (!attr->getRawObsoleted().has_value()) { - // An "unavailable" attribute effectively means obsolete in all versions. - if (attr->isUnconditionallyUnavailable()) - return AvailabilityDomainAndRange(domain.getRemappedDomain(Ctx), - AvailabilityRange::alwaysAvailable()); + if (auto obsoleted = getObsoleted()) + return getDomain().getRemappedDomainAndRange( + *obsoleted, AvailabilityVersionKind::Obsoleted, Ctx); - return std::nullopt; - } + // An "unavailable" attribute effectively means obsolete in all versions. + if (isUnconditionallyUnavailable()) + return AvailabilityDomainAndRange(getDomain().getRemappedDomain(Ctx), + AvailabilityRange::alwaysAvailable()); - llvm::VersionTuple obsoletedVersion = getObsoleted().value(); - llvm::VersionTuple remappedVersion; - if (AvailabilityInference::updateObsoletedAvailabilityDomainForFallback( - *this, Ctx, domain, remappedVersion)) - obsoletedVersion = remappedVersion; - - return AvailabilityDomainAndRange(domain, - AvailabilityRange{obsoletedVersion}); + return std::nullopt; } namespace { diff --git a/lib/AST/AvailabilityContext.cpp b/lib/AST/AvailabilityContext.cpp index 327c74e420b2e..cc059f555d7ef 100644 --- a/lib/AST/AvailabilityContext.cpp +++ b/lib/AST/AvailabilityContext.cpp @@ -14,7 +14,6 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/AvailabilityConstraint.h" #include "swift/AST/AvailabilityContextStorage.h" -#include "swift/AST/AvailabilityInference.h" #include "swift/AST/AvailabilityScope.h" #include "swift/AST/Decl.h" #include "swift/AST/Module.h" diff --git a/lib/AST/AvailabilityDomain.cpp b/lib/AST/AvailabilityDomain.cpp index 769a2ae9b4f0d..5ee3a7fcb4ea1 100644 --- a/lib/AST/AvailabilityDomain.cpp +++ b/lib/AST/AvailabilityDomain.cpp @@ -400,16 +400,73 @@ AvailabilityDomain AvailabilityDomain::getRootDomain() const { return *this; } -const AvailabilityDomain -AvailabilityDomain::getRemappedDomain(const ASTContext &ctx, - bool &didRemap) const { +std::optional +AvailabilityDomain::getRemappedDomainOrNull(const ASTContext &ctx) const { if (getPlatformKind() == PlatformKind::iOS && - isPlatformActive(PlatformKind::visionOS, ctx.LangOpts)) { - didRemap = true; + isPlatformActive(PlatformKind::visionOS, ctx.LangOpts)) return AvailabilityDomain::forPlatform(PlatformKind::visionOS); + + return std::nullopt; +} + +static const clang::DarwinSDKInfo::RelatedTargetVersionMapping * +getFallbackVersionMapping(const ASTContext &Ctx, + clang::DarwinSDKInfo::OSEnvPair Kind) { + auto *SDKInfo = Ctx.getDarwinSDKInfo(); + if (SDKInfo) + return SDKInfo->getVersionMapping(Kind); + + return Ctx.getAuxiliaryDarwinPlatformRemapInfo(Kind); +} + +static std::optional +getRemappedIntroducedVersionForFallbackPlatform( + const ASTContext &Ctx, const llvm::VersionTuple &Version) { + const auto *Mapping = getFallbackVersionMapping( + Ctx, clang::DarwinSDKInfo::OSEnvPair( + llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, + llvm::Triple::XROS, llvm::Triple::UnknownEnvironment)); + if (!Mapping) + return std::nullopt; + return Mapping->mapIntroducedAvailabilityVersion(Version); +} + +static std::optional +getRemappedDeprecatedObsoletedVersionForFallbackPlatform( + const ASTContext &Ctx, const llvm::VersionTuple &Version) { + const auto *Mapping = getFallbackVersionMapping( + Ctx, clang::DarwinSDKInfo::OSEnvPair( + llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, + llvm::Triple::XROS, llvm::Triple::UnknownEnvironment)); + if (!Mapping) + return std::nullopt; + return Mapping->mapDeprecatedObsoletedAvailabilityVersion(Version); +} + +AvailabilityDomainAndRange AvailabilityDomain::getRemappedDomainAndRange( + const llvm::VersionTuple &version, AvailabilityVersionKind versionKind, + const ASTContext &ctx) const { + auto remappedDomain = getRemappedDomainOrNull(ctx); + if (!remappedDomain) + return {*this, AvailabilityRange{version}}; + + std::optional remappedVersion; + switch (versionKind) { + case AvailabilityVersionKind::Introduced: + remappedVersion = + getRemappedIntroducedVersionForFallbackPlatform(ctx, version); + break; + case AvailabilityVersionKind::Deprecated: + case AvailabilityVersionKind::Obsoleted: + remappedVersion = + getRemappedDeprecatedObsoletedVersionForFallbackPlatform(ctx, version); + break; } - return *this; + if (!remappedVersion) + return {*this, AvailabilityRange{version}}; + + return {*remappedDomain, AvailabilityRange{*remappedVersion}}; } bool IsCustomAvailabilityDomainPermanentlyEnabled::evaluate( diff --git a/lib/AST/AvailabilityScope.cpp b/lib/AST/AvailabilityScope.cpp index 81558b9ca272a..911230b0dbdf1 100644 --- a/lib/AST/AvailabilityScope.cpp +++ b/lib/AST/AvailabilityScope.cpp @@ -18,7 +18,6 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/AvailabilityConstraint.h" -#include "swift/AST/AvailabilityInference.h" #include "swift/AST/AvailabilitySpec.h" #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a6c01aa21d307..02d99e4152c25 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -597,32 +597,31 @@ Decl::getIntroducedOSVersion(PlatformKind Kind) const { } std::optional> -Decl::getBackDeployedAttrAndRange(ASTContext &Ctx, - bool forTargetVariant) const { - if (auto *attr = getAttrs().getBackDeployed(Ctx, forTargetVariant)) { - auto version = attr->getVersion(); - AvailabilityDomain ignoredDomain; - AvailabilityInference::updateBeforeAvailabilityDomainForFallback( - attr, getASTContext(), ignoredDomain, version); - - // If the remap for fallback resulted in 1.0, then the - // backdeployment prior to that is not meaningful. - if (version == llvm::VersionTuple(1, 0, 0, 0)) +Decl::getBackDeployedAttrAndRange(bool forTargetVariant) const { + auto &ctx = getASTContext(); + if (auto *attr = getAttrs().getBackDeployed(ctx, forTargetVariant)) { + auto remappedDomainAndRange = + attr->getAvailabilityDomain().getRemappedDomainAndRange( + attr->getVersion(), AvailabilityVersionKind::Introduced, ctx); + + // If the before version was remapped to '1.0', then this decl has + // effectively always been available on the current platform and does not + // qualify as back deployed. + if (remappedDomainAndRange.getRange().getRawMinimumVersion() == + llvm::VersionTuple(1, 0, 0, 0)) return std::nullopt; - return std::make_pair(attr, AvailabilityRange(version)); + return std::make_pair(attr, remappedDomainAndRange.getRange()); } // Accessors may inherit `@backDeployed`. if (auto *AD = dyn_cast(this)) - return AD->getStorage()->getBackDeployedAttrAndRange(Ctx, forTargetVariant); + return AD->getStorage()->getBackDeployedAttrAndRange(forTargetVariant); return std::nullopt; } bool Decl::isBackDeployed() const { - auto &Ctx = getASTContext(); - // A function declared in a local context can never be back-deployed. if (getDeclContext()->isLocalContext()) return false; @@ -636,11 +635,11 @@ bool Decl::isBackDeployed() const { return false; } - if (getBackDeployedAttrAndRange(Ctx)) + if (getBackDeployedAttrAndRange()) return true; - if (Ctx.LangOpts.TargetVariant) { - if (getBackDeployedAttrAndRange(Ctx, /*forTargetVariant=*/true)) + if (getASTContext().LangOpts.TargetVariant) { + if (getBackDeployedAttrAndRange(/*forTargetVariant=*/true)) return true; } @@ -1482,7 +1481,7 @@ AvailabilityRange Decl::getAvailabilityForLinkage() const { // When computing availability for linkage, use the "before" version from // the @backDeployed attribute, if present. - if (auto backDeployedAttrAndRange = getBackDeployedAttrAndRange(ctx)) + if (auto backDeployedAttrAndRange = getBackDeployedAttrAndRange()) return backDeployedAttrAndRange->second; auto containingContext = AvailabilityInference::annotatedAvailableRange(this); diff --git a/lib/IDE/CodeCompletionDiagnostics.cpp b/lib/IDE/CodeCompletionDiagnostics.cpp index cb54dc0238ea3..da6762debcf9d 100644 --- a/lib/IDE/CodeCompletionDiagnostics.cpp +++ b/lib/IDE/CodeCompletionDiagnostics.cpp @@ -13,7 +13,6 @@ #include "CodeCompletionDiagnostics.h" #include "swift/AST/ASTContext.h" -#include "swift/AST/AvailabilityInference.h" #include "swift/AST/Decl.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsIDE.h" diff --git a/lib/SILGen/SILGenAvailability.cpp b/lib/SILGen/SILGenAvailability.cpp index e566259790f71..f289c3a44da5b 100644 --- a/lib/SILGen/SILGenAvailability.cpp +++ b/lib/SILGen/SILGenAvailability.cpp @@ -113,9 +113,9 @@ static std::optional getAvailabilityQueryForBackDeployment(AbstractFunctionDecl *AFD) { auto &ctx = AFD->getASTContext(); if (ctx.LangOpts.TargetVariant) { - auto primaryAttrAndRange = AFD->getBackDeployedAttrAndRange(ctx); + auto primaryAttrAndRange = AFD->getBackDeployedAttrAndRange(); auto variantAttrAndRange = - AFD->getBackDeployedAttrAndRange(ctx, /*forTargetVariant=*/true); + AFD->getBackDeployedAttrAndRange(/*forTargetVariant=*/true); if (!primaryAttrAndRange && !variantAttrAndRange) return std::nullopt; @@ -134,7 +134,7 @@ getAvailabilityQueryForBackDeployment(AbstractFunctionDecl *AFD) { primaryRange, variantRange); } - if (auto primaryAttrAndRange = AFD->getBackDeployedAttrAndRange(ctx)) + if (auto primaryAttrAndRange = AFD->getBackDeployedAttrAndRange()) return AvailabilityQuery::dynamic( primaryAttrAndRange->first->getAvailabilityDomain(), primaryAttrAndRange->second, std::nullopt); @@ -284,7 +284,7 @@ SILGenFunction::emitIfAvailableQuery(SILLocation loc, bool SILGenModule::requiresBackDeploymentThunk(ValueDecl *decl, ResilienceExpansion expansion) { auto &ctx = getASTContext(); - auto attrAndRange = decl->getBackDeployedAttrAndRange(ctx); + auto attrAndRange = decl->getBackDeployedAttrAndRange(); if (!attrAndRange) return false; diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index f9ff76cd06d94..527ccffd74f1e 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -27,7 +27,6 @@ #include "swift/AST/ASTVisitor.h" #include "swift/AST/Attr.h" #include "swift/AST/AttrKind.h" -#include "swift/AST/AvailabilityInference.h" #include "swift/AST/ClangModuleLoader.h" #include "swift/AST/ConformanceLookup.h" #include "swift/AST/Decl.h" @@ -5266,7 +5265,7 @@ void AttributeChecker::checkBackDeployedAttrs( std::map seenPlatforms; const BackDeployedAttr *ActiveAttr = nullptr; - if (auto AttrAndRange = D->getBackDeployedAttrAndRange(Ctx)) + if (auto AttrAndRange = D->getBackDeployedAttrAndRange()) ActiveAttr = AttrAndRange->first; for (auto *Attr : Attrs) { @@ -5366,14 +5365,8 @@ void AttributeChecker::checkBackDeployedAttrs( // Unavailable decls cannot be back deployed. if (availability.containsUnavailableDomain(Domain)) { - auto domainForDiagnostics = Domain; - llvm::VersionTuple ignoredVersion; - - AvailabilityInference::updateBeforeAvailabilityDomainForFallback( - Attr, Ctx, domainForDiagnostics, ignoredVersion); - diagnose(AtLoc, diag::attr_has_no_effect_on_unavailable_decl, Attr, VD, - domainForDiagnostics); + Domain.getRemappedDomain(Ctx)); // Find the attribute that makes the declaration unavailable. const Decl *attrDecl = D; @@ -5396,23 +5389,22 @@ void AttributeChecker::checkBackDeployedAttrs( // fallback could never be executed at runtime. if (auto availableRangeAttrPair = getSemanticAvailableRangeDeclAndAttr(VD, Domain)) { - auto beforeDomain = Domain; - auto beforeVersion = Attr->getVersion(); - auto availableAttr = availableRangeAttrPair.value().first; - auto introVersion = availableAttr.getIntroduced().value(); - AvailabilityDomain introDomain = availableAttr.getDomain(); - - AvailabilityInference::updateBeforeAvailabilityDomainForFallback( - Attr, Ctx, beforeDomain, beforeVersion); - AvailabilityInference::updateIntroducedAvailabilityDomainForFallback( - availableAttr, Ctx, introDomain, introVersion); - - if (beforeVersion <= introVersion) { + auto availableAttr = availableRangeAttrPair->first; + auto introDomainAndRange = availableAttr.getIntroducedDomainAndRange(Ctx); + if (!introDomainAndRange) + continue; + + auto beforeDomainAndRange = Domain.getRemappedDomainAndRange( + Attr->getVersion(), AvailabilityVersionKind::Introduced, Ctx); + + auto introRange = introDomainAndRange->getRange(); + auto beforeRange = beforeDomainAndRange.getRange(); + if (introRange.isContainedIn(beforeRange)) { diagnose(AtLoc, diag::attr_has_no_effect_decl_not_available_before, - Attr, VD, beforeDomain, AvailabilityRange(beforeVersion)); + Attr, VD, beforeDomainAndRange.getDomain(), beforeRange); diagnose(availableAttr.getParsedAttr()->AtLoc, - diag::availability_introduced_in_version, VD, introDomain, - AvailabilityRange(introVersion)) + diag::availability_introduced_in_version, VD, + introDomainAndRange->getDomain(), introRange) .highlight(availableAttr.getParsedAttr()->getRange()); continue; } diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 661428cd08083..94c9a98273b42 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -32,7 +32,6 @@ #include "swift/AST/ASTWalker.h" #include "swift/AST/AccessScope.h" #include "swift/AST/Attr.h" -#include "swift/AST/AvailabilityInference.h" #include "swift/AST/ClangModuleLoader.h" #include "swift/AST/ConformanceLookup.h" #include "swift/AST/Decl.h"