Skip to content

Commit 6eab842

Browse files
authoredMar 5, 2025
Merge pull request #79777 from tshortli/potential-unavailability-diagnostics
AST/Sema: Decouple potential unavailability diagnostics from platform version

26 files changed

+223
-211
lines changed
 

‎include/swift/AST/ASTBridging.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ enum ENUM_EXTENSIBILITY_ATTR(open) BridgedDiagID : uint32_t {
514514
};
515515

516516
class BridgedDiagnosticArgument {
517-
int64_t storage[3];
517+
int64_t storage[4];
518518

519519
public:
520520
BRIDGED_INLINE BridgedDiagnosticArgument(const swift::DiagnosticArgument &arg);

‎include/swift/AST/AvailabilityConstraint.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,10 @@ class AvailabilityConstraint {
132132
/// Returns the domain that the constraint applies to.
133133
AvailabilityDomain getDomain() const { return getAttr().getDomain(); }
134134

135-
/// Returns the platform that this constraint applies to, or
136-
/// `PlatformKind::none` if it is not platform specific.
137-
PlatformKind getPlatform() const;
138-
139135
/// Returns the required range for `IntroducedInNewerVersion` requirements, or
140136
/// `std::nullopt` otherwise.
141137
std::optional<AvailabilityRange>
142-
getRequiredNewerAvailabilityRange(const ASTContext &ctx) const;
138+
getPotentiallyUnavailableRange(const ASTContext &ctx) const;
143139

144140
/// Some availability constraints are active for type-checking but cannot
145141
/// be translated directly into an `if #available(...)` runtime query.

‎include/swift/AST/AvailabilityRange.h

+2
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ class AvailabilityRange {
208208
VersionRange Range;
209209

210210
public:
211+
explicit AvailabilityRange(llvm::VersionTuple LowerEndpoint)
212+
: Range(VersionRange::allGTE(LowerEndpoint)) {}
211213
explicit AvailabilityRange(VersionRange Range) : Range(Range) {}
212214

213215
/// Creates a context that imposes the constraints of the ASTContext's

‎include/swift/AST/DiagnosticEngine.h

+11
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ namespace swift {
146146
DescriptiveStmtKind,
147147
DeclAttribute,
148148
AvailabilityDomain,
149+
AvailabilityRange,
149150
VersionTuple,
150151
LayoutConstraint,
151152
ActorIsolation,
@@ -184,6 +185,7 @@ namespace swift {
184185
StmtKind DescriptiveStmtKindVal;
185186
const DeclAttribute *DeclAttributeVal;
186187
AvailabilityDomain AvailabilityDomainVal;
188+
AvailabilityRange AvailabilityRangeVal;
187189
llvm::VersionTuple VersionVal;
188190
LayoutConstraint LayoutConstraintVal;
189191
ActorIsolation ActorIsolationVal;
@@ -288,6 +290,10 @@ namespace swift {
288290
: Kind(DiagnosticArgumentKind::AvailabilityDomain),
289291
AvailabilityDomainVal(domain) {}
290292

293+
DiagnosticArgument(const AvailabilityRange &range)
294+
: Kind(DiagnosticArgumentKind::AvailabilityRange),
295+
AvailabilityRangeVal(range) {}
296+
291297
DiagnosticArgument(llvm::VersionTuple version)
292298
: Kind(DiagnosticArgumentKind::VersionTuple),
293299
VersionVal(version) { }
@@ -418,6 +424,11 @@ namespace swift {
418424
return AvailabilityDomainVal;
419425
}
420426

427+
const AvailabilityRange getAsAvailabilityRange() const {
428+
assert(Kind == DiagnosticArgumentKind::AvailabilityRange);
429+
return AvailabilityRangeVal;
430+
}
431+
421432
llvm::VersionTuple getAsVersionTuple() const {
422433
assert(Kind == DiagnosticArgumentKind::VersionTuple);
423434
return VersionVal;

‎include/swift/AST/DiagnosticsIDE.def

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ WARNING(ide_availability_softdeprecated, Deprecation,
3030
"%0 will be deprecated"
3131
" in %select{a future version|%select{a future version of %2|%2 %4}3}1"
3232
"%select{|: %5}5",
33-
(const ValueDecl *, bool, AvailabilityDomain, bool, llvm::VersionTuple,
33+
(const ValueDecl *, bool, AvailabilityDomain, bool, AvailabilityRange,
3434
StringRef))
3535

3636
WARNING(ide_availability_softdeprecated_rename, Deprecation,
3737
"%0 will be deprecated"
3838
" in %select{a future version|%select{a future version of %2|%2 %4}3}1"
3939
": renamed to '%5'",
40-
(const ValueDecl *, bool, AvailabilityDomain, bool, llvm::VersionTuple,
40+
(const ValueDecl *, bool, AvailabilityDomain, bool, AvailabilityRange,
4141
StringRef))
4242

4343
WARNING(ide_recursive_accessor_reference,none,

‎include/swift/AST/DiagnosticsIRGen.def

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ ERROR(attr_objc_implementation_resilient_property_deployment_target, none,
7575
"'@implementation' on %0 %1 does not support stored properties whose "
7676
"size can change due to library evolution; raise the minimum deployment "
7777
"target to %0 %2 or store this value in an object or 'any' type",
78-
(AvailabilityDomain, const llvm::VersionTuple, const llvm::VersionTuple))
78+
(AvailabilityDomain, const AvailabilityRange, const AvailabilityRange))
7979

8080
ERROR(unable_to_load_pass_plugin,none,
8181
"unable to load plugin '%0': '%1'", (StringRef, StringRef))

‎include/swift/AST/DiagnosticsSema.def

+30-30
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,7 @@ ERROR(attr_objc_implementation_no_conformance,none,
18411841
ERROR(attr_objc_implementation_raise_minimum_deployment_target,none,
18421842
"'@implementation' of an Objective-C class requires a minimum deployment "
18431843
"target of at least %0 %1",
1844-
(AvailabilityDomain, llvm::VersionTuple))
1844+
(AvailabilityDomain, AvailabilityRange))
18451845
ERROR(attr_implementation_requires_language,none,
18461846
"'@implementation' used without specifying the language being "
18471847
"implemented",
@@ -3996,7 +3996,7 @@ ERROR(attr_not_on_decl_with_invalid_access_level,none,
39963996
ERROR(attr_has_no_effect_decl_not_available_before,none,
39973997
"'%0' has no effect because %1 is not "
39983998
"available before %2 %3",
3999-
(DeclAttribute, const ValueDecl *, AvailabilityDomain, llvm::VersionTuple))
3999+
(DeclAttribute, const ValueDecl *, AvailabilityDomain, AvailabilityRange))
40004000

40014001
ERROR(attr_has_no_effect_on_unavailable_decl,none,
40024002
"'%0' has no effect because %1 is unavailable on %2",
@@ -6008,7 +6008,7 @@ ERROR(isolated_deinit_on_value_type,none,
60086008
())
60096009
ERROR(isolated_deinit_unavailable,none,
60106010
"isolated deinit is only available in %0 %1 or newer",
6011-
(AvailabilityDomain, llvm::VersionTuple))
6011+
(AvailabilityDomain, AvailabilityRange))
60126012

60136013
//------------------------------------------------------------------------------
60146014
// MARK: String Processing
@@ -6023,7 +6023,7 @@ ERROR(regex_capture_types_failed_to_decode,none,
60236023

60246024
ERROR(regex_feature_unavailable, none,
60256025
"%0 is only available in %1 %2 or newer",
6026-
(StringRef, AvailabilityDomain, llvm::VersionTuple))
6026+
(StringRef, AvailabilityDomain, AvailabilityRange))
60276027

60286028
ERROR(must_import_regex_builder_module,none,
60296029
"regex builder requires the 'RegexBuilder' module be imported'", ())
@@ -6373,7 +6373,7 @@ ERROR(objc_in_generic_extension,none,
63736373
"cannot contain '@objc' members", (bool))
63746374
ERROR(objc_in_resilient_extension,none,
63756375
"'@objc' %0 in extension of subclass of %1 requires %2 %3",
6376-
(DescriptiveDeclKind, Identifier, AvailabilityDomain, llvm::VersionTuple))
6376+
(DescriptiveDeclKind, Identifier, AvailabilityDomain, AvailabilityRange))
63776377
ERROR(objc_operator, none,
63786378
"operator methods cannot be declared @objc", ())
63796379
ERROR(objc_operator_proto, none,
@@ -6384,7 +6384,7 @@ ERROR(objc_for_generic_class,none,
63846384
"because they are not directly visible from Objective-C", ())
63856385
ERROR(objc_for_resilient_class,none,
63866386
"explicit '@objc' on subclass of %0 requires %1 %2",
6387-
(Identifier, AvailabilityDomain, llvm::VersionTuple))
6387+
(Identifier, AvailabilityDomain, AvailabilityRange))
63886388
ERROR(objc_getter_for_nonobjc_property,none,
63896389
"'@objc' getter for non-'@objc' property", ())
63906390
ERROR(objc_getter_for_nonobjc_subscript,none,
@@ -6784,25 +6784,25 @@ NOTE(availability_marked_unavailable, none,
67846784

67856785
NOTE(availability_introduced_in_version, none,
67866786
"%0 was introduced in %1 %2",
6787-
(const ValueDecl *, AvailabilityDomain, llvm::VersionTuple))
6787+
(const ValueDecl *, AvailabilityDomain, AvailabilityRange))
67886788

67896789
NOTE(availability_obsoleted, none,
67906790
"%0 was obsoleted in %1 %2",
6791-
(const ValueDecl *, AvailabilityDomain, llvm::VersionTuple))
6791+
(const ValueDecl *, AvailabilityDomain, AvailabilityRange))
67926792

67936793
GROUPED_WARNING(availability_deprecated, DeprecatedDeclaration, Deprecation,
67946794
"%0 %select{is|%select{is|was}3}1 "
67956795
"deprecated%select{| in %2%select{| %4}3}1%select{|: %5}5",
67966796
(const ValueDecl *, bool, AvailabilityDomain, bool,
6797-
llvm::VersionTuple, StringRef))
6797+
AvailabilityRange, StringRef))
67986798

67996799
GROUPED_WARNING(
68006800
availability_deprecated_rename, DeprecatedDeclaration, Deprecation,
68016801
"%0 %select{is|%select{is|was}3}1 "
68026802
"deprecated%select{| in %2%select{| %4}3}1: "
68036803
"%select{renamed to|replaced by}5%" REPLACEMENT_DECL_KIND_SELECT "6 "
68046804
"'%7'",
6805-
(const ValueDecl *, bool, AvailabilityDomain, bool, llvm::VersionTuple,
6805+
(const ValueDecl *, bool, AvailabilityDomain, bool, AvailabilityRange,
68066806
bool, unsigned, StringRef))
68076807
#undef REPLACEMENT_DECL_KIND_SELECT
68086808

@@ -6815,63 +6815,63 @@ ERROR(availability_decl_more_than_enclosing, none,
68156815

68166816
NOTE(availability_implicit_decl_here, none,
68176817
"%0 implicitly declared here with availability of %1 %2 or newer",
6818-
(DescriptiveDeclKind, AvailabilityDomain, llvm::VersionTuple))
6818+
(DescriptiveDeclKind, AvailabilityDomain, AvailabilityRange))
68196819

68206820
NOTE(availability_decl_more_than_enclosing_here, none,
68216821
"enclosing scope requires availability of %0 %1 or newer",
6822-
(AvailabilityDomain, llvm::VersionTuple))
6822+
(AvailabilityDomain, AvailabilityRange))
68236823

68246824
ERROR(availability_decl_only_version_newer, none,
68256825
"%0 is only available in %1 %2 or newer",
6826-
(const ValueDecl *, AvailabilityDomain, llvm::VersionTuple))
6826+
(const ValueDecl *, AvailabilityDomain, AvailabilityRange))
68276827

68286828
ERROR(availability_decl_only_version_newer_for_clients, none,
68296829
"%0 is only available in %1 %2 or newer; clients of %3 may have a lower"
68306830
" deployment target",
6831-
(const ValueDecl *, AvailabilityDomain, llvm::VersionTuple, ModuleDecl *))
6831+
(const ValueDecl *, AvailabilityDomain, AvailabilityRange, ModuleDecl *))
68326832

68336833
WARNING(availability_decl_only_version_newer_for_clients_warn, none,
68346834
"%0 is only available in %1 %2 or newer; clients of %3 may have a lower"
68356835
" deployment target",
6836-
(const ValueDecl *, AvailabilityDomain, llvm::VersionTuple,
6836+
(const ValueDecl *, AvailabilityDomain, AvailabilityRange,
68376837
ModuleDecl *))
68386838

68396839
ERROR(availability_opaque_types_only_version_newer, none,
68406840
"'some' return types are only available in %0 %1 or newer",
6841-
(AvailabilityDomain, llvm::VersionTuple))
6841+
(AvailabilityDomain, AvailabilityRange))
68426842

68436843
ERROR(availability_concurrency_only_version_newer, none,
68446844
"concurrency is only available in %0 %1 or newer",
6845-
(AvailabilityDomain, llvm::VersionTuple))
6845+
(AvailabilityDomain, AvailabilityRange))
68466846

68476847
ERROR(availability_parameterized_protocol_only_version_newer, none,
68486848
"runtime support for parameterized protocol types is only available in "
68496849
"%0 %1 or newer",
6850-
(AvailabilityDomain, llvm::VersionTuple))
6850+
(AvailabilityDomain, AvailabilityRange))
68516851

68526852
ERROR(availability_isolated_any_only_version_newer, none,
68536853
"runtime support for @isolated(any) function types is only available in "
68546854
"%0 %1 or newer",
6855-
(AvailabilityDomain, llvm::VersionTuple))
6855+
(AvailabilityDomain, AvailabilityRange))
68566856

68576857
ERROR(availability_copyable_generics_casting_only_version_newer, none,
68586858
"runtime support for casting types with noncopyable generic arguments "
68596859
"is only available in %0 %1 or newer",
6860-
(AvailabilityDomain, llvm::VersionTuple))
6860+
(AvailabilityDomain, AvailabilityRange))
68616861

68626862
ERROR(availability_escapable_generics_casting_only_version_newer, none,
68636863
"runtime support for casting types with nonescapable generic arguments "
68646864
"is only available in %0 %1 or newer",
6865-
(AvailabilityDomain, llvm::VersionTuple))
6865+
(AvailabilityDomain, AvailabilityRange))
68666866

68676867
ERROR(availability_typed_throws_only_version_newer, none,
68686868
"runtime support for typed throws function types is only available in "
68696869
"%0 %1 or newer",
6870-
(AvailabilityDomain, llvm::VersionTuple))
6870+
(AvailabilityDomain, AvailabilityRange))
68716871

68726872
ERROR(availability_variadic_type_only_version_newer, none,
68736873
"parameter packs in generic types are only available in %0 %1 or newer",
6874-
(AvailabilityDomain, llvm::VersionTuple))
6874+
(AvailabilityDomain, AvailabilityRange))
68756875

68766876
NOTE(availability_guard_with_version_check, none,
68776877
"add 'if #available' version check", ())
@@ -6884,7 +6884,7 @@ FIXIT(insert_available_attr,
68846884

68856885
ERROR(availability_inout_accessor_only_version_newer, none,
68866886
"cannot pass as inout because %0 is only available in %1 %2 or newer",
6887-
(const ValueDecl *, AvailabilityDomain, llvm::VersionTuple))
6887+
(const ValueDecl *, AvailabilityDomain, AvailabilityRange))
68886888

68896889
ERROR(availability_query_required_for_platform, none,
68906890
"condition required for target platform '%0'", (StringRef))
@@ -6931,7 +6931,7 @@ WARNING(availability_enum_element_no_potential_warn,
69316931
ERROR(availability_protocol_requires_version,
69326932
none, "protocol %0 requires %1 to be available in %2 %3 and newer",
69336933
(const ProtocolDecl *, const ValueDecl *, AvailabilityDomain,
6934-
llvm::VersionTuple))
6934+
AvailabilityRange))
69356935

69366936
NOTE(availability_protocol_requirement_here, none,
69376937
"protocol requirement here", ())
@@ -6972,22 +6972,22 @@ NOTE(conformance_availability_marked_unavailable, none,
69726972

69736973
NOTE(conformance_availability_introduced_in_version, none,
69746974
"conformance of %0 to %1 was introduced in %2 %3",
6975-
(Type, Type, AvailabilityDomain, llvm::VersionTuple))
6975+
(Type, Type, AvailabilityDomain, AvailabilityRange))
69766976

69776977
NOTE(conformance_availability_obsoleted, none,
69786978
"conformance of %0 to %1 was obsoleted in %2 %3",
6979-
(Type, Type, AvailabilityDomain, llvm::VersionTuple))
6979+
(Type, Type, AvailabilityDomain, AvailabilityRange))
69806980

69816981
GROUPED_WARNING(conformance_availability_deprecated,
69826982
DeprecatedDeclaration, Deprecation,
69836983
"conformance of %0 to %1 %select{is|%select{is|was}4}2 "
69846984
"deprecated%select{| in %3%select{| %5}4}2%select{|: %6}6",
6985-
(Type, Type, bool, AvailabilityDomain, bool, llvm::VersionTuple,
6985+
(Type, Type, bool, AvailabilityDomain, bool, AvailabilityRange,
69866986
StringRef))
69876987

69886988
ERROR(conformance_availability_only_version_newer, none,
69896989
"conformance of %0 to %1 is only available in %2 %3 or newer",
6990-
(Type, Type, AvailabilityDomain, llvm::VersionTuple))
6990+
(Type, Type, AvailabilityDomain, AvailabilityRange))
69916991

69926992
//------------------------------------------------------------------------------
69936993
// MARK: if #available(...)
@@ -8257,7 +8257,7 @@ ERROR(value_generics_missing_feature,none,
82578257
"value generics require '-enable-experimental-feature ValueGenerics'", ())
82588258
ERROR(availability_value_generic_type_only_version_newer, none,
82598259
"values in generic types are only available in %0 %1 or newer",
8260-
(AvailabilityDomain, llvm::VersionTuple))
8260+
(AvailabilityDomain, AvailabilityRange))
82618261
ERROR(invalid_value_for_type_same_type,none,
82628262
"cannot constrain type parameter %0 to be integer %1", (Type, Type))
82638263

‎lib/AST/Availability.cpp

+7-10
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,15 @@ void VersionRange::Profile(llvm::FoldingSetNodeID &id) const {
5858

5959
AvailabilityRange
6060
AvailabilityRange::forDeploymentTarget(const ASTContext &Ctx) {
61-
return AvailabilityRange(
62-
VersionRange::allGTE(Ctx.LangOpts.getMinPlatformVersion()));
61+
return AvailabilityRange(Ctx.LangOpts.getMinPlatformVersion());
6362
}
6463

6564
AvailabilityRange AvailabilityRange::forInliningTarget(const ASTContext &Ctx) {
66-
return AvailabilityRange(
67-
VersionRange::allGTE(Ctx.LangOpts.MinimumInliningTargetVersion));
65+
return AvailabilityRange(Ctx.LangOpts.MinimumInliningTargetVersion);
6866
}
6967

7068
AvailabilityRange AvailabilityRange::forRuntimeTarget(const ASTContext &Ctx) {
71-
return AvailabilityRange(VersionRange::allGTE(Ctx.LangOpts.RuntimeVersion));
69+
return AvailabilityRange(Ctx.LangOpts.RuntimeVersion);
7270
}
7371

7472
namespace {
@@ -853,7 +851,7 @@ SemanticAvailableAttr::getIntroducedRange(const ASTContext &Ctx) const {
853851
*this, Ctx, unusedDomain, remappedVersion))
854852
introducedVersion = remappedVersion;
855853

856-
return AvailabilityRange{VersionRange::allGTE(introducedVersion)};
854+
return AvailabilityRange{introducedVersion};
857855
}
858856

859857
std::optional<llvm::VersionTuple> SemanticAvailableAttr::getDeprecated() const {
@@ -877,7 +875,7 @@ SemanticAvailableAttr::getDeprecatedRange(const ASTContext &Ctx) const {
877875
*this, Ctx, unusedDomain, remappedVersion))
878876
deprecatedVersion = remappedVersion;
879877

880-
return AvailabilityRange{VersionRange::allGTE(deprecatedVersion)};
878+
return AvailabilityRange{deprecatedVersion};
881879
}
882880

883881
std::optional<llvm::VersionTuple> SemanticAvailableAttr::getObsoleted() const {
@@ -901,7 +899,7 @@ SemanticAvailableAttr::getObsoletedRange(const ASTContext &Ctx) const {
901899
*this, Ctx, unusedDomain, remappedVersion))
902900
obsoletedVersion = remappedVersion;
903901

904-
return AvailabilityRange{VersionRange::allGTE(obsoletedVersion)};
902+
return AvailabilityRange{obsoletedVersion};
905903
}
906904

907905
namespace {
@@ -931,8 +929,7 @@ AvailabilityRange ASTContext::getSwiftFutureAvailability() const {
931929
auto target = LangOpts.Target;
932930

933931
auto getFutureAvailabilityRange = []() -> AvailabilityRange {
934-
return AvailabilityRange(
935-
VersionRange::allGTE(llvm::VersionTuple(99, 99, 0)));
932+
return AvailabilityRange(llvm::VersionTuple(99, 99, 0));
936933
};
937934

938935
if (target.isMacOSX()) {

‎lib/AST/AvailabilityConstraint.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@
1818

1919
using namespace swift;
2020

21-
PlatformKind AvailabilityConstraint::getPlatform() const {
22-
return getAttr().getPlatform();
23-
}
24-
2521
std::optional<AvailabilityRange>
26-
AvailabilityConstraint::getRequiredNewerAvailabilityRange(
22+
AvailabilityConstraint::getPotentiallyUnavailableRange(
2723
const ASTContext &ctx) const {
2824
switch (getReason()) {
2925
case Reason::UnconditionallyUnavailable:

‎lib/AST/AvailabilityDomain.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ getDeploymentVersion(const AvailabilityDomain &domain, const ASTContext &ctx) {
126126
std::optional<AvailabilityRange>
127127
AvailabilityDomain::getDeploymentRange(const ASTContext &ctx) const {
128128
if (auto version = getDeploymentVersion(*this, ctx))
129-
return AvailabilityRange{VersionRange::allGTE(*version)};
129+
return AvailabilityRange{*version};
130130
return std::nullopt;
131131
}
132132

0 commit comments

Comments
 (0)
Please sign in to comment.