22
22
#include " TypeCheckUnsafe.h"
23
23
#include " TypeChecker.h"
24
24
#include " swift/AST/ASTVisitor.h"
25
- #include " swift/AST/AvailabilityInference .h"
25
+ #include " swift/AST/AvailabilityConstraint .h"
26
26
#include " swift/AST/AvailabilityRange.h"
27
27
#include " swift/AST/Decl.h"
28
28
#include " swift/AST/GenericEnvironment.h"
@@ -1810,159 +1810,97 @@ OverrideRequiresKeyword swift::overrideRequiresKeyword(ValueDecl *overridden) {
1810
1810
return OverrideRequiresKeyword::Always;
1811
1811
}
1812
1812
1813
- // / Returns true if the availability of the overriding declaration
1814
- // / makes it a safe override, given the availability of the base declaration.
1815
- static bool isAvailabilitySafeForOverride (ValueDecl *override ,
1816
- ValueDecl *base) {
1817
- // API availability ranges are contravariant: make sure the version range
1818
- // of an overridden declaration is fully contained in the range of the
1819
- // overriding declaration.
1820
- AvailabilityRange overrideInfo =
1821
- AvailabilityInference::availableRange (override );
1822
- AvailabilityRange baseInfo = AvailabilityInference::availableRange (base);
1823
-
1824
- if (baseInfo.isContainedIn (overrideInfo))
1825
- return true ;
1813
+ enum class OverrideAvailability {
1814
+ // / The unavailability of the base decl and override decl are compatible.
1815
+ Compatible,
1816
+ // / The base decl is unavailable but the override decl is not.
1817
+ BaseUnavailable,
1818
+ // / The override decl is unavailable but the base decl is not.
1819
+ OverrideUnavailable,
1820
+ // / The override decl is less available than the base decl.
1821
+ OverrideLessAvailable,
1822
+ // / Do not diagnose the unavailability of these decls.
1823
+ Ignored,
1824
+ };
1826
1825
1827
- // Allow overrides that are not as available as the base decl as long as the
1828
- // override is as available as its context.
1829
- auto availabilityContext = AvailabilityContext::forDeclSignature (
1830
- override ->getDeclContext ()->getSelfNominalTypeDecl ());
1826
+ static std::pair<OverrideAvailability, std::optional<AvailabilityConstraint>>
1827
+ getOverrideAvailability (ValueDecl *override , ValueDecl *base) {
1828
+ auto &ctx = override ->getASTContext ();
1831
1829
1832
- return availabilityContext.getPlatformRange ().isContainedIn (overrideInfo);
1833
- }
1830
+ // Availability is contravariant so make sure the availability of of an
1831
+ // overridden declaration is fully contained in the availability of the
1832
+ // overriding declaration.
1833
+ auto baseAvailability = AvailabilityContext::forDeclSignature (base);
1834
1834
1835
- // / Returns true if a diagnostic about an accessor being less available
1836
- // / than the accessor it overrides would be redundant because we will
1837
- // / already emit another diagnostic.
1838
- static bool
1839
- isRedundantAccessorOverrideAvailabilityDiagnostic (ValueDecl *override ,
1840
- ValueDecl *base) {
1835
+ // The override is allowed to be less available than the base decl as long as
1836
+ // it is as available as its containing nominal decl.
1837
+ auto nominalAvailability = AvailabilityContext::forDeclSignature (
1838
+ override ->getDeclContext ()->getSelfNominalTypeDecl ());
1839
+ baseAvailability.constrainWithContext (nominalAvailability, ctx);
1841
1840
1842
- auto *overrideFn = dyn_cast<AccessorDecl>(override );
1843
- auto *baseFn = dyn_cast<AccessorDecl>(base);
1844
- if (!overrideFn || !baseFn)
1845
- return false ;
1841
+ // In order to maintain source compatibility, universally unavailable decls
1842
+ // are allowed to override universally unavailable bases.
1843
+ AvailabilityConstraintFlags flags;
1844
+ flags |= AvailabilityConstraintFlag::
1845
+ AllowUniversallyUnavailableInCompatibleContexts;
1846
1846
1847
- AbstractStorageDecl *overrideASD = overrideFn->getStorage ();
1848
- AbstractStorageDecl *baseASD = baseFn->getStorage ();
1849
- if (overrideASD->getOverriddenDecl () != baseASD)
1850
- return false ;
1847
+ if (auto constraint =
1848
+ getAvailabilityConstraintsForDecl (override , baseAvailability, flags)
1849
+ .getPrimaryConstraint ()) {
1850
+ if (constraint->isUnavailable ())
1851
+ return {OverrideAvailability::OverrideUnavailable, constraint};
1851
1852
1852
- // If we have already emitted a diagnostic about an unsafe override
1853
- // for the property, don't complain about the accessor.
1854
- if (!isAvailabilitySafeForOverride (overrideASD, baseASD)) {
1855
- return true ;
1853
+ return {OverrideAvailability::OverrideLessAvailable, constraint};
1856
1854
}
1857
1855
1858
- // Returns true if we will already diagnose a bad override
1859
- // on the property's accessor of the given kind.
1860
- auto accessorOverrideAlreadyDiagnosed = [&](AccessorKind kind) {
1861
- FuncDecl *overrideAccessor = overrideASD->getOpaqueAccessor (kind);
1862
- FuncDecl *baseAccessor = baseASD->getOpaqueAccessor (kind);
1863
- if (overrideAccessor && baseAccessor &&
1864
- !isAvailabilitySafeForOverride (overrideAccessor, baseAccessor)) {
1865
- return true ;
1866
- }
1867
- return false ;
1868
- };
1869
-
1870
- // If we have already emitted a diagnostic about an unsafe override
1871
- // for a getter or a setter, no need to complain about the read or
1872
- // modify coroutines, which are synthesized to be as available as either
1873
- // the getter and the setter.
1874
- switch (overrideFn->getAccessorKind ()) {
1875
- case AccessorKind::Get:
1876
- case AccessorKind::DistributedGet:
1877
- case AccessorKind::Set:
1878
- break ;
1879
-
1880
- case AccessorKind::Read:
1881
- case AccessorKind::Read2:
1882
- if (accessorOverrideAlreadyDiagnosed (AccessorKind::Get))
1883
- return true ;
1884
- break ;
1885
-
1886
- case AccessorKind::Modify:
1887
- case AccessorKind::Modify2:
1888
- if (accessorOverrideAlreadyDiagnosed (AccessorKind::Get) ||
1889
- accessorOverrideAlreadyDiagnosed (AccessorKind::Set)) {
1890
- return true ;
1891
- }
1892
- break ;
1893
-
1894
- #define OPAQUE_ACCESSOR (ID, KEYWORD )
1895
- #define ACCESSOR (ID, KEYWORD ) case AccessorKind::ID:
1896
- #include " swift/AST/AccessorKinds.def"
1897
- llvm_unreachable (" checking override for non-opaque accessor" );
1856
+ // Check whether the base is unavailable from the perspective of the override.
1857
+ auto overrideAvailability = AvailabilityContext::forDeclSignature (override );
1858
+ if (auto baseConstraint =
1859
+ getAvailabilityConstraintsForDecl (base, overrideAvailability, flags)
1860
+ .getPrimaryConstraint ()) {
1861
+ if (baseConstraint->isUnavailable ())
1862
+ return {OverrideAvailability::BaseUnavailable, baseConstraint};
1898
1863
}
1899
1864
1900
- return false ;
1865
+ return {OverrideAvailability::Compatible, std::nullopt} ;
1901
1866
}
1902
1867
1903
- // / Diagnose an override for potential availability. Returns true if
1904
- // / a diagnostic was emitted and false otherwise.
1905
- static bool diagnoseOverrideForAvailability (ValueDecl *override ,
1906
- ValueDecl *base) {
1907
- if (isAvailabilitySafeForOverride (override , base))
1908
- return false ;
1909
-
1910
- // Suppress diagnostics about availability overrides for accessors
1911
- // if they would be redundant with other diagnostics.
1912
- if (isRedundantAccessorOverrideAvailabilityDiagnostic (override , base))
1913
- return false ;
1914
-
1915
- auto &diags = override ->getASTContext ().Diags ;
1916
- diags.diagnose (override , diag::override_less_available, override );
1917
- diags.diagnose (base, diag::overridden_here);
1918
-
1919
- return true ;
1920
- }
1921
-
1922
- enum class OverrideUnavailabilityStatus {
1923
- // / The unavailability of the base decl and override decl are compatible.
1924
- Compatible,
1925
- // / The base decl is unavailable but the override decl is not.
1926
- BaseUnavailable,
1927
- // / Do not diagnose the unavailability of these decls.
1928
- Ignored,
1929
- };
1930
-
1931
- static std::pair<OverrideUnavailabilityStatus,
1932
- std::optional<SemanticAvailableAttr>>
1933
- checkOverrideUnavailability (ValueDecl *override , ValueDecl *base) {
1934
- if (auto *overrideParent = override ->getDeclContext ()->getAsDecl ()) {
1935
- // If the parent of the override is unavailable, then the unavailability of
1936
- // the override decl is irrelevant.
1937
- if (AvailabilityContext::forDeclSignature (overrideParent).isUnavailable ())
1938
- return {OverrideUnavailabilityStatus::Ignored, std::nullopt};
1868
+ static std::pair<OverrideAvailability, std::optional<AvailabilityConstraint>>
1869
+ checkOverrideAvailability (ValueDecl *override , ValueDecl *base) {
1870
+ auto &ctx = override ->getASTContext ();
1871
+ if (ctx.LangOpts .DisableAvailabilityChecking )
1872
+ return {OverrideAvailability::Ignored, std::nullopt};
1873
+
1874
+ auto result = getOverrideAvailability (override , base);
1875
+ switch (result.first ) {
1876
+ case OverrideAvailability::Ignored:
1877
+ case OverrideAvailability::Compatible:
1878
+ return result;
1879
+ case OverrideAvailability::BaseUnavailable:
1880
+ case OverrideAvailability::OverrideUnavailable:
1881
+ case OverrideAvailability::OverrideLessAvailable:
1882
+ break ;
1939
1883
}
1940
1884
1941
- if (auto *baseAccessor = dyn_cast<AccessorDecl>(base)) {
1942
- // Ignore implicit accessors since the diagnostics are likely to duplicate
1943
- // the diagnostics for the explicit accessors that availability was inferred
1944
- // from.
1885
+ auto *overrideAccessor = dyn_cast<AccessorDecl>(override );
1886
+ auto *baseAccessor = dyn_cast<AccessorDecl>(base);
1887
+ if (baseAccessor && overrideAccessor) {
1888
+ // Skip implicit accessors since they're synthesized with availability that
1889
+ // matches the accessors that they were derived from and therefore
1890
+ // diagnostics for them will be redundant.
1945
1891
if (baseAccessor->isImplicit ())
1946
- return {OverrideUnavailabilityStatus ::Ignored, std::nullopt};
1892
+ return {OverrideAvailability ::Ignored, std::nullopt};
1947
1893
1948
- if (auto *overrideAccessor = dyn_cast<AccessorDecl>(override )) {
1949
- // If base and override are accessors, check whether the unavailability of
1950
- // their storage matches. Diagnosing accessors with invalid storage
1951
- // produces redundant diagnostics.
1952
- if (checkOverrideUnavailability (overrideAccessor->getStorage (),
1953
- baseAccessor->getStorage ())
1954
- .first != OverrideUnavailabilityStatus::Compatible)
1955
- return {OverrideUnavailabilityStatus::Ignored, std::nullopt};
1956
- }
1894
+ // If we're checking an accessor that's overriding another accessor, ignore
1895
+ // the result if we get the same result for the underlying storage
1896
+ // (otherwise we'll emit redundant diagnostics).
1897
+ if (checkOverrideAvailability (overrideAccessor->getStorage (),
1898
+ baseAccessor->getStorage ())
1899
+ .first != OverrideAvailability::Compatible)
1900
+ return {OverrideAvailability::Ignored, std::nullopt};
1957
1901
}
1958
1902
1959
- auto baseUnavailableAttr = base->getUnavailableAttr ();
1960
- auto overrideUnavailableAttr = override ->getUnavailableAttr ();
1961
-
1962
- if (baseUnavailableAttr && !overrideUnavailableAttr)
1963
- return {OverrideUnavailabilityStatus::BaseUnavailable, baseUnavailableAttr};
1964
-
1965
- return {OverrideUnavailabilityStatus::Compatible, std::nullopt};
1903
+ return result;
1966
1904
}
1967
1905
1968
1906
static bool checkSingleOverride (ValueDecl *override , ValueDecl *base) {
@@ -2231,14 +2169,11 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) {
2231
2169
return true ;
2232
2170
}
2233
2171
2234
- // FIXME: [availability] Possibly should extend to more availability checking.
2235
- auto unavailabilityStatusAndAttr =
2236
- checkOverrideUnavailability (override , base);
2237
- auto unavailableAttr = unavailabilityStatusAndAttr.second ;
2238
-
2239
- switch (unavailabilityStatusAndAttr.first ) {
2240
- case OverrideUnavailabilityStatus::BaseUnavailable: {
2241
- diagnoseOverrideOfUnavailableDecl (override , base, unavailableAttr.value ());
2172
+ auto [status, constraint] = checkOverrideAvailability (override , base);
2173
+ switch (status) {
2174
+ case OverrideAvailability::BaseUnavailable: {
2175
+ auto unavailableAttr = constraint->getAttr ();
2176
+ diagnoseOverrideOfUnavailableDecl (override , base, unavailableAttr);
2242
2177
2243
2178
if (isUnavailableInAllVersions (base)) {
2244
2179
auto modifier = override ->getAttrs ().getAttribute <OverrideAttr>();
@@ -2251,13 +2186,32 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) {
2251
2186
}
2252
2187
break ;
2253
2188
}
2254
- case OverrideUnavailabilityStatus::Compatible:
2255
- case OverrideUnavailabilityStatus::Ignored:
2189
+ case OverrideAvailability::OverrideUnavailable: {
2190
+ auto unavailableAttr = constraint->getAttr ();
2191
+ auto domain = unavailableAttr.getDomain ();
2192
+ auto parsedAttr = unavailableAttr.getParsedAttr ();
2193
+
2194
+ if (domain.isPlatform () || domain.isUniversal ()) {
2195
+ // FIXME: [availability] Diagnose as an error in a future Swift version.
2196
+ break ;
2197
+ }
2198
+
2199
+ if (parsedAttr->getLocation ().isValid ())
2200
+ ctx.Diags .diagnose (override , diag::override_unavailable, override )
2201
+ .fixItRemove (parsedAttr->getRangeWithAt ());
2202
+ else
2203
+ ctx.Diags .diagnose (override , diag::override_unavailable, override );
2204
+ ctx.Diags .diagnose (base, diag::overridden_here);
2205
+ break ;
2206
+ }
2207
+ case OverrideAvailability::OverrideLessAvailable: {
2208
+ ctx.Diags .diagnose (override , diag::override_less_available, override );
2209
+ ctx.Diags .diagnose (base, diag::overridden_here);
2256
2210
break ;
2257
2211
}
2258
-
2259
- if (!ctx. LangOpts . DisableAvailabilityChecking ) {
2260
- diagnoseOverrideForAvailability ( override , base) ;
2212
+ case OverrideAvailability::Compatible:
2213
+ case OverrideAvailability::Ignored:
2214
+ break ;
2261
2215
}
2262
2216
2263
2217
if (ctx.LangOpts .hasFeature (Feature::StrictMemorySafety, /* allowMigration=*/ true )) {
0 commit comments