Skip to content

Commit c044321

Browse files
committed
Sema: Replace TypeChecker::checkConformanceAvailability().
Adopt `getUnmetDeclAvailabilityRequirement()` instead.
1 parent 7b5757b commit c044321

File tree

2 files changed

+25
-79
lines changed

2 files changed

+25
-79
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 25 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,61 +1465,6 @@ AvailabilityRange TypeChecker::overApproximateAvailabilityAtLocation(
14651465
return availabilityAtLocation(loc, DC, MostRefined).getPlatformRange();
14661466
}
14671467

1468-
static bool isDeclarationUnavailable(
1469-
const Decl *D, const DeclContext *referenceDC,
1470-
llvm::function_ref<AvailabilityRange()> getAvailabilityRange) {
1471-
ASTContext &Context = referenceDC->getASTContext();
1472-
if (Context.LangOpts.DisableAvailabilityChecking) {
1473-
return false;
1474-
}
1475-
1476-
if (!referenceDC->getParentSourceFile()) {
1477-
// We only check availability if this reference is in a source file; we do
1478-
// not check in other kinds of FileUnits.
1479-
return false;
1480-
}
1481-
1482-
AvailabilityRange safeRangeUnderApprox{
1483-
AvailabilityInference::availableRange(D)};
1484-
1485-
if (safeRangeUnderApprox.isAlwaysAvailable())
1486-
return false;
1487-
1488-
AvailabilityRange runningOSOverApprox = getAvailabilityRange();
1489-
1490-
// The reference is safe if an over-approximation of the running OS
1491-
// versions is fully contained within an under-approximation
1492-
// of the versions on which the declaration is available. If this
1493-
// containment cannot be guaranteed, we say the reference is
1494-
// not available.
1495-
return !runningOSOverApprox.isContainedIn(safeRangeUnderApprox);
1496-
}
1497-
1498-
static std::optional<AvailabilityRange>
1499-
checkDeclarationAvailability(const Decl *D, const ExportContext &Where) {
1500-
// Skip computing potential unavailability if the declaration is explicitly
1501-
// unavailable and the context is also unavailable.
1502-
if (const AvailableAttr *Attr = AvailableAttr::isUnavailable(D))
1503-
if (isInsideCompatibleUnavailableDeclaration(D, Where.getAvailability(),
1504-
Attr))
1505-
return std::nullopt;
1506-
1507-
if (isDeclarationUnavailable(D, Where.getDeclContext(), [&Where] {
1508-
return Where.getAvailabilityRange();
1509-
})) {
1510-
return AvailabilityInference::availableRange(D);
1511-
}
1512-
1513-
return std::nullopt;
1514-
}
1515-
1516-
std::optional<AvailabilityRange>
1517-
TypeChecker::checkConformanceAvailability(const RootProtocolConformance *conf,
1518-
const ExtensionDecl *ext,
1519-
const ExportContext &where) {
1520-
return checkDeclarationAvailability(ext, where);
1521-
}
1522-
15231468
/// A class that walks the AST to find the innermost (i.e., deepest) node that
15241469
/// contains a target SourceRange and matches a particular criterion.
15251470
/// This class finds the innermost nodes of interest by walking
@@ -2261,12 +2206,14 @@ behaviorLimitForExplicitUnavailability(
22612206

22622207
/// Emits a diagnostic for a protocol conformance that is potentially
22632208
/// unavailable at the given source location.
2264-
static void
2209+
static bool
22652210
diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
22662211
const ExtensionDecl *ext, SourceLoc loc,
22672212
const DeclContext *dc,
22682213
const AvailabilityRange &availability) {
22692214
ASTContext &ctx = dc->getASTContext();
2215+
if (ctx.LangOpts.DisableAvailabilityChecking)
2216+
return false;
22702217

22712218
{
22722219
auto type = rootConf->getType();
@@ -2282,10 +2229,11 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
22822229
// Direct a fixit to the error if an existing guard is nearly-correct
22832230
if (fixAvailabilityByNarrowingNearbyVersionCheck(loc, dc, availability, ctx,
22842231
err))
2285-
return;
2232+
return true;
22862233
}
22872234

22882235
fixAvailability(loc, dc, availability, ctx);
2236+
return true;
22892237
}
22902238

22912239
/// Returns the availability attribute indicating deprecation of the
@@ -4625,6 +4573,7 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46254573
// Diagnose "missing" conformances where we needed a conformance but
46264574
// didn't have one.
46274575
auto *DC = where.getDeclContext();
4576+
auto &ctx = DC->getASTContext();
46284577
if (auto builtinConformance = dyn_cast<BuiltinProtocolConformance>(rootConf)){
46294578
if (builtinConformance->isMissing()) {
46304579
diagnoseMissingConformance(loc, builtinConformance->getType(),
@@ -4638,7 +4587,6 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46384587

46394588
Type selfTy = rootConf->getProtocol()->getSelfInterfaceType();
46404589
if (!depTy->isEqual(selfTy)) {
4641-
auto &ctx = DC->getASTContext();
46424590
ctx.Diags.diagnose(
46434591
loc,
46444592
diag::assoc_conformance_from_implementation_only_module,
@@ -4653,20 +4601,26 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46534601
return true;
46544602
}
46554603

4656-
if (diagnoseExplicitUnavailability(loc, rootConf, ext, where,
4657-
warnIfConformanceUnavailablePreSwift6)) {
4658-
maybeEmitAssociatedTypeNote();
4659-
return true;
4660-
}
4604+
auto unmetRequirement = getUnmetDeclAvailabilityRequirement(
4605+
ext, where.getDeclContext(), where.getAvailability());
4606+
if (unmetRequirement) {
4607+
// FIXME: diagnoseExplicitUnavailability() should take unmet requirement
4608+
if (diagnoseExplicitUnavailability(
4609+
loc, rootConf, ext, where,
4610+
warnIfConformanceUnavailablePreSwift6)) {
4611+
maybeEmitAssociatedTypeNote();
4612+
return true;
4613+
}
46614614

4662-
// Diagnose (and possibly signal) for potential unavailability
4663-
auto maybeUnavail = TypeChecker::checkConformanceAvailability(
4664-
rootConf, ext, where);
4665-
if (maybeUnavail.has_value()) {
4666-
diagnosePotentialUnavailability(rootConf, ext, loc, DC,
4667-
maybeUnavail.value());
4668-
maybeEmitAssociatedTypeNote();
4669-
return true;
4615+
// Diagnose (and possibly signal) for potential unavailability
4616+
if (auto requiredRange =
4617+
unmetRequirement->getRequiredNewerAvailabilityRange(ctx)) {
4618+
if (diagnosePotentialUnavailability(rootConf, ext, loc, DC,
4619+
*requiredRange)) {
4620+
maybeEmitAssociatedTypeNote();
4621+
return true;
4622+
}
4623+
}
46704624
}
46714625

46724626
// Diagnose for deprecation

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,14 +1032,6 @@ diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D);
10321032
/// is allowed.
10331033
std::optional<Diagnostic> diagnosticIfDeclCannotBeUnavailable(const Decl *D);
10341034

1035-
/// Checks whether a conformance should be considered unavailable when
1036-
/// referred to at the given location and, if so, returns the unmet required
1037-
/// version range. Returns None is the declaration is definitely available.
1038-
std::optional<AvailabilityRange>
1039-
checkConformanceAvailability(const RootProtocolConformance *Conf,
1040-
const ExtensionDecl *Ext,
1041-
const ExportContext &Where);
1042-
10431035
bool checkAvailability(
10441036
SourceRange ReferenceRange, AvailabilityRange RequiredAvailability,
10451037
const DeclContext *ReferenceDC,

0 commit comments

Comments
 (0)