@@ -1119,7 +1119,7 @@ class TypeRefinementContextBuilder : private ASTWalker {
1119
1119
}
1120
1120
1121
1121
AvailabilityContext NewConstraint = contextForSpec (Spec, false );
1122
- Query->setAvailableRange (contextForSpec (Spec, true ).getVersionRange ());
1122
+ Query->setAvailableRange (contextForSpec (Spec, true ).getRawVersionRange ());
1123
1123
1124
1124
// When compiling zippered for macCatalyst, we need to collect both
1125
1125
// a macOS version (the target version) and an iOS/macCatalyst version
@@ -1130,7 +1130,7 @@ class TypeRefinementContextBuilder : private ASTWalker {
1130
1130
AvailabilitySpec *VariantSpec =
1131
1131
bestActiveSpecForQuery (Query, /* ForTargetVariant*/ true );
1132
1132
VersionRange VariantRange =
1133
- contextForSpec (VariantSpec, true ).getVersionRange ();
1133
+ contextForSpec (VariantSpec, true ).getRawVersionRange ();
1134
1134
Query->setVariantAvailableRange (VariantRange);
1135
1135
}
1136
1136
@@ -1857,9 +1857,10 @@ static void findAvailabilityFixItNodes(
1857
1857
1858
1858
// / Emit a diagnostic note and Fix-It to add an @available attribute
1859
1859
// / on the given declaration for the given version range.
1860
- static void fixAvailabilityForDecl (SourceRange ReferenceRange, const Decl *D,
1861
- const VersionRange &RequiredRange,
1862
- ASTContext &Context) {
1860
+ static void
1861
+ fixAvailabilityForDecl (SourceRange ReferenceRange, const Decl *D,
1862
+ const AvailabilityContext &RequiredAvailability,
1863
+ ASTContext &Context) {
1863
1864
assert (D);
1864
1865
1865
1866
// Don't suggest adding an @available() to a declaration where we would
@@ -1897,8 +1898,7 @@ static void fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
1897
1898
D->diagnose (diag::availability_add_attribute, KindForDiagnostic)
1898
1899
.fixItInsert (InsertLoc, diag::insert_available_attr,
1899
1900
platformString (Target),
1900
- RequiredRange.getLowerEndpoint ().getAsString (),
1901
- OriginalIndent);
1901
+ RequiredAvailability.getVersionString (), OriginalIndent);
1902
1902
}
1903
1903
1904
1904
// / In the special case of being in an existing, nontrivial type refinement
@@ -1907,29 +1907,26 @@ static void fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
1907
1907
// / version), emit a diagnostic and fixit that narrows the existing TRC
1908
1908
// / condition to the required range.
1909
1909
static bool fixAvailabilityByNarrowingNearbyVersionCheck (
1910
- SourceRange ReferenceRange,
1911
- const DeclContext *ReferenceDC,
1912
- const VersionRange &RequiredRange,
1913
- ASTContext &Context,
1910
+ SourceRange ReferenceRange, const DeclContext *ReferenceDC,
1911
+ const AvailabilityContext &RequiredAvailability, ASTContext &Context,
1914
1912
InFlightDiagnostic &Err) {
1915
1913
const TypeRefinementContext *TRC = nullptr ;
1916
1914
(void )TypeChecker::overApproximateAvailabilityAtLocation (ReferenceRange.Start ,
1917
1915
ReferenceDC, &TRC);
1918
1916
if (!TRC)
1919
1917
return false ;
1920
- VersionRange RunningRange =
1921
- TRC->getExplicitAvailabilityInfo (). getVersionRange ();
1922
- if (RunningRange. hasLowerEndpoint () &&
1923
- RequiredRange. hasLowerEndpoint () &&
1918
+
1919
+ AvailabilityContext AvailabilityAtLoc = TRC->getExplicitAvailabilityInfo ();
1920
+ if (!AvailabilityAtLoc. isAlwaysAvailable () &&
1921
+ !RequiredAvailability. isAlwaysAvailable () &&
1924
1922
TRC->getReason () != TypeRefinementContext::Reason::Root &&
1925
- AvailabilityContext (RequiredRange).isContainedIn (
1926
- AvailabilityContext (RunningRange))) {
1923
+ RequiredAvailability.isContainedIn (AvailabilityAtLoc)) {
1927
1924
1928
1925
// Only fix situations that are "nearby" versions, meaning
1929
1926
// disagreement on a minor-or-less version (subminor-or-less version for
1930
1927
// macOS 10.x.y).
1931
- auto RunningVers = RunningRange. getLowerEndpoint ();
1932
- auto RequiredVers = RequiredRange. getLowerEndpoint ();
1928
+ auto RunningVers = AvailabilityAtLoc. getRawMinimumVersion ();
1929
+ auto RequiredVers = RequiredAvailability. getRawMinimumVersion ();
1933
1930
auto Platform = targetPlatform (Context.LangOpts );
1934
1931
if (RunningVers.getMajor () != RequiredVers.getMajor ())
1935
1932
return false ;
@@ -1947,7 +1944,7 @@ static bool fixAvailabilityByNarrowingNearbyVersionCheck(
1947
1944
if (!FixRange.isValid ())
1948
1945
return false ;
1949
1946
// Have found a nontrivial type refinement context-introducer to narrow.
1950
- Err.fixItReplace (FixRange, RequiredVers. getAsString ());
1947
+ Err.fixItReplace (FixRange, RequiredAvailability. getVersionString ());
1951
1948
return true ;
1952
1949
}
1953
1950
return false ;
@@ -1956,7 +1953,7 @@ static bool fixAvailabilityByNarrowingNearbyVersionCheck(
1956
1953
// / Emit a diagnostic note and Fix-It to add an if #available(...) { } guard
1957
1954
// / that checks for the given version range around the given node.
1958
1955
static void fixAvailabilityByAddingVersionCheck (
1959
- ASTNode NodeToWrap, const VersionRange &RequiredRange ,
1956
+ ASTNode NodeToWrap, const AvailabilityContext &RequiredAvailability ,
1960
1957
SourceRange ReferenceRange, ASTContext &Context) {
1961
1958
// If this is an implicit variable that wraps an expression,
1962
1959
// let's point to it's initializer. For example, result builder
@@ -2010,9 +2007,8 @@ static void fixAvailabilityByAddingVersionCheck(
2010
2007
basePlatformForExtensionPlatform (Target))
2011
2008
Target = *TargetRemovingAppExtension;
2012
2009
2013
- Out << " if #available(" << platformString (Target)
2014
- << " " << RequiredRange.getLowerEndpoint ().getAsString ()
2015
- << " , *) {\n " ;
2010
+ Out << " if #available(" << platformString (Target) << " "
2011
+ << RequiredAvailability.getVersionString () << " , *) {\n " ;
2016
2012
2017
2013
Out << OriginalIndent << ExtraIndent << GuardedText << " \n " ;
2018
2014
@@ -2032,7 +2028,7 @@ static void fixAvailabilityByAddingVersionCheck(
2032
2028
// / requiting the given OS version range.
2033
2029
static void fixAvailability (SourceRange ReferenceRange,
2034
2030
const DeclContext *ReferenceDC,
2035
- const VersionRange &RequiredRange ,
2031
+ const AvailabilityContext &RequiredAvailability ,
2036
2032
ASTContext &Context) {
2037
2033
if (ReferenceRange.isInvalid ())
2038
2034
return ;
@@ -2048,18 +2044,19 @@ static void fixAvailability(SourceRange ReferenceRange,
2048
2044
// Suggest wrapping in if #available(...) { ... } if possible.
2049
2045
if (NodeToWrapInVersionCheck.has_value ()) {
2050
2046
fixAvailabilityByAddingVersionCheck (NodeToWrapInVersionCheck.value (),
2051
- RequiredRange, ReferenceRange, Context);
2047
+ RequiredAvailability, ReferenceRange,
2048
+ Context);
2052
2049
}
2053
2050
2054
2051
// Suggest adding availability attributes.
2055
2052
if (FoundMemberDecl) {
2056
- fixAvailabilityForDecl (ReferenceRange, FoundMemberDecl, RequiredRange,
2057
- Context);
2053
+ fixAvailabilityForDecl (ReferenceRange, FoundMemberDecl,
2054
+ RequiredAvailability, Context);
2058
2055
}
2059
2056
2060
2057
if (FoundTypeLevelDecl) {
2061
- fixAvailabilityForDecl (ReferenceRange, FoundTypeLevelDecl, RequiredRange,
2062
- Context);
2058
+ fixAvailabilityForDecl (ReferenceRange, FoundTypeLevelDecl,
2059
+ RequiredAvailability, Context);
2063
2060
}
2064
2061
}
2065
2062
@@ -2068,20 +2065,18 @@ void TypeChecker::diagnosePotentialUnavailability(
2068
2065
const DeclContext *ReferenceDC, const AvailabilityContext &Availability) {
2069
2066
ASTContext &Context = ReferenceDC->getASTContext ();
2070
2067
2071
- auto RequiredRange = Availability.getVersionRange ();
2072
2068
{
2073
- auto Err =
2074
- Context.Diags .diagnose (
2075
- ReferenceRange.Start , Diag,
2076
- prettyPlatformString (targetPlatform (Context.LangOpts )),
2077
- RequiredRange.getLowerEndpoint ());
2069
+ auto Err = Context.Diags .diagnose (
2070
+ ReferenceRange.Start , Diag,
2071
+ prettyPlatformString (targetPlatform (Context.LangOpts )),
2072
+ Availability.getRawMinimumVersion ());
2078
2073
2079
2074
// Direct a fixit to the error if an existing guard is nearly-correct
2080
2075
if (fixAvailabilityByNarrowingNearbyVersionCheck (
2081
- ReferenceRange, ReferenceDC, RequiredRange , Context, Err))
2076
+ ReferenceRange, ReferenceDC, Availability , Context, Err))
2082
2077
return ;
2083
2078
}
2084
- fixAvailability (ReferenceRange, ReferenceDC, RequiredRange , Context);
2079
+ fixAvailability (ReferenceRange, ReferenceDC, Availability , Context);
2085
2080
}
2086
2081
2087
2082
bool TypeChecker::checkAvailability (SourceRange ReferenceRange,
@@ -2128,7 +2123,6 @@ static Diagnostic getPotentialUnavailabilityDiagnostic(
2128
2123
bool &IsError) {
2129
2124
ASTContext &Context = ReferenceDC->getASTContext ();
2130
2125
auto Platform = prettyPlatformString (targetPlatform (Context.LangOpts ));
2131
- auto Version = Availability.getVersionRange ().getLowerEndpoint ();
2132
2126
2133
2127
if (requiresDeploymentTargetOrEarlier (Availability, Context)) {
2134
2128
// The required OS version is at or before the deployment target so this
@@ -2139,12 +2133,13 @@ static Diagnostic getPotentialUnavailabilityDiagnostic(
2139
2133
return Diagnostic (
2140
2134
IsError ? diag::availability_decl_only_version_newer_for_clients
2141
2135
: diag::availability_decl_only_version_newer_for_clients_warn,
2142
- D, Platform, Version, ReferenceDC->getParentModule ());
2136
+ D, Platform, Availability.getRawMinimumVersion (),
2137
+ ReferenceDC->getParentModule ());
2143
2138
}
2144
2139
2145
2140
IsError = true ;
2146
2141
return Diagnostic (diag::availability_decl_only_version_newer, D, Platform,
2147
- Version );
2142
+ Availability. getRawMinimumVersion () );
2148
2143
}
2149
2144
2150
2145
bool TypeChecker::diagnosePotentialUnavailability (
@@ -2153,7 +2148,6 @@ bool TypeChecker::diagnosePotentialUnavailability(
2153
2148
bool WarnBeforeDeploymentTarget = false ) {
2154
2149
ASTContext &Context = ReferenceDC->getASTContext ();
2155
2150
2156
- auto RequiredRange = Availability.getVersionRange ();
2157
2151
bool IsError;
2158
2152
{
2159
2153
auto Diag = Context.Diags .diagnose (
@@ -2163,11 +2157,11 @@ bool TypeChecker::diagnosePotentialUnavailability(
2163
2157
2164
2158
// Direct a fixit to the error if an existing guard is nearly-correct
2165
2159
if (fixAvailabilityByNarrowingNearbyVersionCheck (
2166
- ReferenceRange, ReferenceDC, RequiredRange , Context, Diag))
2160
+ ReferenceRange, ReferenceDC, Availability , Context, Diag))
2167
2161
return IsError;
2168
2162
}
2169
2163
2170
- fixAvailability (ReferenceRange, ReferenceDC, RequiredRange , Context);
2164
+ fixAvailability (ReferenceRange, ReferenceDC, Availability , Context);
2171
2165
return IsError;
2172
2166
}
2173
2167
@@ -2182,23 +2176,19 @@ void TypeChecker::diagnosePotentialAccessorUnavailability(
2182
2176
auto &diag = ForInout ? diag::availability_inout_accessor_only_version_newer
2183
2177
: diag::availability_decl_only_version_newer;
2184
2178
2185
- auto RequiredRange = Availability.getVersionRange ();
2186
2179
{
2187
- auto Err =
2188
- Context.Diags .diagnose (
2189
- ReferenceRange.Start , diag, Accessor,
2190
- prettyPlatformString (targetPlatform (Context.LangOpts )),
2191
- RequiredRange.getLowerEndpoint ());
2192
-
2180
+ auto Err = Context.Diags .diagnose (
2181
+ ReferenceRange.Start , diag, Accessor,
2182
+ prettyPlatformString (targetPlatform (Context.LangOpts )),
2183
+ Availability.getRawMinimumVersion ());
2193
2184
2194
2185
// Direct a fixit to the error if an existing guard is nearly-correct
2195
- if (fixAvailabilityByNarrowingNearbyVersionCheck (ReferenceRange,
2196
- ReferenceDC,
2197
- RequiredRange, Context, Err))
2186
+ if (fixAvailabilityByNarrowingNearbyVersionCheck (
2187
+ ReferenceRange, ReferenceDC, Availability, Context, Err))
2198
2188
return ;
2199
2189
}
2200
2190
2201
- fixAvailability (ReferenceRange, ReferenceDC, RequiredRange , Context);
2191
+ fixAvailability (ReferenceRange, ReferenceDC, Availability , Context);
2202
2192
}
2203
2193
2204
2194
static DiagnosticBehavior
@@ -2226,25 +2216,24 @@ void TypeChecker::diagnosePotentialUnavailability(
2226
2216
const AvailabilityContext &availability) {
2227
2217
ASTContext &ctx = dc->getASTContext ();
2228
2218
2229
- auto requiredRange = availability.getVersionRange ();
2230
2219
{
2231
2220
auto type = rootConf->getType ();
2232
2221
auto proto = rootConf->getProtocol ()->getDeclaredInterfaceType ();
2233
2222
auto err = ctx.Diags .diagnose (
2234
2223
loc, diag::conformance_availability_only_version_newer, type, proto,
2235
2224
prettyPlatformString (targetPlatform (ctx.LangOpts )),
2236
- requiredRange. getLowerEndpoint ());
2225
+ availability. getRawMinimumVersion ());
2237
2226
2238
2227
err.warnUntilSwiftVersion (6 );
2239
2228
err.limitBehavior (behaviorLimitForExplicitUnavailability (rootConf, dc));
2240
2229
2241
2230
// Direct a fixit to the error if an existing guard is nearly-correct
2242
- if (fixAvailabilityByNarrowingNearbyVersionCheck (loc, dc,
2243
- requiredRange, ctx, err))
2231
+ if (fixAvailabilityByNarrowingNearbyVersionCheck (loc, dc, availability, ctx,
2232
+ err))
2244
2233
return ;
2245
2234
}
2246
2235
2247
- fixAvailability (loc, dc, requiredRange , ctx);
2236
+ fixAvailability (loc, dc, availability , ctx);
2248
2237
}
2249
2238
2250
2239
const AvailableAttr *TypeChecker::getDeprecated (const Decl *D) {
@@ -4635,7 +4624,7 @@ static bool declNeedsExplicitAvailability(const Decl *decl) {
4635
4624
4636
4625
// Warn on decls without an introduction version.
4637
4626
auto safeRangeUnderApprox = AvailabilityInference::availableRange (decl, ctx);
4638
- return ! safeRangeUnderApprox.getVersionRange (). hasLowerEndpoint ();
4627
+ return safeRangeUnderApprox.isAlwaysAvailable ();
4639
4628
}
4640
4629
4641
4630
void swift::checkExplicitAvailability (Decl *decl) {
0 commit comments