Skip to content

Commit 919ec93

Browse files
authored
Merge pull request #77384 from tshortli/rename-unmet-availability-requirement
2 parents d479d74 + 161dc2e commit 919ec93

9 files changed

+142
-110
lines changed

include/swift/AST/Availability.h

-72
Original file line numberDiff line numberDiff line change
@@ -335,78 +335,6 @@ class AvailabilityRange {
335335
}
336336
};
337337

338-
/// Represents the reason a declaration is considered unavailable in a certain
339-
/// context.
340-
class UnmetAvailabilityRequirement {
341-
public:
342-
enum class Kind {
343-
/// The declaration is referenced in a context in which it is
344-
/// generally unavailable. For example, a reference to a declaration that is
345-
/// unavailable on macOS from a context that may execute on macOS has this
346-
/// unmet requirement.
347-
AlwaysUnavailable,
348-
349-
/// The declaration is referenced in a context in which it is considered
350-
/// obsolete. For example, a reference to a declaration that is obsolete in
351-
/// macOS 13 from a context that may execute on macOS 13 or later has this
352-
/// unmet requirement.
353-
Obsoleted,
354-
355-
/// The declaration is only available in a different version. For example,
356-
/// the declaration might only be introduced in the Swift 6 language mode
357-
/// while the module is being compiled in the Swift 5 language mode.
358-
RequiresVersion,
359-
360-
/// The declaration is referenced in a context that does not have an
361-
/// adequate minimum version constraint. For example, a reference to a
362-
/// declaration that is introduced in macOS 13 from a context that may
363-
/// execute on earlier versions of macOS has this unmet requirement. This
364-
/// kind of unmet requirement can be addressed by tightening the minimum
365-
/// version of the context with `if #available(...)` or by adding or
366-
/// adjusting an `@available` attribute.
367-
IntroducedInNewerVersion,
368-
};
369-
370-
private:
371-
Kind kind;
372-
const AvailableAttr *attr;
373-
374-
UnmetAvailabilityRequirement(Kind kind, const AvailableAttr *attr)
375-
: kind(kind), attr(attr){};
376-
377-
public:
378-
static UnmetAvailabilityRequirement
379-
forAlwaysUnavailable(const AvailableAttr *attr) {
380-
return UnmetAvailabilityRequirement(Kind::AlwaysUnavailable, attr);
381-
}
382-
383-
static UnmetAvailabilityRequirement forObsoleted(const AvailableAttr *attr) {
384-
return UnmetAvailabilityRequirement(Kind::Obsoleted, attr);
385-
}
386-
387-
static UnmetAvailabilityRequirement
388-
forRequiresVersion(const AvailableAttr *attr) {
389-
return UnmetAvailabilityRequirement(Kind::RequiresVersion, attr);
390-
}
391-
392-
static UnmetAvailabilityRequirement
393-
forIntroducedInNewerVersion(const AvailableAttr *attr) {
394-
return UnmetAvailabilityRequirement(Kind::IntroducedInNewerVersion, attr);
395-
}
396-
397-
Kind getKind() const { return kind; }
398-
const AvailableAttr *getAttr() const { return attr; }
399-
400-
/// Returns the required range for `IntroducedInNewerVersion` requirements, or
401-
/// `std::nullopt` otherwise.
402-
std::optional<AvailabilityRange>
403-
getRequiredNewerAvailabilityRange(ASTContext &ctx) const;
404-
405-
/// Returns true if this unmet requirement can be satisfied by introducing an
406-
/// `if #available(...)` condition in source.
407-
bool isConditionallySatisfiable() const;
408-
};
409-
410338
class AvailabilityInference {
411339
public:
412340
/// Returns the decl that should be considered the parent decl of the given
+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//===--- AvailabilityConstraint.h - Swift Availability Constraints ------*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the AvailabilityConstraint class.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_AVAILABILITY_CONSTRAINT_H
18+
#define SWIFT_AST_AVAILABILITY_CONSTRAINT_H
19+
20+
#include "swift/AST/Availability.h"
21+
#include "swift/AST/PlatformKind.h"
22+
#include "swift/Basic/LLVM.h"
23+
24+
namespace swift {
25+
26+
class ASTContext;
27+
class AvailableAttr;
28+
29+
/// Represents the reason a declaration could be considered unavailable in a
30+
/// certain context.
31+
class AvailabilityConstraint {
32+
public:
33+
enum class Kind {
34+
/// The declaration is referenced in a context in which it is generally
35+
/// unavailable. For example, a reference to a declaration that is
36+
/// unavailable on macOS from a context that may execute on macOS has this
37+
/// constraint.
38+
AlwaysUnavailable,
39+
40+
/// The declaration is referenced in a context in which it is considered
41+
/// obsolete. For example, a reference to a declaration that is obsolete in
42+
/// macOS 13 from a context that may execute on macOS 13 or later has this
43+
/// constraint.
44+
Obsoleted,
45+
46+
/// The declaration is only available in a different version. For example,
47+
/// the declaration might only be introduced in the Swift 6 language mode
48+
/// while the module is being compiled in the Swift 5 language mode.
49+
RequiresVersion,
50+
51+
/// The declaration is referenced in a context that does not have an
52+
/// adequate minimum version constraint. For example, a reference to a
53+
/// declaration that is introduced in macOS 13 from a context that may
54+
/// execute on earlier versions of macOS has this constraint. This
55+
/// kind of constraint can be satisfied by tightening the minimum
56+
/// version of the context with `if #available(...)` or by adding or
57+
/// adjusting an `@available` attribute.
58+
IntroducedInNewerVersion,
59+
};
60+
61+
private:
62+
Kind kind;
63+
const AvailableAttr *attr;
64+
65+
AvailabilityConstraint(Kind kind, const AvailableAttr *attr)
66+
: kind(kind), attr(attr) {};
67+
68+
public:
69+
static AvailabilityConstraint
70+
forAlwaysUnavailable(const AvailableAttr *attr) {
71+
return AvailabilityConstraint(Kind::AlwaysUnavailable, attr);
72+
}
73+
74+
static AvailabilityConstraint forObsoleted(const AvailableAttr *attr) {
75+
return AvailabilityConstraint(Kind::Obsoleted, attr);
76+
}
77+
78+
static AvailabilityConstraint forRequiresVersion(const AvailableAttr *attr) {
79+
return AvailabilityConstraint(Kind::RequiresVersion, attr);
80+
}
81+
82+
static AvailabilityConstraint
83+
forIntroducedInNewerVersion(const AvailableAttr *attr) {
84+
return AvailabilityConstraint(Kind::IntroducedInNewerVersion, attr);
85+
}
86+
87+
Kind getKind() const { return kind; }
88+
const AvailableAttr *getAttr() const { return attr; }
89+
90+
/// Returns the required range for `IntroducedInNewerVersion` requirements, or
91+
/// `std::nullopt` otherwise.
92+
std::optional<AvailabilityRange>
93+
getRequiredNewerAvailabilityRange(ASTContext &ctx) const;
94+
95+
/// Returns true if this unmet requirement can be satisfied by introducing an
96+
/// `if #available(...)` condition in source.
97+
bool isConditionallySatisfiable() const;
98+
};
99+
100+
} // end namespace swift
101+
102+
#endif

lib/AST/Availability.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/Availability.h"
1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/Attr.h"
20+
#include "swift/AST/AvailabilityConstraint.h"
2021
#include "swift/AST/Decl.h"
2122
#include "swift/AST/PlatformKind.h"
2223
#include "swift/AST/TypeCheckRequests.h"
@@ -65,7 +66,7 @@ AvailabilityRange AvailabilityRange::forRuntimeTarget(const ASTContext &Ctx) {
6566
}
6667

6768
std::optional<AvailabilityRange>
68-
UnmetAvailabilityRequirement::getRequiredNewerAvailabilityRange(
69+
AvailabilityConstraint::getRequiredNewerAvailabilityRange(
6970
ASTContext &ctx) const {
7071
switch (kind) {
7172
case Kind::AlwaysUnavailable:
@@ -77,7 +78,7 @@ UnmetAvailabilityRequirement::getRequiredNewerAvailabilityRange(
7778
}
7879
}
7980

80-
bool UnmetAvailabilityRequirement::isConditionallySatisfiable() const {
81+
bool AvailabilityConstraint::isConditionallySatisfiable() const {
8182
switch (kind) {
8283
case Kind::AlwaysUnavailable:
8384
case Kind::RequiresVersion:

lib/Sema/BuilderTransform.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ ResultBuilderOpSupport TypeChecker::checkBuilderOpSupport(
13181318

13191319
auto isUnavailable = [&](Decl *D) -> bool {
13201320
auto loc = extractNearestSourceLoc(dc);
1321-
return getUnmetDeclAvailabilityRequirement(D, dc, loc).has_value();
1321+
return getUnsatisfiedAvailabilityConstraint(D, dc, loc).has_value();
13221322
};
13231323

13241324
bool foundMatch = false;

lib/Sema/CSSyntacticElement.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2475,9 +2475,9 @@ class ResultBuilderRewriter : public SyntacticElementSolutionApplication {
24752475
if (!nominal)
24762476
return false;
24772477

2478-
auto unmetRequirement = getUnmetDeclAvailabilityRequirement(
2478+
auto constraint = getUnsatisfiedAvailabilityConstraint(
24792479
nominal, context.getAsDeclContext(), loc);
2480-
if (unmetRequirement && unmetRequirement->isConditionallySatisfiable()) {
2480+
if (constraint && constraint->isConditionallySatisfiable()) {
24812481
auto &ctx = getASTContext();
24822482
ctx.Diags.diagnose(loc,
24832483
diag::result_builder_missing_limited_availability,

lib/Sema/ConstraintSystem.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -4682,7 +4682,7 @@ bool ConstraintSystem::isDeclUnavailable(const Decl *D,
46824682
loc = getLoc(anchor);
46834683
}
46844684

4685-
return getUnmetDeclAvailabilityRequirement(D, DC, loc).has_value();
4685+
return getUnsatisfiedAvailabilityConstraint(D, DC, loc).has_value();
46864686
}
46874687

46884688
bool ConstraintSystem::isConformanceUnavailable(ProtocolConformanceRef conformance,
@@ -4881,9 +4881,9 @@ bool ConstraintSystem::isReadOnlyKeyPathComponent(
48814881
if (auto setter = storage->getOpaqueAccessor(AccessorKind::Set)) {
48824882
// FIXME: Fully unavailable setters should cause the key path to be
48834883
// readonly too.
4884-
auto unmetRequirement =
4885-
getUnmetDeclAvailabilityRequirement(setter, DC, referenceLoc);
4886-
if (unmetRequirement && unmetRequirement->isConditionallySatisfiable())
4884+
auto constraint =
4885+
getUnsatisfiedAvailabilityConstraint(setter, DC, referenceLoc);
4886+
if (constraint && constraint->isConditionallySatisfiable())
48874887
return true;
48884888
}
48894889

lib/Sema/TypeCheckAvailability.cpp

+19-19
Original file line numberDiff line numberDiff line change
@@ -3032,8 +3032,8 @@ bool diagnoseExplicitUnavailability(
30323032
return true;
30333033
}
30343034

3035-
std::optional<UnmetAvailabilityRequirement>
3036-
swift::getUnmetDeclAvailabilityRequirement(
3035+
std::optional<AvailabilityConstraint>
3036+
swift::getUnsatisfiedAvailabilityConstraint(
30373037
const Decl *decl, const DeclContext *declContext,
30383038
AvailabilityContext availabilityContext) {
30393039
auto &ctx = declContext->getASTContext();
@@ -3056,29 +3056,29 @@ swift::getUnmetDeclAvailabilityRequirement(
30563056
if ((attr->isLanguageVersionSpecific() ||
30573057
attr->isPackageDescriptionVersionSpecific()) &&
30583058
attr->Introduced.has_value())
3059-
return UnmetAvailabilityRequirement::forRequiresVersion(attr);
3059+
return AvailabilityConstraint::forRequiresVersion(attr);
30603060

3061-
return UnmetAvailabilityRequirement::forAlwaysUnavailable(attr);
3061+
return AvailabilityConstraint::forAlwaysUnavailable(attr);
30623062

30633063
case AvailableVersionComparison::Obsoleted:
3064-
return UnmetAvailabilityRequirement::forObsoleted(attr);
3064+
return AvailabilityConstraint::forObsoleted(attr);
30653065
}
30663066
}
30673067

30683068
// Check whether the declaration is available in a newer platform version.
30693069
auto rangeAndAttr = AvailabilityInference::availableRangeAndAttr(decl);
30703070
if (!availabilityContext.getPlatformRange().isContainedIn(rangeAndAttr.first))
3071-
return UnmetAvailabilityRequirement::forIntroducedInNewerVersion(
3071+
return AvailabilityConstraint::forIntroducedInNewerVersion(
30723072
rangeAndAttr.second);
30733073

30743074
return std::nullopt;
30753075
}
30763076

3077-
std::optional<UnmetAvailabilityRequirement>
3078-
swift::getUnmetDeclAvailabilityRequirement(const Decl *decl,
3079-
const DeclContext *referenceDC,
3080-
SourceLoc referenceLoc) {
3081-
return getUnmetDeclAvailabilityRequirement(
3077+
std::optional<AvailabilityConstraint>
3078+
swift::getUnsatisfiedAvailabilityConstraint(const Decl *decl,
3079+
const DeclContext *referenceDC,
3080+
SourceLoc referenceLoc) {
3081+
return getUnsatisfiedAvailabilityConstraint(
30823082
decl, referenceDC,
30833083
TypeChecker::availabilityAtLocation(referenceLoc, referenceDC));
30843084
}
@@ -4094,10 +4094,10 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
40944094
auto *DC = Where.getDeclContext();
40954095
auto &ctx = DC->getASTContext();
40964096

4097-
auto unmetRequirement =
4098-
getUnmetDeclAvailabilityRequirement(D, DC, Where.getAvailability());
4097+
auto constraint =
4098+
getUnsatisfiedAvailabilityConstraint(D, DC, Where.getAvailability());
40994099

4100-
if (unmetRequirement && !unmetRequirement->isConditionallySatisfiable()) {
4100+
if (constraint && !constraint->isConditionallySatisfiable()) {
41014101
// FIXME: diagnoseExplicitUnavailability should take an unmet requirement
41024102
if (diagnoseExplicitUnavailability(D, R, Where, call, Flags))
41034103
return true;
@@ -4121,10 +4121,10 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
41214121
&& isa<ProtocolDecl>(D))
41224122
return false;
41234123

4124-
if (!unmetRequirement)
4124+
if (!constraint)
41254125
return false;
41264126

4127-
auto requiredRange = unmetRequirement->getRequiredNewerAvailabilityRange(ctx);
4127+
auto requiredRange = constraint->getRequiredNewerAvailabilityRange(ctx);
41284128

41294129
// Diagnose (and possibly signal) for potential unavailability
41304130
if (!requiredRange)
@@ -4601,9 +4601,9 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46014601
return true;
46024602
}
46034603

4604-
auto unmetRequirement = getUnmetDeclAvailabilityRequirement(
4604+
auto constraint = getUnsatisfiedAvailabilityConstraint(
46054605
ext, where.getDeclContext(), where.getAvailability());
4606-
if (unmetRequirement) {
4606+
if (constraint) {
46074607
// FIXME: diagnoseExplicitUnavailability() should take unmet requirement
46084608
if (diagnoseExplicitUnavailability(
46094609
loc, rootConf, ext, where,
@@ -4614,7 +4614,7 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46144614

46154615
// Diagnose (and possibly signal) for potential unavailability
46164616
if (auto requiredRange =
4617-
unmetRequirement->getRequiredNewerAvailabilityRange(ctx)) {
4617+
constraint->getRequiredNewerAvailabilityRange(ctx)) {
46184618
if (diagnosePotentialUnavailability(rootConf, ext, loc, DC,
46194619
*requiredRange)) {
46204620
maybeEmitAssociatedTypeNote();

lib/Sema/TypeCheckAvailability.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_SEMA_TYPE_CHECK_AVAILABILITY_H
1515

1616
#include "swift/AST/AttrKind.h"
17+
#include "swift/AST/AvailabilityConstraint.h"
1718
#include "swift/AST/AvailabilityContext.h"
1819
#include "swift/AST/DeclContext.h"
1920
#include "swift/AST/Identifier.h"
@@ -245,18 +246,18 @@ void diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
245246

246247
/// Checks whether a declaration should be considered unavailable when referred
247248
/// to in the given declaration context and availability context and, if so,
248-
/// returns a result that describes the unmet availability requirements.
249+
/// returns a result that describes the unsatisfied constraint.
249250
/// Returns `std::nullopt` if the declaration is available.
250-
std::optional<UnmetAvailabilityRequirement>
251-
getUnmetDeclAvailabilityRequirement(const Decl *decl,
252-
const DeclContext *declContext,
253-
AvailabilityContext availabilityContext);
251+
std::optional<AvailabilityConstraint>
252+
getUnsatisfiedAvailabilityConstraint(const Decl *decl,
253+
const DeclContext *declContext,
254+
AvailabilityContext availabilityContext);
254255

255256
/// Checks whether a declaration should be considered unavailable when referred
256257
/// to at the given source location in the given decl context and, if so,
257-
/// returns a result that describes the unmet availability requirements.
258+
/// returns a result that describes the unsatisfied constraint.
258259
/// Returns `std::nullopt` if the declaration is available.
259-
std::optional<UnmetAvailabilityRequirement> getUnmetDeclAvailabilityRequirement(
260+
std::optional<AvailabilityConstraint> getUnsatisfiedAvailabilityConstraint(
260261
const Decl *decl, const DeclContext *referenceDC, SourceLoc referenceLoc);
261262

262263
/// Diagnose uses of the runtime support of the given type, such as

lib/Sema/TypeCheckPattern.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ using namespace swift;
3838
/// be kept in sync with importEnumCaseAlias in the ClangImporter library.
3939
static EnumElementDecl *extractEnumElement(DeclContext *DC, SourceLoc UseLoc,
4040
const VarDecl *constant) {
41-
if (auto requirement =
42-
getUnmetDeclAvailabilityRequirement(constant, DC, UseLoc)) {
41+
if (auto constraint =
42+
getUnsatisfiedAvailabilityConstraint(constant, DC, UseLoc)) {
4343
// Only diagnose explicit unavailability.
44-
if (!requirement->isConditionallySatisfiable())
44+
if (!constraint->isConditionallySatisfiable())
4545
diagnoseDeclAvailability(constant, UseLoc, nullptr,
4646
ExportContext::forFunctionBody(DC, UseLoc));
4747
}

0 commit comments

Comments
 (0)