2222#include " TypeCheckUnsafe.h"
2323#include " TypeChecker.h"
2424#include " swift/AST/ASTVisitor.h"
25- #include " swift/AST/AvailabilityInference .h"
25+ #include " swift/AST/AvailabilityConstraint .h"
2626#include " swift/AST/AvailabilityRange.h"
2727#include " swift/AST/Decl.h"
2828#include " swift/AST/GenericEnvironment.h"
@@ -1810,159 +1810,97 @@ OverrideRequiresKeyword swift::overrideRequiresKeyword(ValueDecl *overridden) {
18101810 return OverrideRequiresKeyword::Always;
18111811}
18121812
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+ };
18261825
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 ();
18311829
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);
18341834
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);
18411840
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;
18461846
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};
18511852
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};
18561854 }
18571855
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};
18981863 }
18991864
1900- return false ;
1865+ return {OverrideAvailability::Compatible, std:: nullopt } ;
19011866}
19021867
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 ;
19391883 }
19401884
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.
19451891 if (baseAccessor->isImplicit ())
1946- return {OverrideUnavailabilityStatus ::Ignored, std::nullopt };
1892+ return {OverrideAvailability ::Ignored, std::nullopt };
19471893
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 };
19571901 }
19581902
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;
19661904}
19671905
19681906static bool checkSingleOverride (ValueDecl *override , ValueDecl *base) {
@@ -2231,14 +2169,11 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) {
22312169 return true ;
22322170 }
22332171
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);
22422177
22432178 if (isUnavailableInAllVersions (base)) {
22442179 auto modifier = override ->getAttrs ().getAttribute <OverrideAttr>();
@@ -2251,13 +2186,32 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) {
22512186 }
22522187 break ;
22532188 }
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);
22562210 break ;
22572211 }
2258-
2259- if (!ctx. LangOpts . DisableAvailabilityChecking ) {
2260- diagnoseOverrideForAvailability ( override , base) ;
2212+ case OverrideAvailability::Compatible:
2213+ case OverrideAvailability::Ignored:
2214+ break ;
22612215 }
22622216
22632217 if (ctx.LangOpts .hasFeature (Feature::StrictMemorySafety, /* allowMigration=*/ true )) {
0 commit comments