@@ -316,19 +316,6 @@ ExportContext::getExportabilityReason() const {
316
316
return std::nullopt;
317
317
}
318
318
319
- std::optional<AvailabilityRange>
320
- UnmetAvailabilityRequirement::getRequiredNewerAvailabilityRange (
321
- ASTContext &ctx) const {
322
- switch (kind) {
323
- case Kind::AlwaysUnavailable:
324
- case Kind::RequiresVersion:
325
- case Kind::Obsoleted:
326
- return std::nullopt;
327
- case Kind::IntroducedInNewerVersion:
328
- return AvailabilityInference::availableRange (attr, ctx);
329
- }
330
- }
331
-
332
319
// / Returns the first availability attribute on the declaration that is active
333
320
// / on the target platform.
334
321
static const AvailableAttr *getActiveAvailableAttribute (const Decl *D,
@@ -1478,62 +1465,6 @@ AvailabilityRange TypeChecker::overApproximateAvailabilityAtLocation(
1478
1465
return availabilityAtLocation (loc, DC, MostRefined).getPlatformRange ();
1479
1466
}
1480
1467
1481
- bool TypeChecker::isDeclarationUnavailable (
1482
- const Decl *D, const DeclContext *referenceDC,
1483
- llvm::function_ref<AvailabilityRange()> getAvailabilityRange) {
1484
- ASTContext &Context = referenceDC->getASTContext ();
1485
- if (Context.LangOpts .DisableAvailabilityChecking ) {
1486
- return false ;
1487
- }
1488
-
1489
- if (!referenceDC->getParentSourceFile ()) {
1490
- // We only check availability if this reference is in a source file; we do
1491
- // not check in other kinds of FileUnits.
1492
- return false ;
1493
- }
1494
-
1495
- AvailabilityRange safeRangeUnderApprox{
1496
- AvailabilityInference::availableRange (D)};
1497
-
1498
- if (safeRangeUnderApprox.isAlwaysAvailable ())
1499
- return false ;
1500
-
1501
- AvailabilityRange runningOSOverApprox = getAvailabilityRange ();
1502
-
1503
- // The reference is safe if an over-approximation of the running OS
1504
- // versions is fully contained within an under-approximation
1505
- // of the versions on which the declaration is available. If this
1506
- // containment cannot be guaranteed, we say the reference is
1507
- // not available.
1508
- return !runningOSOverApprox.isContainedIn (safeRangeUnderApprox);
1509
- }
1510
-
1511
- std::optional<AvailabilityRange>
1512
- TypeChecker::checkDeclarationAvailability (const Decl *D,
1513
- const ExportContext &Where) {
1514
- // Skip computing potential unavailability if the declaration is explicitly
1515
- // unavailable and the context is also unavailable.
1516
- if (const AvailableAttr *Attr = AvailableAttr::isUnavailable (D))
1517
- if (isInsideCompatibleUnavailableDeclaration (D, Where.getAvailability (),
1518
- Attr))
1519
- return std::nullopt;
1520
-
1521
- if (isDeclarationUnavailable (D, Where.getDeclContext (), [&Where] {
1522
- return Where.getAvailabilityRange ();
1523
- })) {
1524
- return AvailabilityInference::availableRange (D);
1525
- }
1526
-
1527
- return std::nullopt;
1528
- }
1529
-
1530
- std::optional<AvailabilityRange>
1531
- TypeChecker::checkConformanceAvailability (const RootProtocolConformance *conf,
1532
- const ExtensionDecl *ext,
1533
- const ExportContext &where) {
1534
- return checkDeclarationAvailability (ext, where);
1535
- }
1536
-
1537
1468
// / A class that walks the AST to find the innermost (i.e., deepest) node that
1538
1469
// / contains a target SourceRange and matches a particular criterion.
1539
1470
// / This class finds the innermost nodes of interest by walking
@@ -2275,12 +2206,14 @@ behaviorLimitForExplicitUnavailability(
2275
2206
2276
2207
// / Emits a diagnostic for a protocol conformance that is potentially
2277
2208
// / unavailable at the given source location.
2278
- static void
2209
+ static bool
2279
2210
diagnosePotentialUnavailability (const RootProtocolConformance *rootConf,
2280
2211
const ExtensionDecl *ext, SourceLoc loc,
2281
2212
const DeclContext *dc,
2282
2213
const AvailabilityRange &availability) {
2283
2214
ASTContext &ctx = dc->getASTContext ();
2215
+ if (ctx.LangOpts .DisableAvailabilityChecking )
2216
+ return false ;
2284
2217
2285
2218
{
2286
2219
auto type = rootConf->getType ();
@@ -2296,10 +2229,11 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
2296
2229
// Direct a fixit to the error if an existing guard is nearly-correct
2297
2230
if (fixAvailabilityByNarrowingNearbyVersionCheck (loc, dc, availability, ctx,
2298
2231
err))
2299
- return ;
2232
+ return true ;
2300
2233
}
2301
2234
2302
2235
fixAvailability (loc, dc, availability, ctx);
2236
+ return true ;
2303
2237
}
2304
2238
2305
2239
// / Returns the availability attribute indicating deprecation of the
@@ -3099,9 +3033,9 @@ bool diagnoseExplicitUnavailability(
3099
3033
}
3100
3034
3101
3035
std::optional<UnmetAvailabilityRequirement>
3102
- swift::checkDeclarationAvailability ( const Decl *decl,
3103
- const DeclContext *declContext,
3104
- AvailabilityContext availabilityContext) {
3036
+ swift::getUnmetDeclAvailabilityRequirement (
3037
+ const Decl *decl, const DeclContext *declContext,
3038
+ AvailabilityContext availabilityContext) {
3105
3039
auto &ctx = declContext->getASTContext ();
3106
3040
3107
3041
// Generic parameters are always available.
@@ -3140,6 +3074,14 @@ swift::checkDeclarationAvailability(const Decl *decl,
3140
3074
return std::nullopt;
3141
3075
}
3142
3076
3077
+ std::optional<UnmetAvailabilityRequirement>
3078
+ swift::getUnmetDeclAvailabilityRequirement (const Decl *decl,
3079
+ const DeclContext *referenceDC,
3080
+ SourceLoc referenceLoc) {
3081
+ return getUnmetDeclAvailabilityRequirement (
3082
+ decl, referenceDC,
3083
+ TypeChecker::availabilityAtLocation (referenceLoc, referenceDC));
3084
+ }
3143
3085
3144
3086
// / Check if this is a subscript declaration inside String or
3145
3087
// / Substring that returns String, and if so return true.
@@ -4153,13 +4095,9 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
4153
4095
auto &ctx = DC->getASTContext ();
4154
4096
4155
4097
auto unmetRequirement =
4156
- checkDeclarationAvailability (D, DC, Where.getAvailability ());
4157
- auto requiredRange =
4158
- unmetRequirement
4159
- ? unmetRequirement->getRequiredNewerAvailabilityRange (ctx)
4160
- : std::nullopt;
4098
+ getUnmetDeclAvailabilityRequirement (D, DC, Where.getAvailability ());
4161
4099
4162
- if (unmetRequirement && !requiredRange ) {
4100
+ if (unmetRequirement && !unmetRequirement-> isConditionallySatisfiable () ) {
4163
4101
// FIXME: diagnoseExplicitUnavailability should take an unmet requirement
4164
4102
if (diagnoseExplicitUnavailability (D, R, Where, call, Flags))
4165
4103
return true ;
@@ -4183,6 +4121,11 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
4183
4121
&& isa<ProtocolDecl>(D))
4184
4122
return false ;
4185
4123
4124
+ if (!unmetRequirement)
4125
+ return false ;
4126
+
4127
+ auto requiredRange = unmetRequirement->getRequiredNewerAvailabilityRange (ctx);
4128
+
4186
4129
// Diagnose (and possibly signal) for potential unavailability
4187
4130
if (!requiredRange)
4188
4131
return false ;
@@ -4630,6 +4573,7 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
4630
4573
// Diagnose "missing" conformances where we needed a conformance but
4631
4574
// didn't have one.
4632
4575
auto *DC = where.getDeclContext ();
4576
+ auto &ctx = DC->getASTContext ();
4633
4577
if (auto builtinConformance = dyn_cast<BuiltinProtocolConformance>(rootConf)){
4634
4578
if (builtinConformance->isMissing ()) {
4635
4579
diagnoseMissingConformance (loc, builtinConformance->getType (),
@@ -4643,7 +4587,6 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
4643
4587
4644
4588
Type selfTy = rootConf->getProtocol ()->getSelfInterfaceType ();
4645
4589
if (!depTy->isEqual (selfTy)) {
4646
- auto &ctx = DC->getASTContext ();
4647
4590
ctx.Diags .diagnose (
4648
4591
loc,
4649
4592
diag::assoc_conformance_from_implementation_only_module,
@@ -4658,20 +4601,26 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
4658
4601
return true ;
4659
4602
}
4660
4603
4661
- if (diagnoseExplicitUnavailability (loc, rootConf, ext, where,
4662
- warnIfConformanceUnavailablePreSwift6)) {
4663
- maybeEmitAssociatedTypeNote ();
4664
- return true ;
4665
- }
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
+ }
4666
4614
4667
- // Diagnose (and possibly signal) for potential unavailability
4668
- auto maybeUnavail = TypeChecker::checkConformanceAvailability (
4669
- rootConf, ext, where);
4670
- if (maybeUnavail.has_value ()) {
4671
- diagnosePotentialUnavailability (rootConf, ext, loc, DC,
4672
- maybeUnavail.value ());
4673
- maybeEmitAssociatedTypeNote ();
4674
- 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
+ }
4675
4624
}
4676
4625
4677
4626
// Diagnose for deprecation
0 commit comments