Skip to content

Commit 01215b0

Browse files
committed
AST: Remove UnavailabilityReason.
`UnavailabilityReason` does not live up to its name because it only models potential unavailability due to an unmet OS version requirement. It does not model unavailability caused by explicit annotation, language mode requirements, obsoletion, etc. `AvailabilityContext` already models an OS version requirement, so use it instead. NFC.
1 parent 8052e3f commit 01215b0

File tree

4 files changed

+50
-82
lines changed

4 files changed

+50
-82
lines changed

include/swift/AST/Availability.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -194,28 +194,6 @@ class VersionRange {
194194
}
195195
};
196196

197-
/// Records the reason a declaration is potentially unavailable.
198-
class UnavailabilityReason {
199-
private:
200-
VersionRange RequiredDeploymentRange;
201-
202-
explicit UnavailabilityReason(const VersionRange RequiredDeploymentRange)
203-
: RequiredDeploymentRange(RequiredDeploymentRange) {}
204-
205-
public:
206-
static UnavailabilityReason requiresVersionRange(const VersionRange Range) {
207-
return UnavailabilityReason(Range);
208-
}
209-
210-
const VersionRange &getRequiredOSVersionRange() const {
211-
return RequiredDeploymentRange;
212-
}
213-
214-
/// Returns true if the required OS version range's lower endpoint is at or
215-
/// below the deployment target of the given ASTContext.
216-
bool requiresDeploymentTargetOrEarlier(ASTContext &Ctx) const;
217-
};
218-
219197
/// Represents a version range in which something is available.
220198
///
221199
/// The AvailabilityContext structure forms a [lattice][], which allows it to

lib/AST/Availability.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -517,14 +517,6 @@ bool Decl::requiresUnavailableDeclABICompatibilityStubs() const {
517517
return isUnreachableAtRuntime();
518518
}
519519

520-
bool UnavailabilityReason::requiresDeploymentTargetOrEarlier(
521-
ASTContext &Ctx) const {
522-
return RequiredDeploymentRange.getLowerEndpoint() <=
523-
AvailabilityContext::forDeploymentTarget(Ctx)
524-
.getVersionRange()
525-
.getLowerEndpoint();
526-
}
527-
528520
AvailabilityContext
529521
AvailabilityInference::annotatedAvailableRangeForAttr(const SpecializeAttr* attr,
530522
ASTContext &ctx) {

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,7 @@ bool TypeChecker::isDeclarationUnavailable(
14581458
return !runningOSOverApprox.isContainedIn(safeRangeUnderApprox);
14591459
}
14601460

1461-
std::optional<UnavailabilityReason>
1461+
std::optional<AvailabilityContext>
14621462
TypeChecker::checkDeclarationAvailability(const Decl *D,
14631463
const ExportContext &Where) {
14641464
// Skip computing potential unavailability if the declaration is explicitly
@@ -1471,17 +1471,13 @@ TypeChecker::checkDeclarationAvailability(const Decl *D,
14711471
return Where.getAvailabilityContext();
14721472
})) {
14731473
auto &Context = Where.getDeclContext()->getASTContext();
1474-
AvailabilityContext safeRangeUnderApprox{
1475-
AvailabilityInference::availableRange(D, Context)};
1476-
1477-
VersionRange version = safeRangeUnderApprox.getVersionRange();
1478-
return UnavailabilityReason::requiresVersionRange(version);
1474+
return AvailabilityInference::availableRange(D, Context);
14791475
}
14801476

14811477
return std::nullopt;
14821478
}
14831479

1484-
std::optional<UnavailabilityReason>
1480+
std::optional<AvailabilityContext>
14851481
TypeChecker::checkConformanceAvailability(const RootProtocolConformance *conf,
14861482
const ExtensionDecl *ext,
14871483
const ExportContext &where) {
@@ -2069,17 +2065,16 @@ static void fixAvailability(SourceRange ReferenceRange,
20692065

20702066
void TypeChecker::diagnosePotentialUnavailability(
20712067
SourceRange ReferenceRange, Diag<StringRef, llvm::VersionTuple> Diag,
2072-
const DeclContext *ReferenceDC,
2073-
const UnavailabilityReason &Reason) {
2068+
const DeclContext *ReferenceDC, const AvailabilityContext &Availability) {
20742069
ASTContext &Context = ReferenceDC->getASTContext();
20752070

2076-
auto RequiredRange = Reason.getRequiredOSVersionRange();
2071+
auto RequiredRange = Availability.getVersionRange();
20772072
{
20782073
auto Err =
20792074
Context.Diags.diagnose(
20802075
ReferenceRange.Start, Diag,
20812076
prettyPlatformString(targetPlatform(Context.LangOpts)),
2082-
Reason.getRequiredOSVersionRange().getLowerEndpoint());
2077+
RequiredRange.getLowerEndpoint());
20832078

20842079
// Direct a fixit to the error if an existing guard is nearly-correct
20852080
if (fixAvailabilityByNarrowingNearbyVersionCheck(
@@ -2090,20 +2085,19 @@ void TypeChecker::diagnosePotentialUnavailability(
20902085
}
20912086

20922087
bool TypeChecker::checkAvailability(SourceRange ReferenceRange,
2093-
AvailabilityContext Availability,
2088+
AvailabilityContext RequiredAvailability,
20942089
Diag<StringRef, llvm::VersionTuple> Diag,
20952090
const DeclContext *ReferenceDC) {
20962091
ASTContext &ctx = ReferenceDC->getASTContext();
20972092
if (ctx.LangOpts.DisableAvailabilityChecking)
20982093
return false;
20992094

2100-
auto runningOS =
2101-
TypeChecker::overApproximateAvailabilityAtLocation(
2102-
ReferenceRange.Start, ReferenceDC);
2103-
if (!runningOS.isContainedIn(Availability)) {
2095+
auto availabilityAtLocation =
2096+
TypeChecker::overApproximateAvailabilityAtLocation(ReferenceRange.Start,
2097+
ReferenceDC);
2098+
if (!availabilityAtLocation.isContainedIn(RequiredAvailability)) {
21042099
diagnosePotentialUnavailability(ReferenceRange, Diag, ReferenceDC,
2105-
UnavailabilityReason::requiresVersionRange(
2106-
Availability.getVersionRange()));
2100+
RequiredAvailability);
21072101
return true;
21082102
}
21092103

@@ -2119,17 +2113,24 @@ void TypeChecker::checkConcurrencyAvailability(SourceRange ReferenceRange,
21192113
ReferenceDC);
21202114
}
21212115

2116+
static bool
2117+
requiresDeploymentTargetOrEarlier(const AvailabilityContext &availability,
2118+
ASTContext &ctx) {
2119+
auto deploymentTarget = AvailabilityContext::forDeploymentTarget(ctx);
2120+
return deploymentTarget.isContainedIn(availability);
2121+
}
2122+
21222123
/// Returns the diagnostic to emit for the potentially unavailable decl and sets
21232124
/// \p IsError accordingly.
21242125
static Diagnostic getPotentialUnavailabilityDiagnostic(
21252126
const ValueDecl *D, const DeclContext *ReferenceDC,
2126-
const UnavailabilityReason &Reason, bool WarnBeforeDeploymentTarget,
2127+
const AvailabilityContext &Availability, bool WarnBeforeDeploymentTarget,
21272128
bool &IsError) {
21282129
ASTContext &Context = ReferenceDC->getASTContext();
21292130
auto Platform = prettyPlatformString(targetPlatform(Context.LangOpts));
2130-
auto Version = Reason.getRequiredOSVersionRange().getLowerEndpoint();
2131+
auto Version = Availability.getVersionRange().getLowerEndpoint();
21312132

2132-
if (Reason.requiresDeploymentTargetOrEarlier(Context)) {
2133+
if (requiresDeploymentTargetOrEarlier(Availability, Context)) {
21332134
// The required OS version is at or before the deployment target so this
21342135
// diagnostic should indicate that the decl could be unavailable to clients
21352136
// of the module containing the reference.
@@ -2148,18 +2149,17 @@ static Diagnostic getPotentialUnavailabilityDiagnostic(
21482149

21492150
bool TypeChecker::diagnosePotentialUnavailability(
21502151
const ValueDecl *D, SourceRange ReferenceRange,
2151-
const DeclContext *ReferenceDC,
2152-
const UnavailabilityReason &Reason,
2152+
const DeclContext *ReferenceDC, const AvailabilityContext &Availability,
21532153
bool WarnBeforeDeploymentTarget = false) {
21542154
ASTContext &Context = ReferenceDC->getASTContext();
21552155

2156-
auto RequiredRange = Reason.getRequiredOSVersionRange();
2156+
auto RequiredRange = Availability.getVersionRange();
21572157
bool IsError;
21582158
{
21592159
auto Diag = Context.Diags.diagnose(
21602160
ReferenceRange.Start,
21612161
getPotentialUnavailabilityDiagnostic(
2162-
D, ReferenceDC, Reason, WarnBeforeDeploymentTarget, IsError));
2162+
D, ReferenceDC, Availability, WarnBeforeDeploymentTarget, IsError));
21632163

21642164
// Direct a fixit to the error if an existing guard is nearly-correct
21652165
if (fixAvailabilityByNarrowingNearbyVersionCheck(
@@ -2173,7 +2173,7 @@ bool TypeChecker::diagnosePotentialUnavailability(
21732173

21742174
void TypeChecker::diagnosePotentialAccessorUnavailability(
21752175
const AccessorDecl *Accessor, SourceRange ReferenceRange,
2176-
const DeclContext *ReferenceDC, const UnavailabilityReason &Reason,
2176+
const DeclContext *ReferenceDC, const AvailabilityContext &Availability,
21772177
bool ForInout) {
21782178
ASTContext &Context = ReferenceDC->getASTContext();
21792179

@@ -2182,13 +2182,13 @@ void TypeChecker::diagnosePotentialAccessorUnavailability(
21822182
auto &diag = ForInout ? diag::availability_inout_accessor_only_version_newer
21832183
: diag::availability_decl_only_version_newer;
21842184

2185-
auto RequiredRange = Reason.getRequiredOSVersionRange();
2185+
auto RequiredRange = Availability.getVersionRange();
21862186
{
21872187
auto Err =
21882188
Context.Diags.diagnose(
21892189
ReferenceRange.Start, diag, Accessor,
21902190
prettyPlatformString(targetPlatform(Context.LangOpts)),
2191-
Reason.getRequiredOSVersionRange().getLowerEndpoint());
2191+
RequiredRange.getLowerEndpoint());
21922192

21932193

21942194
// Direct a fixit to the error if an existing guard is nearly-correct
@@ -2221,21 +2221,19 @@ behaviorLimitForExplicitUnavailability(
22212221
}
22222222

22232223
void TypeChecker::diagnosePotentialUnavailability(
2224-
const RootProtocolConformance *rootConf,
2225-
const ExtensionDecl *ext,
2226-
SourceLoc loc,
2227-
const DeclContext *dc,
2228-
const UnavailabilityReason &reason) {
2224+
const RootProtocolConformance *rootConf, const ExtensionDecl *ext,
2225+
SourceLoc loc, const DeclContext *dc,
2226+
const AvailabilityContext &availability) {
22292227
ASTContext &ctx = dc->getASTContext();
22302228

2231-
auto requiredRange = reason.getRequiredOSVersionRange();
2229+
auto requiredRange = availability.getVersionRange();
22322230
{
22332231
auto type = rootConf->getType();
22342232
auto proto = rootConf->getProtocol()->getDeclaredInterfaceType();
22352233
auto err = ctx.Diags.diagnose(
22362234
loc, diag::conformance_availability_only_version_newer, type, proto,
22372235
prettyPlatformString(targetPlatform(ctx.LangOpts)),
2238-
reason.getRequiredOSVersionRange().getLowerEndpoint());
2236+
requiredRange.getLowerEndpoint());
22392237

22402238
err.warnUntilSwiftVersion(6);
22412239
err.limitBehavior(behaviorLimitForExplicitUnavailability(rootConf, dc));
@@ -4065,20 +4063,22 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
40654063
if (!maybeUnavail.has_value())
40664064
return false;
40674065

4068-
auto unavailReason = maybeUnavail.value();
4066+
auto requiredAvailability = maybeUnavail.value();
40694067
auto *DC = Where.getDeclContext();
4068+
auto &ctx = DC->getASTContext();
40704069
if (Flags.contains(
40714070
DeclAvailabilityFlag::
40724071
AllowPotentiallyUnavailableAtOrBelowDeploymentTarget) &&
4073-
unavailReason.requiresDeploymentTargetOrEarlier(DC->getASTContext()))
4072+
requiresDeploymentTargetOrEarlier(requiredAvailability, ctx))
40744073
return false;
40754074

40764075
if (accessor) {
40774076
bool forInout = Flags.contains(DeclAvailabilityFlag::ForInout);
40784077
TypeChecker::diagnosePotentialAccessorUnavailability(
4079-
accessor, R, DC, unavailReason, forInout);
4078+
accessor, R, DC, requiredAvailability, forInout);
40804079
} else {
4081-
if (!TypeChecker::diagnosePotentialUnavailability(D, R, DC, unavailReason))
4080+
if (!TypeChecker::diagnosePotentialUnavailability(D, R, DC,
4081+
requiredAvailability))
40824082
return false;
40834083
}
40844084

lib/Sema/TypeChecker.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,17 +1029,15 @@ bool isDeclarationUnavailable(
10291029
llvm::function_ref<AvailabilityContext()> getAvailabilityContext);
10301030

10311031
/// Checks whether a declaration should be considered unavailable when
1032-
/// referred to at the given location and, if so, returns the reason why the
1033-
/// declaration is unavailable. Returns None is the declaration is
1034-
/// definitely available.
1035-
std::optional<UnavailabilityReason>
1032+
/// referred to at the given location and, if so, returns the unmet required
1033+
/// version range. Returns None is the declaration is definitely available.
1034+
std::optional<AvailabilityContext>
10361035
checkDeclarationAvailability(const Decl *D, const ExportContext &Where);
10371036

10381037
/// Checks whether a conformance should be considered unavailable when
1039-
/// referred to at the given location and, if so, returns the reason why the
1040-
/// declaration is unavailable. Returns None is the declaration is
1041-
/// definitely available.
1042-
std::optional<UnavailabilityReason>
1038+
/// referred to at the given location and, if so, returns the unmet required
1039+
/// version range. Returns None is the declaration is definitely available.
1040+
std::optional<AvailabilityContext>
10431041
checkConformanceAvailability(const RootProtocolConformance *Conf,
10441042
const ExtensionDecl *Ext,
10451043
const ExportContext &Where);
@@ -1056,7 +1054,7 @@ void checkIgnoredExpr(Expr *E);
10561054
bool diagnosePotentialUnavailability(const ValueDecl *D,
10571055
SourceRange ReferenceRange,
10581056
const DeclContext *ReferenceDC,
1059-
const UnavailabilityReason &Reason,
1057+
const AvailabilityContext &Availability,
10601058
bool WarnBeforeDeploymentTarget);
10611059

10621060
// Emits a diagnostic for a protocol conformance that is potentially
@@ -1065,13 +1063,13 @@ void diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
10651063
const ExtensionDecl *ext,
10661064
SourceLoc loc,
10671065
const DeclContext *dc,
1068-
const UnavailabilityReason &reason);
1066+
const AvailabilityContext &availability);
10691067

10701068
void
10711069
diagnosePotentialUnavailability(SourceRange ReferenceRange,
10721070
Diag<StringRef, llvm::VersionTuple> Diag,
10731071
const DeclContext *ReferenceDC,
1074-
const UnavailabilityReason &Reason);
1072+
const AvailabilityContext &Availability);
10751073

10761074
/// Type check a 'distributed actor' declaration.
10771075
void checkDistributedActor(SourceFile *SF, NominalTypeDecl *decl);
@@ -1082,7 +1080,7 @@ void checkDistributedActor(SourceFile *SF, NominalTypeDecl *decl);
10821080
bool checkDistributedFunc(FuncDecl *func);
10831081

10841082
bool checkAvailability(SourceRange ReferenceRange,
1085-
AvailabilityContext Availability,
1083+
AvailabilityContext RequiredAvailability,
10861084
Diag<StringRef, llvm::VersionTuple> Diag,
10871085
const DeclContext *ReferenceDC);
10881086

@@ -1093,7 +1091,7 @@ void checkConcurrencyAvailability(SourceRange ReferenceRange,
10931091
/// potentially unavailable.
10941092
void diagnosePotentialAccessorUnavailability(
10951093
const AccessorDecl *Accessor, SourceRange ReferenceRange,
1096-
const DeclContext *ReferenceDC, const UnavailabilityReason &Reason,
1094+
const DeclContext *ReferenceDC, const AvailabilityContext &Availability,
10971095
bool ForInout);
10981096

10991097
/// Returns the availability attribute indicating deprecation if the

0 commit comments

Comments
 (0)